diff --git a/Cargo.lock b/Cargo.lock index 89edbc949a5..5eefe69ceab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -268,7 +268,7 @@ dependencies = [ [[package]] name = "build-rs" -version = "0.3.2" +version = "0.3.3" dependencies = [ "unicode-ident", ] diff --git a/crates/build-rs-test-lib/build.rs b/crates/build-rs-test-lib/build.rs index 0592a374915..be3538d60df 100644 --- a/crates/build-rs-test-lib/build.rs +++ b/crates/build-rs-test-lib/build.rs @@ -11,6 +11,7 @@ fn smoke_test_inputs() { dbg!(cargo()); dbg!(cargo_cfg_feature()); dbg!(cargo_cfg("careful")); + dbg!(cargo_cfg_debug_assertions()); #[cfg(feature = "unstable")] dbg!(cargo_cfg_fmt_debug()); #[cfg(feature = "unstable")] diff --git a/crates/build-rs/Cargo.toml b/crates/build-rs/Cargo.toml index 093f22cd730..a340cf9436a 100644 --- a/crates/build-rs/Cargo.toml +++ b/crates/build-rs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "build-rs" -version = "0.3.2" +version = "0.3.3" rust-version.workspace = true edition.workspace = true license.workspace = true diff --git a/crates/build-rs/src/input.rs b/crates/build-rs/src/input.rs index d8a75d41922..f2e92383ba8 100644 --- a/crates/build-rs/src/input.rs +++ b/crates/build-rs/src/input.rs @@ -172,11 +172,6 @@ mod cfg { } /// If we are compiling with debug assertions enabled. - /// - /// Build scripts are not passed this cfg because - /// this cfg is always true and misleading. - /// That is because Cargo queries rustc without any profile settings. - #[cfg(any())] #[track_caller] pub fn cargo_cfg_debug_assertions() -> bool { ENV.is_present("CARGO_CFG_DEBUG_ASSERTIONS") diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index 5393196106f..7ca866bcaca 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -407,9 +407,19 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul "feature", unit.features.iter().map(|s| s.as_str()).collect::>(), ); + // Manually inject debug_assertions based on the profile setting. + // The cfg query from rustc doesn't include profile settings and would always be true, + // so we override it with the actual profile setting. + if unit.profile.debug_assertions { + cfg_map.insert("debug_assertions", Vec::new()); + } for cfg in bcx.target_data.cfg(unit.kind) { match *cfg { Cfg::Name(ref n) => { + // Skip debug_assertions from rustc query; we use the profile setting instead + if n.as_str() == "debug_assertions" { + continue; + } cfg_map.insert(n.as_str(), Vec::new()); } Cfg::KeyPair(ref k, ref v) => { @@ -419,11 +429,6 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul } } for (k, v) in cfg_map { - if k == "debug_assertions" { - // This cfg is always true and misleading, so avoid setting it. - // That is because Cargo queries rustc without any profile settings. - continue; - } // FIXME: We should handle raw-idents somehow instead of predenting they // don't exist here let k = format!("CARGO_CFG_{}", super::envify(k)); diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index 9fe7400b85c..dec14cbac92 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -330,6 +330,7 @@ impl Profiles { result.root = for_unit_profile.root; result.debuginfo = for_unit_profile.debuginfo; result.opt_level = for_unit_profile.opt_level; + result.debug_assertions = for_unit_profile.debug_assertions; result.trim_paths = for_unit_profile.trim_paths.clone(); result } diff --git a/src/doc/src/reference/environment-variables.md b/src/doc/src/reference/environment-variables.md index 2f69434ddc0..cb9976ddb89 100644 --- a/src/doc/src/reference/environment-variables.md +++ b/src/doc/src/reference/environment-variables.md @@ -363,7 +363,7 @@ let out_dir = env::var("OUT_DIR").unwrap(); > Note that different [target triples][Target Triple] have different sets of `cfg` values, > hence variables present in one target triple might not be available in the other. > - > Some cfg values like `debug_assertions` and `test` are not available. + > Some cfg values like `test` are not available. * `OUT_DIR` --- the folder in which all output and intermediate artifacts should be placed. This folder is inside the build directory for the package being built, and it is unique for the package in question. diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 784530dc129..5605f4736ec 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -5887,7 +5887,7 @@ fn user_specific_cfgs_are_filtered_out() { r#" fn main() { assert!(std::env::var_os("CARGO_CFG_PROC_MACRO").is_none()); - assert!(std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_none()); + assert!(std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some()); } "#, ) diff --git a/tests/testsuite/build_script_env.rs b/tests/testsuite/build_script_env.rs index 15d3a671535..442d7ad3d3c 100644 --- a/tests/testsuite/build_script_env.rs +++ b/tests/testsuite/build_script_env.rs @@ -452,3 +452,142 @@ fn rerun_if_env_newly_added_in_config() { "#]]) .run(); } + +#[cargo_test] +fn build_script_debug_assertions_dev() { + // Test that CARGO_CFG_DEBUG_ASSERTIONS is set in dev profile (default) + let build_rs = r#" + fn main() { + let has_debug_assertions = std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some(); + assert!(has_debug_assertions, "CARGO_CFG_DEBUG_ASSERTIONS should be set in dev profile"); + } + "#; + + let p = project() + .file("src/lib.rs", r#""#) + .file("build.rs", build_rs) + .build(); + + // Default dev profile has debug-assertions enabled + p.cargo("check").run(); +} + +#[cargo_test] +fn build_script_debug_assertions_release() { + // Test that CARGO_CFG_DEBUG_ASSERTIONS is NOT set in release profile (default) + let build_rs = r#" + fn main() { + let has_debug_assertions = std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some(); + assert!(!has_debug_assertions, "CARGO_CFG_DEBUG_ASSERTIONS should NOT be set in release profile"); + } + "#; + + let p = project() + .file("src/lib.rs", r#""#) + .file("build.rs", build_rs) + .build(); + + // Release profile has debug-assertions disabled by default + p.cargo("check --release").run(); +} + +#[cargo_test] +fn build_script_debug_assertions_override_dev() { + // Test that CARGO_CFG_DEBUG_ASSERTIONS respects profile overrides + // Dev profile with debug-assertions explicitly DISABLED + let build_rs = r#" + fn main() { + let has_debug_assertions = std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some(); + assert!(!has_debug_assertions, "CARGO_CFG_DEBUG_ASSERTIONS should NOT be set when dev profile disables it"); + } + "#; + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + + [profile.dev] + debug-assertions = false + "#, + ) + .file("src/lib.rs", r#""#) + .file("build.rs", build_rs) + .build(); + + // Dev profile with debug-assertions explicitly disabled + p.cargo("check").run(); +} + +#[cargo_test] +fn build_script_debug_assertions_override_release() { + // Test that CARGO_CFG_DEBUG_ASSERTIONS respects profile overrides + // Release profile with debug-assertions explicitly ENABLED + let build_rs = r#" + fn main() { + let has_debug_assertions = std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some(); + assert!(has_debug_assertions, "CARGO_CFG_DEBUG_ASSERTIONS should be set when release profile enables it"); + } + "#; + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + + [profile.release] + debug-assertions = true + "#, + ) + .file("src/lib.rs", r#""#) + .file("build.rs", build_rs) + .build(); + + // Release profile with debug-assertions explicitly enabled + p.cargo("check --release").run(); +} + +#[cargo_test] +fn build_script_debug_assertions_build_override() { + let build_rs = r#" + fn main() { + let profile = std::env::var("PROFILE").unwrap(); + if profile == "debug" { + assert!(!cfg!(debug_assertions)); + } else if profile == "release" { + assert!(cfg!(debug_assertions)); + } + } + "#; + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2024" + + [profile.dev.build-override] + debug-assertions = false + + [profile.release.build-override] + debug-assertions = true + "#, + ) + .file("src/lib.rs", r#""#) + .file("build.rs", build_rs) + .build(); + + p.cargo("check").run(); + p.cargo("check --release").run(); +}