@@ -12,10 +12,12 @@ use std::{ffi::OsString, path::PathBuf};
12
12
// https://github.com/rust-lang/rust/blob/26ecd44160f54395b3bd5558cc5352f49cb0a0ba/compiler/rustc_session/src/config.rs
13
13
14
14
/// Includes only the rustc arguments we care about
15
+ #[ derive( Debug ) ]
15
16
pub struct RustcArgs {
16
17
pub crate_name : String ,
17
18
pub crate_types : Vec < String > ,
18
19
pub cfg : Vec < String > ,
20
+ pub emit : Vec < String > ,
19
21
pub out_dir : PathBuf ,
20
22
pub target : Option < String > ,
21
23
pub print : Vec < String > ,
@@ -35,18 +37,96 @@ impl RustcArgs {
35
37
}
36
38
}
37
39
40
+ impl RustcArgs {
41
+ // Split into its own function for unit testing
42
+ fn from_vec ( raw_args : Vec < OsString > ) -> Result < RustcArgs , pico_args:: Error > {
43
+ let mut parser = pico_args:: Arguments :: from_vec ( raw_args) ;
44
+
45
+ // --emit requires slightly more complex parsing
46
+ let raw_emit_args: Vec < String > = parser. values_from_str ( "--emit" ) ?;
47
+ let mut emit: Vec < String > = Vec :: new ( ) ;
48
+ for raw_arg in raw_emit_args {
49
+ for item in raw_arg. split ( ',' ) {
50
+ emit. push ( item. to_owned ( ) ) ;
51
+ }
52
+ }
53
+
54
+ Ok ( RustcArgs {
55
+ crate_name : parser. value_from_str ( "--crate-name" ) ?,
56
+ crate_types : parser. values_from_str ( "--crate-type" ) ?,
57
+ cfg : parser. values_from_str ( "--cfg" ) ?,
58
+ emit,
59
+ out_dir : parser
60
+ . value_from_os_str :: < & str , PathBuf , pico_args:: Error > ( "--out-dir" , |s| {
61
+ Ok ( PathBuf :: from ( s) )
62
+ } ) ?,
63
+ target : parser. opt_value_from_str ( "--target" ) ?,
64
+ print : parser. values_from_str ( "--print" ) ?,
65
+ } )
66
+ }
67
+ }
68
+
38
69
pub fn parse_args ( ) -> Result < RustcArgs , pico_args:: Error > {
39
70
let raw_args: Vec < OsString > = std:: env:: args_os ( ) . skip ( 2 ) . collect ( ) ;
40
- let mut parser = pico_args:: Arguments :: from_vec ( raw_args) ;
41
-
42
- Ok ( RustcArgs {
43
- crate_name : parser. value_from_str ( "--crate-name" ) ?,
44
- crate_types : parser. values_from_str ( "--crate-type" ) ?,
45
- cfg : parser. values_from_str ( "--cfg" ) ?,
46
- out_dir : parser. value_from_os_str :: < & str , PathBuf , pico_args:: Error > ( "--out-dir" , |s| {
47
- Ok ( PathBuf :: from ( s) )
48
- } ) ?,
49
- target : parser. opt_value_from_str ( "--target" ) ?,
50
- print : parser. values_from_str ( "--print" ) ?,
51
- } )
71
+ RustcArgs :: from_vec ( raw_args)
72
+ }
73
+
74
+ pub fn should_embed_audit_data ( args : & RustcArgs ) -> bool {
75
+ // Only inject audit data into crate types 'bin' and 'cdylib',
76
+ // it doesn't make sense for static libs and weird other types.
77
+ if !( args. crate_types . contains ( & "bin" . to_owned ( ) )
78
+ || args. crate_types . contains ( & "cdylib" . to_owned ( ) ) )
79
+ {
80
+ return false ;
81
+ }
82
+
83
+ // when --emit is specified explicitly, only inject audit data for --emit=link
84
+ // because it doesn't make sense for all other types such as llvm-ir, asm, etc.
85
+ if !args. emit . is_empty ( ) && !args. emit . contains ( & "link" . to_owned ( ) ) {
86
+ return false ;
87
+ }
88
+
89
+ // --print disables compilation UNLESS --emit is also specified
90
+ if !args. print . is_empty ( ) && args. emit . is_empty ( ) {
91
+ return false ;
92
+ }
93
+
94
+ true
95
+ }
96
+
97
+ #[ cfg( test) ]
98
+ mod tests {
99
+ use super :: * ;
100
+
101
+ #[ test]
102
+ fn cargo_c_compatibility ( ) {
103
+ let raw_rustc_args = vec ! [ "--crate-name" , "rustls" , "--edition=2021" , "src/lib.rs" , "--error-format=json" , "--json=diagnostic-rendered-ansi,artifacts,future-incompat" , "--crate-type" , "staticlib" , "--crate-type" , "cdylib" , "--emit=dep-info,link" , "-C" , "embed-bitcode=no" , "-C" , "debuginfo=2" , "-C" , "link-arg=-Wl,-soname,librustls.so.0.14.0" , "-Cmetadata=rustls-ffi" , "--cfg" , "cargo_c" , "--print" , "native-static-libs" , "--cfg" , "feature=\" aws-lc-rs\" " , "--cfg" , "feature=\" capi\" " , "--cfg" , "feature=\" default\" " , "--check-cfg" , "cfg(docsrs)" , "--check-cfg" , "cfg(feature, values(\" aws-lc-rs\" , \" capi\" , \" cert_compression\" , \" default\" , \" no_log_capture\" , \" read_buf\" , \" ring\" ))" , "-C" , "metadata=b6a43041f637feb8" , "--out-dir" , "/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/deps" , "--target" , "x86_64-unknown-linux-gnu" , "-C" , "linker=clang" , "-C" , "incremental=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/incremental" , "-L" , "dependency=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/deps" , "-L" , "dependency=/home/user/Code/rustls-ffi/target/debug/deps" , "--extern" , "libc=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/deps/liblibc-4fc7c9f82dda33ee.rlib" , "--extern" , "log=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/deps/liblog-6f7c8f4d1d5ec422.rlib" , "--extern" , "rustls=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/deps/librustls-a93cda0ba0380929.rlib" , "--extern" , "pki_types=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/deps/librustls_pki_types-27749859644f0979.rlib" , "--extern" , "rustls_platform_verifier=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/deps/librustls_platform_verifier-bceca5cf09f3d7ba.rlib" , "--extern" , "webpki=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/deps/libwebpki-bc4a16dd84e0b062.rlib" , "-C" , "link-arg=-fuse-ld=/home/user/mold-2.32.0-x86_64-linux/bin/mold" , "-L" , "native=/home/user/Code/rustls-ffi/target/x86_64-unknown-linux-gnu/debug/build/aws-lc-sys-d52f8990d9ede41d/out" ] ;
104
+ let raw_rustc_args: Vec < OsString > = raw_rustc_args. into_iter ( ) . map ( |s| s. into ( ) ) . collect ( ) ;
105
+ let args = RustcArgs :: from_vec ( raw_rustc_args) . unwrap ( ) ;
106
+ assert ! ( should_embed_audit_data( & args) ) ;
107
+ }
108
+
109
+ #[ test]
110
+ fn multiple_emit_values ( ) {
111
+ let raw_rustc_args = vec ! [
112
+ "--emit=dep-info,link" ,
113
+ "--emit" ,
114
+ "llvm-bc" ,
115
+ // end of interesting args, start of boilerplate
116
+ "--crate-name" ,
117
+ "foobar" ,
118
+ "--out-dir" ,
119
+ "/foo/bar" ,
120
+ ] ;
121
+ let raw_rustc_args: Vec < OsString > = raw_rustc_args. into_iter ( ) . map ( |s| s. into ( ) ) . collect ( ) ;
122
+ let mut args = RustcArgs :: from_vec ( raw_rustc_args) . unwrap ( ) ;
123
+
124
+ let expected = vec ! [ "dep-info" , "link" , "llvm-bc" ] ;
125
+ let mut expected: Vec < String > = expected. into_iter ( ) . map ( |s| s. into ( ) ) . collect ( ) ;
126
+
127
+ args. emit . sort ( ) ;
128
+ expected. sort ( ) ;
129
+
130
+ assert_eq ! ( args. emit, expected)
131
+ }
52
132
}
0 commit comments