Skip to content

Commit f4ef735

Browse files
committed
feat(build-script): Pass CARGO_CFG_FEATURE
This may look redundant with `CARGO_FEATURE_<CASE_CONVERTED_NAME>=1` except that doesn't provide a lossless way of getting the names, e.g. for forwarding for child builds like tests that need to build examples. This also makes things more consistent as users conditionalize on features through `cfg` and this even fits with what the `CARGO_CFG_` docs say: > For each configuration option of the package being built, this > environment variable will contain the value of the configuration, where > <cfg> is the name of the configuration uppercased and having - > translated to _. Boolean configurations are present if they are set, and > not present otherwise. Configurations with multiple values are joined to > a single variable with the values delimited by ,. This includes 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: Fixes #3702
1 parent bcc217d commit f4ef735

File tree

6 files changed

+32
-3
lines changed

6 files changed

+32
-3
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ fn main() {
99
fn smoke_test_inputs() {
1010
use build_rs::input::*;
1111
dbg!(cargo());
12+
dbg!(cargo_cfg_feature());
1213
dbg!(cargo_cfg("careful"));
1314
#[cfg(feature = "unstable")]
1415
dbg!(cargo_cfg_fmt_debug());

crates/build-rs/src/input.rs

+7
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ mod cfg {
102102
// those disabled with #[cfg(any())] don't seem meaningfully useful
103103
// but we list all cfg that are default known to check-cfg
104104

105+
/// Each activated feature of the package being built
106+
#[doc = requires_msrv!("1.85")]
107+
#[track_caller]
108+
pub fn cargo_cfg_feature() -> Vec<String> {
109+
to_strings(var_or_panic(&cargo_cfg_var("target_feature")), ',')
110+
}
111+
105112
#[cfg(any())]
106113
#[track_caller]
107114
pub fn cargo_cfg_clippy() -> bool {

crates/build-rs/src/lib.rs

+14
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,20 @@ MSRV: Respected as of "#,
4040
};
4141
}
4242

43+
macro_rules! requires_msrv {
44+
($ver:literal) => {
45+
concat!(
46+
r#"<div class="warning">
47+
48+
MSRV: Requires "#,
49+
$ver,
50+
r#".
51+
52+
</div>"#
53+
)
54+
};
55+
}
56+
4357
mod ident;
4458

4559
pub mod input;

src/cargo/core/compiler/custom_build.rs

+4
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,10 @@ fn build_work(build_runner: &mut BuildRunner<'_, '_>, unit: &Unit) -> CargoResul
336336
}
337337

338338
let mut cfg_map = HashMap::new();
339+
cfg_map.insert(
340+
"feature",
341+
unit.features.iter().map(|s| s.as_str()).collect::<Vec<_>>(),
342+
);
339343
for cfg in bcx.target_data.cfg(unit.kind) {
340344
match *cfg {
341345
Cfg::Name(ref n) => {

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,7 @@ let out_dir = env::var("OUT_DIR").unwrap();
342342
values built-in to the compiler (which can be seen with `rustc --print=cfg`)
343343
and values set by build scripts and extra flags passed to `rustc` (such as
344344
those defined in `RUSTFLAGS`). Some examples of what these variables are:
345+
* `CARGO_CFG_FEATURE` --- Each activated feature of the package being built.
345346
* `CARGO_CFG_UNIX` --- Set on [unix-like platforms].
346347
* `CARGO_CFG_WINDOWS` --- Set on [windows-like platforms].
347348
* `CARGO_CFG_TARGET_FAMILY=unix,wasm` --- The [target family].
@@ -356,8 +357,7 @@ let out_dir = env::var("OUT_DIR").unwrap();
356357
> Note that different [target triples][Target Triple] have different sets of `cfg` values,
357358
> hence variables present in one target triple might not be available in the other.
358359
>
359-
> Some cfg values like `debug_assertions`, `test`, and Cargo features like
360-
> `feature="foo"` are not available.
360+
> Some cfg values like `debug_assertions` and `test` are not available.
361361
* `OUT_DIR` --- the folder in which all output and intermediate artifacts should
362362
be placed. This folder is inside the build directory for the package being built,
363363
and it is unique for the package in question.

tests/testsuite/build_script.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ fn custom_build_env_vars() {
156156
authors = ["[email protected]"]
157157
158158
[features]
159-
bar_feat = ["bar/foo"]
159+
bar_feat = ["bar/foo", "bar/other"]
160160
161161
[dependencies.bar]
162162
path = "bar"
@@ -176,6 +176,7 @@ fn custom_build_env_vars() {
176176
177177
[features]
178178
foo = []
179+
other = []
179180
"#,
180181
)
181182
.file("bar/src/lib.rs", "pub fn hello() {}");
@@ -213,6 +214,8 @@ fn custom_build_env_vars() {
213214
let _host = env::var("HOST").unwrap();
214215
215216
let _feat = env::var("CARGO_FEATURE_FOO").unwrap();
217+
let feat = env::var("CARGO_CFG_FEATURE").unwrap();
218+
assert_eq!(feat, "foo,other");
216219
217220
let cargo = env::var("CARGO").unwrap();
218221
if env::var_os("CHECK_CARGO_IS_RUSTC").is_some() {{

0 commit comments

Comments
 (0)