Skip to content

Commit 9fa462f

Browse files
authored
Enable CARGO_CFG_DEBUG_ASSERTIONS in build scripts based on profile (#16160)
Build scripts need to know whether debug assertions are enabled to properly configure dependencies with matching assertion behavior. Previously, `CARGO_CFG_DEBUG_ASSERTIONS` was filtered out because the cfg query to rustc doesn't include profile settings. This PR manually sets `CARGO_CFG_DEBUG_ASSERTIONS` based on the profile's `debug-assertions` setting, allowing build scripts to configure dependencies appropriately. FCP: #16160 (comment) Closes #15760
2 parents 2b7dbd9 + 2eb1ecc commit 9fa462f

File tree

9 files changed

+155
-14
lines changed

9 files changed

+155
-14
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/build-rs-test-lib/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ fn smoke_test_inputs() {
1111
dbg!(cargo());
1212
dbg!(cargo_cfg_feature());
1313
dbg!(cargo_cfg("careful"));
14+
dbg!(cargo_cfg_debug_assertions());
1415
#[cfg(feature = "unstable")]
1516
dbg!(cargo_cfg_fmt_debug());
1617
#[cfg(feature = "unstable")]

crates/build-rs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "build-rs"
3-
version = "0.3.2"
3+
version = "0.3.3"
44
rust-version.workspace = true
55
edition.workspace = true
66
license.workspace = true

crates/build-rs/src/input.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,11 +172,6 @@ mod cfg {
172172
}
173173

174174
/// If we are compiling with debug assertions enabled.
175-
///
176-
/// Build scripts are not passed this cfg because
177-
/// this cfg is always true and misleading.
178-
/// That is because Cargo queries rustc without any profile settings.
179-
#[cfg(any())]
180175
#[track_caller]
181176
pub fn cargo_cfg_debug_assertions() -> bool {
182177
ENV.is_present("CARGO_CFG_DEBUG_ASSERTIONS")

src/cargo/core/compiler/custom_build.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,19 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
404404
"feature",
405405
unit.features.iter().map(|s| s.as_str()).collect::<Vec<_>>(),
406406
);
407+
// Manually inject debug_assertions based on the profile setting.
408+
// The cfg query from rustc doesn't include profile settings and would always be true,
409+
// so we override it with the actual profile setting.
410+
if unit.profile.debug_assertions {
411+
cfg_map.insert("debug_assertions", Vec::new());
412+
}
407413
for cfg in bcx.target_data.cfg(unit.kind) {
408414
match *cfg {
409415
Cfg::Name(ref n) => {
416+
// Skip debug_assertions from rustc query; we use the profile setting instead
417+
if n.as_str() == "debug_assertions" {
418+
continue;
419+
}
410420
cfg_map.insert(n.as_str(), Vec::new());
411421
}
412422
Cfg::KeyPair(ref k, ref v) => {
@@ -416,11 +426,6 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
416426
}
417427
}
418428
for (k, v) in cfg_map {
419-
if k == "debug_assertions" {
420-
// This cfg is always true and misleading, so avoid setting it.
421-
// That is because Cargo queries rustc without any profile settings.
422-
continue;
423-
}
424429
// FIXME: We should handle raw-idents somehow instead of predenting they
425430
// don't exist here
426431
let k = format!("CARGO_CFG_{}", super::envify(k));

src/cargo/core/profiles.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,7 @@ impl Profiles {
330330
result.root = for_unit_profile.root;
331331
result.debuginfo = for_unit_profile.debuginfo;
332332
result.opt_level = for_unit_profile.opt_level;
333+
result.debug_assertions = for_unit_profile.debug_assertions;
333334
result.trim_paths = for_unit_profile.trim_paths.clone();
334335
result
335336
}

src/doc/src/reference/environment-variables.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ let out_dir = env::var("OUT_DIR").unwrap();
363363
> Note that different [target triples][Target Triple] have different sets of `cfg` values,
364364
> hence variables present in one target triple might not be available in the other.
365365
>
366-
> Some cfg values like `debug_assertions` and `test` are not available.
366+
> Some cfg values like `test` are not available.
367367
* `OUT_DIR` --- the folder in which all output and intermediate artifacts should
368368
be placed. This folder is inside the build directory for the package being built,
369369
and it is unique for the package in question.

tests/testsuite/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5887,7 +5887,7 @@ fn user_specific_cfgs_are_filtered_out() {
58875887
r#"
58885888
fn main() {
58895889
assert!(std::env::var_os("CARGO_CFG_PROC_MACRO").is_none());
5890-
assert!(std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_none());
5890+
assert!(std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some());
58915891
}
58925892
"#,
58935893
)

tests/testsuite/build_script_env.rs

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,3 +452,142 @@ fn rerun_if_env_newly_added_in_config() {
452452
"#]])
453453
.run();
454454
}
455+
456+
#[cargo_test]
457+
fn build_script_debug_assertions_dev() {
458+
// Test that CARGO_CFG_DEBUG_ASSERTIONS is set in dev profile (default)
459+
let build_rs = r#"
460+
fn main() {
461+
let has_debug_assertions = std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some();
462+
assert!(has_debug_assertions, "CARGO_CFG_DEBUG_ASSERTIONS should be set in dev profile");
463+
}
464+
"#;
465+
466+
let p = project()
467+
.file("src/lib.rs", r#""#)
468+
.file("build.rs", build_rs)
469+
.build();
470+
471+
// Default dev profile has debug-assertions enabled
472+
p.cargo("check").run();
473+
}
474+
475+
#[cargo_test]
476+
fn build_script_debug_assertions_release() {
477+
// Test that CARGO_CFG_DEBUG_ASSERTIONS is NOT set in release profile (default)
478+
let build_rs = r#"
479+
fn main() {
480+
let has_debug_assertions = std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some();
481+
assert!(!has_debug_assertions, "CARGO_CFG_DEBUG_ASSERTIONS should NOT be set in release profile");
482+
}
483+
"#;
484+
485+
let p = project()
486+
.file("src/lib.rs", r#""#)
487+
.file("build.rs", build_rs)
488+
.build();
489+
490+
// Release profile has debug-assertions disabled by default
491+
p.cargo("check --release").run();
492+
}
493+
494+
#[cargo_test]
495+
fn build_script_debug_assertions_override_dev() {
496+
// Test that CARGO_CFG_DEBUG_ASSERTIONS respects profile overrides
497+
// Dev profile with debug-assertions explicitly DISABLED
498+
let build_rs = r#"
499+
fn main() {
500+
let has_debug_assertions = std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some();
501+
assert!(!has_debug_assertions, "CARGO_CFG_DEBUG_ASSERTIONS should NOT be set when dev profile disables it");
502+
}
503+
"#;
504+
505+
let p = project()
506+
.file(
507+
"Cargo.toml",
508+
r#"
509+
[package]
510+
name = "foo"
511+
version = "0.1.0"
512+
edition = "2024"
513+
514+
[profile.dev]
515+
debug-assertions = false
516+
"#,
517+
)
518+
.file("src/lib.rs", r#""#)
519+
.file("build.rs", build_rs)
520+
.build();
521+
522+
// Dev profile with debug-assertions explicitly disabled
523+
p.cargo("check").run();
524+
}
525+
526+
#[cargo_test]
527+
fn build_script_debug_assertions_override_release() {
528+
// Test that CARGO_CFG_DEBUG_ASSERTIONS respects profile overrides
529+
// Release profile with debug-assertions explicitly ENABLED
530+
let build_rs = r#"
531+
fn main() {
532+
let has_debug_assertions = std::env::var_os("CARGO_CFG_DEBUG_ASSERTIONS").is_some();
533+
assert!(has_debug_assertions, "CARGO_CFG_DEBUG_ASSERTIONS should be set when release profile enables it");
534+
}
535+
"#;
536+
537+
let p = project()
538+
.file(
539+
"Cargo.toml",
540+
r#"
541+
[package]
542+
name = "foo"
543+
version = "0.1.0"
544+
edition = "2024"
545+
546+
[profile.release]
547+
debug-assertions = true
548+
"#,
549+
)
550+
.file("src/lib.rs", r#""#)
551+
.file("build.rs", build_rs)
552+
.build();
553+
554+
// Release profile with debug-assertions explicitly enabled
555+
p.cargo("check --release").run();
556+
}
557+
558+
#[cargo_test]
559+
fn build_script_debug_assertions_build_override() {
560+
let build_rs = r#"
561+
fn main() {
562+
let profile = std::env::var("PROFILE").unwrap();
563+
if profile == "debug" {
564+
assert!(!cfg!(debug_assertions));
565+
} else if profile == "release" {
566+
assert!(cfg!(debug_assertions));
567+
}
568+
}
569+
"#;
570+
571+
let p = project()
572+
.file(
573+
"Cargo.toml",
574+
r#"
575+
[package]
576+
name = "foo"
577+
version = "0.1.0"
578+
edition = "2024"
579+
580+
[profile.dev.build-override]
581+
debug-assertions = false
582+
583+
[profile.release.build-override]
584+
debug-assertions = true
585+
"#,
586+
)
587+
.file("src/lib.rs", r#""#)
588+
.file("build.rs", build_rs)
589+
.build();
590+
591+
p.cargo("check").run();
592+
p.cargo("check --release").run();
593+
}

0 commit comments

Comments
 (0)