diff --git a/crates/build-rs-test-lib/build.rs b/crates/build-rs-test-lib/build.rs index eff04806a73..0592a374915 100644 --- a/crates/build-rs-test-lib/build.rs +++ b/crates/build-rs-test-lib/build.rs @@ -9,6 +9,7 @@ fn main() { fn smoke_test_inputs() { use build_rs::input::*; dbg!(cargo()); + dbg!(cargo_cfg_feature()); dbg!(cargo_cfg("careful")); #[cfg(feature = "unstable")] dbg!(cargo_cfg_fmt_debug()); diff --git a/crates/build-rs/src/input.rs b/crates/build-rs/src/input.rs index 112aa5fed4e..6cfdd3268a6 100644 --- a/crates/build-rs/src/input.rs +++ b/crates/build-rs/src/input.rs @@ -102,6 +102,13 @@ mod cfg { // those disabled with #[cfg(any())] don't seem meaningfully useful // but we list all cfg that are default known to check-cfg + /// Each activated feature of the package being built + #[doc = requires_msrv!("1.85")] + #[track_caller] + pub fn cargo_cfg_feature() -> Vec { + to_strings(var_or_panic(&cargo_cfg_var("target_feature")), ',') + } + #[cfg(any())] #[track_caller] pub fn cargo_cfg_clippy() -> bool { diff --git a/crates/build-rs/src/lib.rs b/crates/build-rs/src/lib.rs index bc511f6f629..6221e44d3bd 100644 --- a/crates/build-rs/src/lib.rs +++ b/crates/build-rs/src/lib.rs @@ -40,6 +40,20 @@ MSRV: Respected as of "#, }; } +macro_rules! requires_msrv { + ($ver:literal) => { + concat!( + r#"
+ +MSRV: Requires "#, + $ver, + r#". + +
"# + ) + }; +} + mod ident; pub mod input; diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index a9928ab58c6..9f7287baace 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -336,6 +336,10 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul } let mut cfg_map = HashMap::new(); + cfg_map.insert( + "feature", + unit.features.iter().map(|s| s.as_str()).collect::>(), + ); for cfg in bcx.target_data.cfg(unit.kind) { match *cfg { Cfg::Name(ref n) => { diff --git a/src/doc/src/reference/environment-variables.md b/src/doc/src/reference/environment-variables.md index c47c5d178d0..0e1dcd3435e 100644 --- a/src/doc/src/reference/environment-variables.md +++ b/src/doc/src/reference/environment-variables.md @@ -342,6 +342,7 @@ let out_dir = env::var("OUT_DIR").unwrap(); values built-in to the compiler (which can be seen with `rustc --print=cfg`) and values set by build scripts and extra flags passed to `rustc` (such as those defined in `RUSTFLAGS`). Some examples of what these variables are: + * `CARGO_CFG_FEATURE` --- Each activated feature of the package being built. * `CARGO_CFG_UNIX` --- Set on [unix-like platforms]. * `CARGO_CFG_WINDOWS` --- Set on [windows-like platforms]. * `CARGO_CFG_TARGET_FAMILY=unix,wasm` --- The [target family]. @@ -356,8 +357,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`, `test`, and Cargo features like - > `feature="foo"` are not available. + > Some cfg values like `debug_assertions` and `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_script.rs b/tests/testsuite/build_script.rs index 5725c728ea7..ed41f4db4ca 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -156,7 +156,7 @@ fn custom_build_env_vars() { authors = ["wycats@example.com"] [features] - bar_feat = ["bar/foo"] + bar_feat = ["bar/foo", "bar/other"] [dependencies.bar] path = "bar" @@ -176,6 +176,7 @@ fn custom_build_env_vars() { [features] foo = [] + other = [] "#, ) .file("bar/src/lib.rs", "pub fn hello() {}"); @@ -213,6 +214,8 @@ fn custom_build_env_vars() { let _host = env::var("HOST").unwrap(); let _feat = env::var("CARGO_FEATURE_FOO").unwrap(); + let feat = env::var("CARGO_CFG_FEATURE").unwrap(); + assert_eq!(feat, "foo,other"); let cargo = env::var("CARGO").unwrap(); if env::var_os("CHECK_CARGO_IS_RUSTC").is_some() {{