diff --git a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix index be4bbbe06dc9..060ce25df8db 100644 --- a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix @@ -49,7 +49,7 @@ let completeDepsDir = lib.concatStringsSep " " completeDeps; completeBuildDepsDir = lib.concatStringsSep " " completeBuildDeps; envFeatures = lib.concatStringsSep " " ( - map (f: lib.replaceStrings [ "-" ] [ "_" ] (lib.toUpper f)) crateFeatures + map (f: "CARGO_FEATURE_${lib.replaceStrings [ "-" ] [ "_" ] (lib.toUpper f)}=1") crateFeatures ); in '' @@ -206,11 +206,10 @@ in ( # Features should be set as environment variable for build scripts: # https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts - for feature in ${envFeatures}; do - export CARGO_FEATURE_$feature=1 - done - - target/build/${crateName}/build_script_build | tee target/build/${crateName}.opt + # + # We use `env` instead of `export` because it's possible for a Cargo feature name to contain a character that Bash does + # not support for variables. + env ${envFeatures} target/build/${crateName}/build_script_build | tee target/build/${crateName}.opt ) set +e diff --git a/pkgs/build-support/rust/build-rust-crate/test/default.nix b/pkgs/build-support/rust/build-rust-crate/test/default.nix index d5c56858c6a4..dafb3ce631d7 100644 --- a/pkgs/build-support/rust/build-rust-crate/test/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/test/default.nix @@ -477,6 +477,7 @@ rec { crateName = "build-script-feature-env"; features = [ "some-feature" + "some-c++17-thing" "crate/another_feature" ]; src = symlinkJoin { @@ -488,6 +489,10 @@ rec { fn feature_not_visible() { assert!(std::env::var("CARGO_FEATURE_SOME_FEATURE").is_err()); assert!(option_env!("CARGO_FEATURE_SOME_FEATURE").is_none()); + assert!(std::env::var("CARGO_FEATURE_SOME_C++17_THING").is_err()); + assert!(option_env!("CARGO_FEATURE_SOME_C++17_THING").is_none()); + assert!(std::env::var("CARGO_FEATURE_ANOTHER_FEATURE").is_err()); + assert!(option_env!("CARGO_FEATURE_ANOTHER_FEATURE").is_none()); } fn main() {} '') @@ -495,6 +500,10 @@ rec { fn main() { assert!(std::env::var("CARGO_FEATURE_SOME_FEATURE").is_ok()); assert!(option_env!("CARGO_FEATURE_SOME_FEATURE").is_none()); + assert!(std::env::var("CARGO_FEATURE_SOME_C++17_THING").is_ok()); + assert!(option_env!("CARGO_FEATURE_SOME_C++17_THING").is_none()); + assert!(std::env::var("CARGO_FEATURE_ANOTHER_FEATURE").is_err()); + assert!(option_env!("CARGO_FEATURE_ANOTHER_FEATURE").is_none()); } '') ];