Merge pull request #90193 from danieldk/build-rs-feature-env
buildRustCrate: set CARGO_FEATURE_* when running the build script
This commit is contained in:
commit
d282a7e07f
|
@ -1,4 +1,4 @@
|
||||||
{ lib, stdenv, mkRustcDepArgs, rust }:
|
{ lib, stdenv, mkRustcDepArgs, mkRustcFeatureArgs, rust }:
|
||||||
{ crateName,
|
{ crateName,
|
||||||
dependencies,
|
dependencies,
|
||||||
crateFeatures, crateRenames, libName, release, libPath,
|
crateFeatures, crateRenames, libName, release, libPath,
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
++ ["-C codegen-units=$NIX_BUILD_CORES"]
|
++ ["-C codegen-units=$NIX_BUILD_CORES"]
|
||||||
++ ["--remap-path-prefix=$NIX_BUILD_TOP=/" ]
|
++ ["--remap-path-prefix=$NIX_BUILD_TOP=/" ]
|
||||||
++ [(mkRustcDepArgs dependencies crateRenames)]
|
++ [(mkRustcDepArgs dependencies crateRenames)]
|
||||||
++ [crateFeatures]
|
++ [(mkRustcFeatureArgs crateFeatures)]
|
||||||
++ extraRustcOpts
|
++ extraRustcOpts
|
||||||
++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTarget stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc"
|
++ lib.optional (stdenv.hostPlatform != stdenv.buildPlatform) "--target ${rust.toRustTarget stdenv.hostPlatform} -C linker=${stdenv.hostPlatform.config}-gcc"
|
||||||
# since rustc 1.42 the "proc_macro" crate is part of the default crate prelude
|
# since rustc 1.42 the "proc_macro" crate is part of the default crate prelude
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{ lib, stdenv, echo_colored, noisily, mkRustcDepArgs }:
|
{ lib, stdenv, echo_colored, noisily, mkRustcDepArgs, mkRustcFeatureArgs }:
|
||||||
{ build
|
{
|
||||||
|
build
|
||||||
, buildDependencies
|
, buildDependencies
|
||||||
, colors
|
, colors
|
||||||
, completeBuildDeps
|
, completeBuildDeps
|
||||||
|
@ -30,6 +31,9 @@ let version_ = lib.splitString "-" crateVersion;
|
||||||
optLevel = if release then 3 else 0;
|
optLevel = if release then 3 else 0;
|
||||||
completeDepsDir = lib.concatStringsSep " " completeDeps;
|
completeDepsDir = lib.concatStringsSep " " completeDeps;
|
||||||
completeBuildDepsDir = lib.concatStringsSep " " completeBuildDeps;
|
completeBuildDepsDir = lib.concatStringsSep " " completeBuildDeps;
|
||||||
|
envFeatures = lib.concatStringsSep " " (
|
||||||
|
map (f: lib.replaceChars ["-"] ["_"] (lib.toUpper f)) crateFeatures
|
||||||
|
);
|
||||||
in ''
|
in ''
|
||||||
${echo_colored colors}
|
${echo_colored colors}
|
||||||
${noisily colors verbose}
|
${noisily colors verbose}
|
||||||
|
@ -161,14 +165,24 @@ in ''
|
||||||
EXTRA_BUILD_FLAGS="$EXTRA_BUILD_FLAGS $(tr '\n' ' ' < target/link.build)"
|
EXTRA_BUILD_FLAGS="$EXTRA_BUILD_FLAGS $(tr '\n' ' ' < target/link.build)"
|
||||||
fi
|
fi
|
||||||
noisily rustc --crate-name build_script_build $BUILD --crate-type bin ${rustcOpts} \
|
noisily rustc --crate-name build_script_build $BUILD --crate-type bin ${rustcOpts} \
|
||||||
${crateFeatures} --out-dir target/build/${crateName} --emit=dep-info,link \
|
${mkRustcFeatureArgs crateFeatures} --out-dir target/build/${crateName} --emit=dep-info,link \
|
||||||
-L dependency=target/buildDeps ${buildDeps} --cap-lints allow $EXTRA_BUILD_FLAGS --color ${colors}
|
-L dependency=target/buildDeps ${buildDeps} --cap-lints allow $EXTRA_BUILD_FLAGS --color ${colors}
|
||||||
|
|
||||||
mkdir -p target/build/${crateName}.out
|
mkdir -p target/build/${crateName}.out
|
||||||
export RUST_BACKTRACE=1
|
export RUST_BACKTRACE=1
|
||||||
BUILD_OUT_DIR="-L $OUT_DIR"
|
BUILD_OUT_DIR="-L $OUT_DIR"
|
||||||
mkdir -p $OUT_DIR
|
mkdir -p $OUT_DIR
|
||||||
|
|
||||||
|
(
|
||||||
|
# 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 > target/build/${crateName}.opt
|
target/build/${crateName}/build_script_build > target/build/${crateName}.opt
|
||||||
|
)
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
EXTRA_BUILD=$(sed -n "s/^cargo:rustc-flags=\(.*\)/\1/p" target/build/${crateName}.opt | tr '\n' ' ' | sort -u)
|
EXTRA_BUILD=$(sed -n "s/^cargo:rustc-flags=\(.*\)/\1/p" target/build/${crateName}.opt | tr '\n' ' ' | sort -u)
|
||||||
EXTRA_FEATURES=$(sed -n "s/^cargo:rustc-cfg=\(.*\)/--cfg \1/p" target/build/${crateName}.opt | tr '\n' ' ')
|
EXTRA_FEATURES=$(sed -n "s/^cargo:rustc-cfg=\(.*\)/--cfg \1/p" target/build/${crateName}.opt | tr '\n' ' ')
|
||||||
|
|
|
@ -45,14 +45,17 @@ let
|
||||||
" --extern ${name}=${dep.lib}/lib/lib${extern}-${dep.metadata}${stdenv.hostPlatform.extensions.sharedLibrary}")
|
" --extern ${name}=${dep.lib}/lib/lib${extern}-${dep.metadata}${stdenv.hostPlatform.extensions.sharedLibrary}")
|
||||||
) dependencies;
|
) dependencies;
|
||||||
|
|
||||||
|
# Create feature arguments for rustc.
|
||||||
|
mkRustcFeatureArgs = lib.concatMapStringsSep " " (f: ''--cfg feature=\"${f}\"'');
|
||||||
|
|
||||||
inherit (import ./log.nix { inherit lib; }) noisily echo_colored;
|
inherit (import ./log.nix { inherit lib; }) noisily echo_colored;
|
||||||
|
|
||||||
configureCrate = import ./configure-crate.nix {
|
configureCrate = import ./configure-crate.nix {
|
||||||
inherit lib stdenv echo_colored noisily mkRustcDepArgs;
|
inherit lib stdenv echo_colored noisily mkRustcDepArgs mkRustcFeatureArgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
buildCrate = import ./build-crate.nix {
|
buildCrate = import ./build-crate.nix {
|
||||||
inherit lib stdenv mkRustcDepArgs rust;
|
inherit lib stdenv mkRustcDepArgs mkRustcFeatureArgs rust;
|
||||||
};
|
};
|
||||||
|
|
||||||
installCrate = import ./install-crate.nix { inherit stdenv; };
|
installCrate = import ./install-crate.nix { inherit stdenv; };
|
||||||
|
@ -233,8 +236,11 @@ stdenv.mkDerivation (rec {
|
||||||
++ lib.concatMap (dep: dep.completeBuildDeps ++ dep.completeDeps) buildDependencies
|
++ lib.concatMap (dep: dep.completeBuildDeps ++ dep.completeDeps) buildDependencies
|
||||||
);
|
);
|
||||||
|
|
||||||
crateFeatures = lib.optionalString (crate ? features)
|
# Create a list of features that are enabled by the crate itself and
|
||||||
(lib.concatMapStringsSep " " (f: ''--cfg feature=\"${f}\"'') (crate.features ++ features));
|
# through the features argument of buildRustCrate. Exclude features
|
||||||
|
# with a forward slash, since they are passed through to dependencies.
|
||||||
|
crateFeatures = lib.optionals (crate ? features)
|
||||||
|
(builtins.filter (f: !lib.hasInfix "/" f) (crate.features ++ features));
|
||||||
|
|
||||||
libName = if crate ? libName then crate.libName else crate.crateName;
|
libName = if crate ? libName then crate.libName else crate.crateName;
|
||||||
libPath = if crate ? libPath then crate.libPath else "";
|
libPath = if crate ? libPath then crate.libPath else "";
|
||||||
|
@ -244,7 +250,8 @@ stdenv.mkDerivation (rec {
|
||||||
metadata = let
|
metadata = let
|
||||||
depsMetadata = lib.foldl' (str: dep: str + dep.metadata) "" (dependencies ++ buildDependencies);
|
depsMetadata = lib.foldl' (str: dep: str + dep.metadata) "" (dependencies ++ buildDependencies);
|
||||||
hashedMetadata = builtins.hashString "sha256"
|
hashedMetadata = builtins.hashString "sha256"
|
||||||
(crateName + "-" + crateVersion + "___" + toString crateFeatures + "___" + depsMetadata);
|
(crateName + "-" + crateVersion + "___" + toString (mkRustcFeatureArgs crateFeatures) +
|
||||||
|
"___" + depsMetadata);
|
||||||
in lib.substring 0 10 hashedMetadata;
|
in lib.substring 0 10 hashedMetadata;
|
||||||
|
|
||||||
build = crate.build or "";
|
build = crate.build or "";
|
||||||
|
|
|
@ -344,6 +344,32 @@ let
|
||||||
buildTests = true;
|
buildTests = true;
|
||||||
expectedTestOutputs = [ "test baz_false ... ok" ];
|
expectedTestOutputs = [ "test baz_false ... ok" ];
|
||||||
};
|
};
|
||||||
|
buildScriptFeatureEnv = {
|
||||||
|
crateName = "build-script-feature-env";
|
||||||
|
features = [ "some-feature" "crate/another_feature" ];
|
||||||
|
src = symlinkJoin {
|
||||||
|
name = "build-script-feature-env";
|
||||||
|
paths = [
|
||||||
|
(mkFile "src/main.rs" ''
|
||||||
|
#[cfg(test)]
|
||||||
|
#[test]
|
||||||
|
fn feature_not_visible() {
|
||||||
|
assert!(std::env::var("CARGO_FEATURE_SOME_FEATURE").is_err());
|
||||||
|
assert!(option_env!("CARGO_FEATURE_SOME_FEATURE").is_none());
|
||||||
|
}
|
||||||
|
fn main() {}
|
||||||
|
'')
|
||||||
|
(mkFile "build.rs" ''
|
||||||
|
fn main() {
|
||||||
|
assert!(std::env::var("CARGO_FEATURE_SOME_FEATURE").is_ok());
|
||||||
|
assert!(option_env!("CARGO_FEATURE_SOME_FEATURE").is_none());
|
||||||
|
}
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
buildTests = true;
|
||||||
|
expectedTestOutputs = [ "test feature_not_visible ... ok" ];
|
||||||
|
};
|
||||||
# Regression test for https://github.com/NixOS/nixpkgs/pull/88054
|
# Regression test for https://github.com/NixOS/nixpkgs/pull/88054
|
||||||
# Build script output should be rewritten as valid env vars.
|
# Build script output should be rewritten as valid env vars.
|
||||||
buildScriptIncludeDirDeps = let
|
buildScriptIncludeDirDeps = let
|
||||||
|
|
Loading…
Reference in New Issue