@@ -12,10 +12,12 @@ use std::{ffi::OsString, path::PathBuf};
1212// https://github.com/rust-lang/rust/blob/26ecd44160f54395b3bd5558cc5352f49cb0a0ba/compiler/rustc_session/src/config.rs
1313
1414/// Includes only the rustc arguments we care about
15+ #[ derive( Debug ) ]
1516pub struct RustcArgs {
1617 pub crate_name : String ,
1718 pub crate_types : Vec < String > ,
1819 pub cfg : Vec < String > ,
20+ pub emit : Vec < String > ,
1921 pub out_dir : PathBuf ,
2022 pub target : Option < String > ,
2123 pub print : Vec < String > ,
@@ -35,18 +37,96 @@ impl RustcArgs {
3537 }
3638}
3739
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+
3869pub fn parse_args ( ) -> Result < RustcArgs , pico_args:: Error > {
3970 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+ }
52132}
0 commit comments