@@ -14,78 +14,10 @@ use crate::{
1414use std:: io:: BufRead ;
1515
1616pub fn main ( rustc_path : & OsStr ) {
17- let mut command = rustc_command ( rustc_path) ;
18-
19- // Binaries and C dynamic libraries are not built as non-primary packages,
20- // so this should not cause issues with Cargo caches.
21- if env:: var_os ( "CARGO_PRIMARY_PACKAGE" ) . is_some ( ) {
22- let args = rustc_arguments:: parse_args ( ) . unwrap ( ) ; // descriptive enough message
23- if should_embed_audit_data ( & args) {
24- // Get the audit data to embed
25- let target_triple = args
26- . target
27- . clone ( )
28- . unwrap_or_else ( || rustc_host_target_triple ( rustc_path) ) ;
29- let contents: Vec < u8 > =
30- collect_audit_data:: compressed_dependency_list ( & args, & target_triple) ;
31- // write the audit info to an object file
32- let target_info = target_info:: rustc_target_info ( rustc_path, & target_triple) ;
33- let binfile = binary_file:: create_binary_file (
34- & target_info,
35- & target_triple,
36- & contents,
37- "AUDITABLE_VERSION_INFO" ,
38- ) ;
39- if let Some ( file) = binfile {
40- // Place the audit data in the output dir.
41- // We can place it anywhere really, the only concern is clutter and name collisions,
42- // and the target dir is locked so we're probably good
43- let filename = format ! (
44- "{}_audit_data.o" ,
45- args. crate_name
46- . as_ref( )
47- . expect( "rustc command is missing --crate-name" )
48- ) ;
49- let path = args
50- . out_dir
51- . as_ref ( )
52- . expect ( "rustc command is missing --out-dir" )
53- . join ( filename) ;
54- std:: fs:: write ( & path, file) . expect ( "Unable to write output file" ) ;
55-
56- // Modify the rustc command to link the object file with audit data
57- let mut linker_command = OsString :: from ( "-Clink-arg=" ) ;
58- linker_command. push ( & path) ;
59- command. arg ( linker_command) ;
60- // Prevent the symbol from being removed as unused by the linker
61- if is_apple ( & target_info) {
62- if args. bare_linker ( ) {
63- command. arg ( "-Clink-arg=-u,_AUDITABLE_VERSION_INFO" ) ;
64- } else {
65- command. arg ( "-Clink-arg=-Wl,-u,_AUDITABLE_VERSION_INFO" ) ;
66- }
67- } else if is_msvc ( & target_info) {
68- command. arg ( "-Clink-arg=/INCLUDE:AUDITABLE_VERSION_INFO" ) ;
69- } else if is_wasm ( & target_info) {
70- // We don't emit the symbol name in WASM, so nothing to do
71- } else {
72- // Unrecognized platform, assume it to be unix-like
73- #[ allow( clippy:: collapsible_else_if) ]
74- if args. bare_linker ( ) {
75- command. arg ( "-Clink-arg=--undefined=AUDITABLE_VERSION_INFO" ) ;
76- } else {
77- command. arg ( "-Clink-arg=-Wl,--undefined=AUDITABLE_VERSION_INFO" ) ;
78- }
79- }
80- } else {
81- // create_binary_file() returned None, indicating an unsupported architecture
82- eprintln ! (
83- "WARNING: target '{target_triple}' is not supported by 'cargo auditable'!\n \
84- The build will continue, but no audit data will be injected into the binary."
85- ) ;
86- }
87- }
88- }
17+ let mut command = match rustc_command_with_audit_data ( rustc_path) {
18+ Some ( cmd) => cmd,
19+ None => rustc_command ( rustc_path) , // could not construct command that injects audit data, skip it
20+ } ;
8921
9022 // Invoke rustc
9123 let results = command. status ( ) . unwrap_or_else ( |err| {
@@ -127,3 +59,99 @@ fn rustc_host_target_triple(rustc_path: &OsStr) -> String {
12759 . map ( |l| l[ 6 ..] . to_string ( ) )
12860 . expect ( "Failed to parse rustc output to determine the current platform. Please report this bug!" )
12961}
62+
63+ fn rustc_command_with_audit_data ( rustc_path : & OsStr ) -> Option < Command > {
64+ let mut command = rustc_command ( rustc_path) ;
65+
66+ // Only inject audit data if CARGO_PRIMARY_PACKAGE is set.
67+ // This allows linking audit data only in toplevel binaries, not intermediate artifacts.
68+ //
69+ // Binaries and C dynamic libraries are not built as non-primary packages,
70+ // so this should not cause issues with Cargo caches.
71+ #[ allow( clippy:: question_mark) ]
72+ if env:: var_os ( "CARGO_PRIMARY_PACKAGE" ) . is_none ( ) {
73+ return None ;
74+ }
75+ let args = rustc_arguments:: parse_args ( ) . unwrap ( ) ; // descriptive enough message
76+ if !should_embed_audit_data ( & args) {
77+ return None ;
78+ }
79+ // Get the audit data to embed
80+ let target_triple = args
81+ . target
82+ . clone ( )
83+ . unwrap_or_else ( || rustc_host_target_triple ( rustc_path) ) ;
84+ let contents: Vec < u8 > = collect_audit_data:: compressed_dependency_list ( & args, & target_triple) ;
85+
86+ // write the audit info to an object file
87+ let target_info = target_info:: rustc_target_info ( rustc_path, & target_triple) ;
88+ let binfile = binary_file:: create_binary_file (
89+ & target_info,
90+ & target_triple,
91+ & contents,
92+ "AUDITABLE_VERSION_INFO" ,
93+ ) ;
94+ if let Some ( file) = binfile {
95+ // Place the audit data in the output dir.
96+ // We can place it anywhere really, the only concern is clutter and name collisions,
97+ // and the target dir is locked so we're probably good
98+ let crate_name = match args. crate_name . as_deref ( ) {
99+ Some ( name) => name,
100+ None => {
101+ eprintln ! (
102+ "WARNING: cargo-auditable: rustc command is missing --crate-name\n \
103+ Please double-check that the audit data was injected into the binary.\n \
104+ If it wasn't, please report a bug."
105+ ) ;
106+ return None ;
107+ }
108+ } ;
109+ let out_dir = match args. out_dir . as_deref ( ) {
110+ Some ( name) => name,
111+ None => {
112+ eprintln ! (
113+ "WARNING: cargo-auditable: rustc command is missing --out-dir\n \
114+ Please double-check that the audit data was injected into the binary.\n \
115+ If it wasn't, please report a bug."
116+ ) ;
117+ return None ;
118+ }
119+ } ;
120+ let filename = format ! ( "{crate_name}_audit_data.o" ) ;
121+ let path = out_dir. join ( filename) ;
122+ std:: fs:: write ( & path, file) . expect ( "Unable to write output file" ) ;
123+
124+ // Modify the rustc command to link the object file with audit data
125+ let mut linker_command = OsString :: from ( "-Clink-arg=" ) ;
126+ linker_command. push ( & path) ;
127+ command. arg ( linker_command) ;
128+ // Prevent the symbol from being removed as unused by the linker
129+ if is_apple ( & target_info) {
130+ if args. bare_linker ( ) {
131+ command. arg ( "-Clink-arg=-u,_AUDITABLE_VERSION_INFO" ) ;
132+ } else {
133+ command. arg ( "-Clink-arg=-Wl,-u,_AUDITABLE_VERSION_INFO" ) ;
134+ }
135+ } else if is_msvc ( & target_info) {
136+ command. arg ( "-Clink-arg=/INCLUDE:AUDITABLE_VERSION_INFO" ) ;
137+ } else if is_wasm ( & target_info) {
138+ // We don't emit the symbol name in WASM, so nothing to do
139+ } else {
140+ // Unrecognized platform, assume it to be unix-like
141+ #[ allow( clippy:: collapsible_else_if) ]
142+ if args. bare_linker ( ) {
143+ command. arg ( "-Clink-arg=--undefined=AUDITABLE_VERSION_INFO" ) ;
144+ } else {
145+ command. arg ( "-Clink-arg=-Wl,--undefined=AUDITABLE_VERSION_INFO" ) ;
146+ }
147+ }
148+ Some ( command)
149+ } else {
150+ // create_binary_file() returned None, indicating an unsupported architecture
151+ eprintln ! (
152+ "WARNING: cargo-auditable: target '{target_triple}' is not supported!\n \
153+ The build will continue, but no audit data will be injected into the binary."
154+ ) ;
155+ None
156+ }
157+ }
0 commit comments