@@ -105,30 +105,62 @@ impl BuildOptions<'_> {
105105 Ok ( built_benches)
106106 }
107107
108+ /// Adds debug flags and codspeed compilation
109+ ///
110+ /// If the user has set `RUSTFLAGS`, it will append the flags to it.
111+ /// Else, and if the cargo version allows it, it will set the cargo config through
112+ /// `--config 'build.rustflags=[ ... ]'`
113+ ///
114+ /// # Why we do this
115+ /// As tracked in [https://github.com/rust-lang/cargo/issues/5376], setting `RUSTFLAGS`
116+ /// completely overrides rustflags from cargo config
117+ /// We use the cargo built-in config mechanism to set the flags if the user has not set
118+ /// `RUSTFLAGS`.
119+ fn add_rust_flags ( & self , cargo : & mut Command , measurement_mode : MeasurementMode ) {
120+ let mut flags = vec ! [
121+ // Add debug info (equivalent to -g)
122+ "-Cdebuginfo=2" . to_owned( ) ,
123+ // Prevent debug info stripping
124+ // https://doc.rust-lang.org/cargo/reference/profiles.html#release
125+ // According to cargo docs, for release profile which we default to:
126+ // `strip = "none"` and `debug = false`.
127+ // In practice, if we set debug info through RUSTFLAGS, cargo still strips them, most
128+ // likely because debug = false in the release profile.
129+ // We also need to disable stripping through rust flags.
130+ "-Cstrip=none" . to_owned( ) ,
131+ ] ;
132+
133+ // Add the codspeed cfg flag if instrumentation mode is enabled
134+ if measurement_mode == MeasurementMode :: Instrumentation {
135+ flags. push ( "--cfg=codspeed" . to_owned ( ) ) ;
136+ }
137+
138+ match std:: env:: var ( "RUSTFLAGS" ) {
139+ Result :: Ok ( existing_rustflags) => {
140+ // Expand already existing RUSTFLAGS env var
141+ let flags_str = flags. join ( " " ) ;
142+ cargo. env ( "RUSTFLAGS" , format ! ( "{existing_rustflags} {flags_str}" ) ) ;
143+ }
144+ Err ( _) => {
145+ // Use --config to set rustflags
146+ // Our rust integration has an msrv of 1.74, --config is available since 1.63
147+ // https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html#cargo-163-2022-08-11
148+ let config_value = format ! (
149+ "build.rustflags=[{}]" ,
150+ flags. into_iter( ) . map( |f| format!( "\" {f}\" " ) ) . join( "," )
151+ ) ;
152+ cargo. arg ( "--config" ) . arg ( config_value) ;
153+ }
154+ }
155+ }
156+
108157 /// Generates a subcommand to build the benchmarks by invoking cargo and forwarding the filters
109158 /// This command explicitly ignores the `self.benches`: all benches are built
110159 fn build_command ( & self , measurement_mode : MeasurementMode ) -> Command {
111160 let mut cargo = Command :: new ( "cargo" ) ;
112161 cargo. args ( [ "build" , "--benches" ] ) ;
113162
114- let mut rust_flags = std:: env:: var ( "RUSTFLAGS" ) . unwrap_or_else ( |_| "" . into ( ) ) ;
115- // Add debug info (equivalent to -g)
116- rust_flags. push_str ( " -C debuginfo=2" ) ;
117-
118- // Prevent debug info stripping
119- // https://doc.rust-lang.org/cargo/reference/profiles.html#release
120- // According to cargo docs, for release profile which we default to:
121- // `strip = "none"` and `debug = false`.
122- // In practice, if we set debug info through RUSTFLAGS, cargo still strips them, most
123- // likely because debug = false in the release profile.
124- // We also need to disable stripping through rust flags.
125- rust_flags. push_str ( " -C strip=none" ) ;
126-
127- // Add the codspeed cfg flag if instrumentation mode is enabled
128- if measurement_mode == MeasurementMode :: Instrumentation {
129- rust_flags. push_str ( " --cfg codspeed" ) ;
130- }
131- cargo. env ( "RUSTFLAGS" , rust_flags) ;
163+ self . add_rust_flags ( & mut cargo, measurement_mode) ;
132164
133165 if let Some ( features) = self . features {
134166 cargo. arg ( "--features" ) . arg ( features. join ( "," ) ) ;
0 commit comments