diff options
author | Ilan Joselevich <personal@ilanjoselevich.com> | 2024-06-21 14:21:47 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-21 14:21:47 +0300 |
commit | d9e50897517e3de79a42f3556dbfac89d2d670b9 (patch) | |
tree | 980076b737f5abc4a8f0c4c37e8404a51558eb87 | |
parent | 9b8794fc6f11a6aa985cf2a2a62d4e7d27d65bd0 (diff) | |
parent | 95bb41081771810971ac96f1e1ed76ef1dea57bf (diff) |
Merge pull request #321220 from thehabbos007/cargo-colon
buildRustCrate: support new cargo invocation syntax for build script outputs
-rw-r--r-- | pkgs/build-support/rust/build-rust-crate/configure-crate.nix | 24 | ||||
-rw-r--r-- | pkgs/build-support/rust/build-rust-crate/test/default.nix | 47 |
2 files changed, 61 insertions, 10 deletions
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 4077ee5ced8e..ab872bac854f 100644 --- a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix @@ -198,13 +198,16 @@ in '' ) set +e - 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_LINK_ARGS=$(sed -n "s/^cargo:rustc-link-arg=\(.*\)/-C link-arg=\1/p" target/build/${crateName}.opt | tr '\n' ' ') - EXTRA_LINK_ARGS_BINS=$(sed -n "s/^cargo:rustc-link-arg-bins=\(.*\)/-C link-arg=\1/p" target/build/${crateName}.opt | tr '\n' ' ') - EXTRA_LINK_ARGS_LIB=$(sed -n "s/^cargo:rustc-link-arg-lib=\(.*\)/-C link-arg=\1/p" target/build/${crateName}.opt | tr '\n' ' ') - EXTRA_LINK_LIBS=$(sed -n "s/^cargo:rustc-link-lib=\(.*\)/\1/p" target/build/${crateName}.opt | tr '\n' ' ') - EXTRA_LINK_SEARCH=$(sed -n "s/^cargo:rustc-link-search=\(.*\)/\1/p" target/build/${crateName}.opt | tr '\n' ' ' | sort -u) + # We want to support the new prefix invocation syntax which uses two colons + # See https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script + + EXTRA_BUILD=$(sed -n "s/^cargo::\{0,1\}rustc-flags=\(.*\)/\1/p" target/build/${crateName}.opt | tr '\n' ' ' | sort -u) + EXTRA_FEATURES=$(sed -n "s/^cargo::\{0,1\}rustc-cfg=\(.*\)/--cfg \1/p" target/build/${crateName}.opt | tr '\n' ' ') + EXTRA_LINK_ARGS=$(sed -n "s/^cargo::\{0,1\}rustc-link-arg=\(.*\)/-C link-arg=\1/p" target/build/${crateName}.opt | tr '\n' ' ') + EXTRA_LINK_ARGS_BINS=$(sed -n "s/^cargo::\{0,1\}rustc-link-arg-bins=\(.*\)/-C link-arg=\1/p" target/build/${crateName}.opt | tr '\n' ' ') + EXTRA_LINK_ARGS_LIB=$(sed -n "s/^cargo::\{0,1\}rustc-link-arg-lib=\(.*\)/-C link-arg=\1/p" target/build/${crateName}.opt | tr '\n' ' ') + EXTRA_LINK_LIBS=$(sed -n "s/^cargo::\{0,1\}rustc-link-lib=\(.*\)/\1/p" target/build/${crateName}.opt | tr '\n' ' ') + EXTRA_LINK_SEARCH=$(sed -n "s/^cargo::\{0,1\}rustc-link-search=\(.*\)/\1/p" target/build/${crateName}.opt | tr '\n' ' ' | sort -u) # We want to read part of every line that has cargo:rustc-env= prefix and # export it as environment variables. This turns out tricky if the lines @@ -217,14 +220,15 @@ in '' # _OLDIFS="$IFS" IFS=$'\n' - for env in $(sed -n "s/^cargo:rustc-env=\(.*\)/\1/p" target/build/${crateName}.opt); do + for env in $(sed -n "s/^cargo::\{0,1\}rustc-env=\(.*\)/\1/p" target/build/${crateName}.opt); do export "$env" done IFS="$_OLDIFS" CRATENAME=$(echo ${crateName} | sed -e "s/\(.*\)-sys$/\U\1/" -e "s/-/_/g") - grep -P "^cargo:(?!(rustc-|warning=|rerun-if-changed=|rerun-if-env-changed))" target/build/${crateName}.opt \ - | awk -F= "/^cargo:/ { sub(/^cargo:/, \"\", \$1); gsub(/-/, \"_\", \$1); print \"export \" toupper(\"DEP_$(echo $CRATENAME)_\" \$1) \"=\" \"\\\"\"\$2\"\\\"\" }" > target/env + grep -P "^cargo:(?!:?(rustc-|warning=|rerun-if-changed=|rerun-if-env-changed))" target/build/${crateName}.opt \ + | awk -F= "/^cargo::metadata=/ { gsub(/-/, \"_\", \$2); print \"export \" toupper(\"DEP_$(echo $CRATENAME)_\" \$2) \"=\" \"\\\"\"\$3\"\\\"\"; next } + /^cargo:/ { sub(/^cargo::?/, \"\", \$1); gsub(/-/, \"_\", \$1); print \"export \" toupper(\"DEP_$(echo $CRATENAME)_\" \$1) \"=\" \"\\\"\"\$2\"\\\"\"; next }" > target/env set -e fi runHook postConfigure 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 522eedfede7f..d020031a92f9 100644 --- a/pkgs/build-support/rust/build-rust-crate/test/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/test/default.nix @@ -421,6 +421,53 @@ let buildDependencies = [ depCrate ]; dependencies = [ depCrate ]; }; + # Support new invocation prefix for build scripts `cargo::` + # https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script + buildScriptInvocationPrefix = let + depCrate = buildRustCrate: mkCrate buildRustCrate { + crateName = "bar"; + src = mkFile "build.rs" '' + fn main() { + // Old invocation prefix + // We likely won't see be mixing these syntaxes in the same build script in the wild. + println!("cargo:key_old=value_old"); + + // New invocation prefix + println!("cargo::metadata=key=value"); + println!("cargo::metadata=key_complex=complex(value)"); + } + ''; + }; + in { + crateName = "foo"; + src = symlinkJoin { + name = "build-script-and-main-invocation-prefix"; + paths = [ + (mkFile "src/main.rs" '' + const BUILDFOO: &'static str = env!("BUILDFOO"); + + #[test] + fn build_foo_check() { assert!(BUILDFOO == "yes(check)"); } + + fn main() { } + '') + (mkFile "build.rs" '' + use std::env; + fn main() { + assert!(env::var_os("DEP_BAR_KEY_OLD").expect("metadata key 'key_old' not set in dependency") == "value_old"); + assert!(env::var_os("DEP_BAR_KEY").expect("metadata key 'key' not set in dependency") == "value"); + assert!(env::var_os("DEP_BAR_KEY_COMPLEX").expect("metadata key 'key_complex' not set in dependency") == "complex(value)"); + + println!("cargo::rustc-env=BUILDFOO=yes(check)"); + } + '') + ]; + }; + buildDependencies = [ (depCrate buildPackages.buildRustCrate) ]; + dependencies = [ (depCrate buildRustCrate) ]; + buildTests = true; + expectedTestOutputs = [ "test build_foo_check ... ok" ]; + }; # Regression test for https://github.com/NixOS/nixpkgs/issues/74071 # Whenevever a build.rs file is generating files those should not be overlayed onto the actual source dir buildRsOutDirOverlay = { |