1
- use crate :: Result ;
1
+ use crate :: { Result , TestGenerator } ;
2
2
use std:: env;
3
3
use std:: fs:: { canonicalize, File } ;
4
4
use std:: io:: Write ;
5
5
use std:: path:: { Path , PathBuf } ;
6
6
use std:: process:: Command ;
7
7
8
+ /// Generate all tests for the given crate and output the Rust side to a file.
9
+ pub fn generate_test (
10
+ generator : & mut TestGenerator ,
11
+ crate_path : impl AsRef < Path > ,
12
+ output_file_path : impl AsRef < Path > ,
13
+ ) -> Result < PathBuf > {
14
+ let output_file_path = generator. generate_files ( crate_path, output_file_path) ?;
15
+
16
+ // Search for the target and host to build for if specified manually (generator.target, generator.host),
17
+ // via build script (TARGET, HOST), or for internal testing (TARGET_PLATFORM, HOST_PLATFORM).
18
+ let target = generator. target . clone ( ) . unwrap_or_else ( || {
19
+ env:: var ( "TARGET" ) . unwrap_or_else ( |_| env:: var ( "TARGET_PLATFORM" ) . unwrap ( ) )
20
+ } ) ;
21
+ let host = generator
22
+ . host
23
+ . clone ( )
24
+ . unwrap_or_else ( || env:: var ( "HOST" ) . unwrap_or_else ( |_| env:: var ( "HOST_PLATFORM" ) . unwrap ( ) ) ) ;
25
+
26
+ let mut cfg = cc:: Build :: new ( ) ;
27
+ // FIXME: Cpp not supported.
28
+ cfg. file ( output_file_path. with_extension ( "c" ) ) ;
29
+ cfg. host ( & host) ;
30
+
31
+ if target. contains ( "msvc" ) {
32
+ cfg. flag ( "/W3" )
33
+ . flag ( "/Wall" )
34
+ . flag ( "/WX" )
35
+ // ignored warnings
36
+ . flag ( "/wd4820" ) // warning about adding padding?
37
+ . flag ( "/wd4100" ) // unused parameters
38
+ . flag ( "/wd4996" ) // deprecated functions
39
+ . flag ( "/wd4296" ) // '<' being always false
40
+ . flag ( "/wd4255" ) // converting () to (void)
41
+ . flag ( "/wd4668" ) // using an undefined thing in preprocessor?
42
+ . flag ( "/wd4366" ) // taking ref to packed struct field might be unaligned
43
+ . flag ( "/wd4189" ) // local variable initialized but not referenced
44
+ . flag ( "/wd4710" ) // function not inlined
45
+ . flag ( "/wd5045" ) // compiler will insert Spectre mitigation
46
+ . flag ( "/wd4514" ) // unreferenced inline function removed
47
+ . flag ( "/wd4711" ) ; // function selected for automatic inline
48
+ } else {
49
+ cfg. flag ( "-Wall" )
50
+ . flag ( "-Wextra" )
51
+ . flag ( "-Werror" )
52
+ . flag ( "-Wno-unused-parameter" )
53
+ . flag ( "-Wno-type-limits" )
54
+ // allow taking address of packed struct members:
55
+ . flag ( "-Wno-address-of-packed-member" )
56
+ . flag ( "-Wno-unknown-warning-option" )
57
+ . flag ( "-Wno-deprecated-declarations" ) ; // allow deprecated items
58
+ }
59
+
60
+ for p in & generator. includes {
61
+ cfg. include ( p) ;
62
+ }
63
+
64
+ let stem: & str = output_file_path. file_stem ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ;
65
+ cfg. target ( & target)
66
+ . out_dir ( output_file_path. parent ( ) . unwrap ( ) )
67
+ . compile ( stem) ;
68
+
69
+ Ok ( output_file_path)
70
+ }
71
+
8
72
/// Compiles a Rust source file and links it against a static library.
9
73
///
10
74
/// Returns the path to the generated binary.
11
- pub fn compile_test < P : AsRef < Path > > (
12
- output_dir : P ,
13
- crate_path : P ,
14
- library_file : P ,
75
+ #[ doc( hidden) ]
76
+ pub fn __compile_test (
77
+ output_dir : impl AsRef < Path > ,
78
+ crate_path : impl AsRef < Path > ,
79
+ library_file : impl AsRef < Path > ,
15
80
) -> Result < PathBuf > {
16
81
let rustc = env:: var ( "RUSTC" ) . unwrap_or_else ( |_| "rustc" . into ( ) ) ;
17
82
let output_dir = output_dir. as_ref ( ) ;
18
83
let crate_path = crate_path. as_ref ( ) ;
19
- let library_file = library_file. as_ref ( ) ;
84
+ let library_file = library_file. as_ref ( ) . file_stem ( ) . unwrap ( ) ;
20
85
21
86
let rust_file = output_dir
22
87
. join ( crate_path. file_stem ( ) . unwrap ( ) )
23
88
. with_extension ( "rs" ) ;
24
89
let binary_path = output_dir. join ( rust_file. file_stem ( ) . unwrap ( ) ) ;
25
90
91
+ // Create a file that contains the Rust 'bindings' as well as the generated test code.
26
92
File :: create ( & rust_file) ?. write_all (
27
93
format ! (
28
94
"include!(r#\" {}\" #);\n include!(r#\" {}.rs\" #);" ,
29
95
canonicalize( crate_path) ?. display( ) ,
30
- library_file. display ( )
96
+ library_file. to_str ( ) . unwrap ( )
31
97
)
32
98
. as_bytes ( ) ,
33
99
) ?;
34
100
101
+ // Compile the test file with the compiled C library file found in `output_dir`
102
+ // into a binary file, ignoring all warnings about unused items. (not all items
103
+ // are currently tested)
104
+
35
105
let mut cmd = Command :: new ( rustc) ;
36
106
cmd. arg ( & rust_file)
37
107
. arg ( format ! ( "-Lnative={}" , output_dir. display( ) ) )
38
- . arg ( format ! (
39
- "-lstatic={}" ,
40
- library_file. file_stem( ) . unwrap( ) . to_str( ) . unwrap( )
41
- ) )
42
- . arg ( "--target" )
43
- . arg ( env:: var ( "TARGET_PLATFORM" ) . unwrap ( ) )
108
+ . arg ( format ! ( "-lstatic={}" , library_file. to_str( ) . unwrap( ) ) )
109
+ . arg ( "--edition" )
110
+ . arg ( "2021" ) // Defaults to 2015.
44
111
. arg ( "-o" )
45
112
. arg ( & binary_path)
46
113
. arg ( "-Aunused" ) ;
47
114
115
+ // Pass in a different target, linker or flags if set, useful for cross compilation.
116
+
117
+ let target = env:: var ( "TARGET_PLATFORM" ) . unwrap_or_default ( ) ;
118
+ if !target. is_empty ( ) {
119
+ cmd. arg ( "--target" ) . arg ( target) ;
120
+ }
121
+
48
122
let linker = env:: var ( "LINKER" ) . unwrap_or_default ( ) ;
49
123
if !linker. is_empty ( ) {
50
124
cmd. arg ( format ! ( "-Clinker={linker}" ) ) ;
@@ -64,14 +138,17 @@ pub fn compile_test<P: AsRef<Path>>(
64
138
}
65
139
66
140
/// Executes the compiled test binary and returns its output.
67
- pub fn run_test ( test_binary : & str ) -> Result < String > {
141
+ ///
142
+ /// If a RUNNER environment variable is present, it will use that to run the binary.
143
+ #[ doc( hidden) ]
144
+ pub fn __run_test < P : AsRef < Path > > ( test_binary : P ) -> Result < String > {
68
145
let runner = env:: var ( "RUNNER" ) . unwrap_or_default ( ) ;
69
146
let output = if runner. is_empty ( ) {
70
- Command :: new ( test_binary) . output ( ) ?
147
+ Command :: new ( test_binary. as_ref ( ) ) . output ( ) ?
71
148
} else {
72
149
let mut args = runner. split_whitespace ( ) ;
73
150
let mut cmd = Command :: new ( args. next ( ) . unwrap ( ) ) ;
74
- cmd. args ( args) . arg ( test_binary) . output ( ) ?
151
+ cmd. args ( args) . arg ( test_binary. as_ref ( ) ) . output ( ) ?
75
152
} ;
76
153
77
154
if !output. status . success ( ) {
0 commit comments