Skip to content

Commit

Permalink
feat(build-script): Pass CARGO_CFG_FEATURE
Browse files Browse the repository at this point in the history
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
  • Loading branch information
epage committed Dec 9, 2024
1 parent bcc217d commit f4ef735
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 3 deletions.
1 change: 1 addition & 0 deletions crates/build-rs-test-lib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
7 changes: 7 additions & 0 deletions crates/build-rs/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> {
to_strings(var_or_panic(&cargo_cfg_var("target_feature")), ',')
}

#[cfg(any())]
#[track_caller]
pub fn cargo_cfg_clippy() -> bool {
Expand Down
14 changes: 14 additions & 0 deletions crates/build-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,20 @@ MSRV: Respected as of "#,
};
}

macro_rules! requires_msrv {
($ver:literal) => {
concat!(
r#"<div class="warning">
MSRV: Requires "#,
$ver,
r#".
</div>"#
)
};
}

mod ident;

pub mod input;
Expand Down
4 changes: 4 additions & 0 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<Vec<_>>(),
);
for cfg in bcx.target_data.cfg(unit.kind) {
match *cfg {
Cfg::Name(ref n) => {
Expand Down
4 changes: 2 additions & 2 deletions src/doc/src/reference/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand All @@ -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.
Expand Down
5 changes: 4 additions & 1 deletion tests/testsuite/build_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -176,6 +176,7 @@ fn custom_build_env_vars() {
[features]
foo = []
other = []
"#,
)
.file("bar/src/lib.rs", "pub fn hello() {}");
Expand Down Expand Up @@ -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() {{
Expand Down

0 comments on commit f4ef735

Please sign in to comment.