From ea6e048c37eff63e057f767410acd8fc911ba078 Mon Sep 17 00:00:00 2001 From: Daniël de Kok Date: Thu, 12 Mar 2020 12:29:31 +0100 Subject: buildRustCrate: only link build deps into build script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the Cargo documentation: > The build script does not have access to the dependencies listed in > the dependencies or dev-dependencies section (they’re not built > yet!). Also, build dependencies are not available to the package > itself unless also explicitly added in the [dependencies] table. https://doc.rust-lang.org/cargo/reference/build-scripts.html This change separates linkage of regular dependencies and build dependencies. --- .../rust/build-rust-crate/configure-crate.nix | 63 ++++++++++++++++------ pkgs/build-support/rust/build-rust-crate/lib.sh | 1 + .../rust/build-rust-crate/test/default.nix | 30 +++++++++++ 3 files changed, 79 insertions(+), 15 deletions(-) (limited to 'pkgs/build-support/rust') 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 013b99a77b4b2..2f7d3b77f3974 100644 --- a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix @@ -56,32 +56,66 @@ in '' i=$1 ln -s -f $i/lib/*.rlib $2 #*/ ln -s -f $i/lib/*.so $i/lib/*.dylib $2 #*/ - if [ -e "$i/lib/link" ]; then - cat $i/lib/link >> target/link - cat $i/lib/link >> target/link.final - fi if [ -e $i/env ]; then source $i/env fi } + # The following steps set up the dependencies of the crate. Two + # kinds of dependencies are distinguished: build dependencies + # (used by the build script) and crate dependencies. For each + # dependency we have to: + # + # - Make its Rust library available to rustc. This is done by + # symlinking all library dependencies into a directory that + # can be provided to rustc. + # - Accumulate linking flags. These flags are largely used for + # linking native libraries. + # + # The crate link flags are added to the `link` and `link.final` + # files. The `link` file is used for linkage in the current + # crate. The `link.final` file will be copied to the output and can + # be used by downstream crates to get the linker flags of this + # crate. + mkdir -p target/{deps,lib,build,buildDeps} chmod uga+w target -R echo ${extraLinkFlags} > target/link echo ${extraLinkFlags} > target/link.final + + # Prepare crate dependencies for i in ${completeDepsDir}; do symlink_dependency $i target/deps + if [ -e "$i/lib/link" ]; then + cat $i/lib/link >> target/link + cat $i/lib/link >> target/link.final + fi done + + # Prepare crate build dependencies that are used for the build script. for i in ${completeBuildDepsDir}; do - symlink_dependency $i target/buildDeps + symlink_dependency $i target/buildDeps + if [ -e "$i/lib/link" ]; then + cat $i/lib/link >> target/link.build + fi done - if [[ -e target/link ]]; then - sort -u target/link > target/link.sorted - mv target/link.sorted target/link - sort -u target/link.final > target/link.final.sorted - mv target/link.final.sorted target/link.final - tr '\n' ' ' < target/link > target/link_ + + # Remove duplicate linker flags from the build dependencies. + if [[ -e target/link.build ]]; then + sort -u target/link.build > target/link.build.sorted + mv target/link.build.sorted target/link.build fi + + # Remove duplicate linker flags from the dependencies. + sort -u target/link > target/link.sorted + mv target/link.sorted target/link + tr '\n' ' ' < target/link > target/link_ + + # Remove duplicate linker flags from the that are written + # to the derivation's output. + sort -u target/link.final > target/link.final.sorted + mv target/link.final.sorted target/link.final + EXTRA_BUILD="" BUILD_OUT_DIR="" export CARGO_PKG_NAME=${crateName} @@ -120,15 +154,14 @@ in '' elif [[ -e "build.rs" ]]; then BUILD="build.rs" fi + + # Compile and run the build script, when available. if [[ ! -z "$BUILD" ]] ; then echo_build_heading "$BUILD" ${libName} mkdir -p target/build/${crateName} EXTRA_BUILD_FLAGS="" - if [ -e target/link_ ]; then - EXTRA_BUILD_FLAGS=$(cat target/link_) - fi if [ -e target/link.build ]; then - EXTRA_BUILD_FLAGS="$EXTRA_BUILD_FLAGS $(cat target/link.build)" + EXTRA_BUILD_FLAGS="$EXTRA_BUILD_FLAGS $(tr '\n' ' ' < target/link.build)" fi noisily rustc --crate-name build_script_build $BUILD --crate-type bin ${rustcOpts} \ ${crateFeatures} --out-dir target/build/${crateName} --emit=dep-info,link \ diff --git a/pkgs/build-support/rust/build-rust-crate/lib.sh b/pkgs/build-support/rust/build-rust-crate/lib.sh index 0f08c133e5572..5843ee98b0d56 100644 --- a/pkgs/build-support/rust/build-rust-crate/lib.sh +++ b/pkgs/build-support/rust/build-rust-crate/lib.sh @@ -79,6 +79,7 @@ build_bin_test_file() { build_bin_test "$derived_crate_name" "$file" } +# Add additional link options that were provided by the build script. setup_link_paths() { EXTRA_LIB="" if [[ -e target/link_ ]]; then 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 710045664686b..f24583c41fcbd 100644 --- a/pkgs/build-support/rust/build-rust-crate/test/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/test/default.nix @@ -207,6 +207,36 @@ let }) ]; }; + buildScriptDeps = let + depCrate = boolVal: mkCrate { + crateName = "bar"; + src = mkFile "src/lib.rs" '' + pub const baz: bool = ${boolVal}; + ''; + }; + in { + crateName = "foo"; + src = symlinkJoin { + name = "build-script-and-main"; + paths = [ + (mkFile "src/main.rs" '' + extern crate bar; + #[cfg(test)] + #[test] + fn baz_false() { assert!(!bar::baz); } + fn main() { } + '') + (mkFile "build.rs" '' + extern crate bar; + fn main() { assert!(bar::baz); } + '') + ]; + }; + buildDependencies = [ (depCrate "true") ]; + dependencies = [ (depCrate "false") ]; + buildTests = true; + expectedTestOutputs = [ "test baz_false ... 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 = { -- cgit 1.4.1 From 412c72d20f067dfb45aaa041c2333fbdc82dca6d Mon Sep 17 00:00:00 2001 From: Daniël de Kok Date: Fri, 13 Mar 2020 11:21:07 +0100 Subject: buildRustCrate: sort linker options in-place --- pkgs/build-support/rust/build-rust-crate/configure-crate.nix | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'pkgs/build-support/rust') 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 2f7d3b77f3974..61c39c6b21c0c 100644 --- a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix @@ -102,19 +102,16 @@ in '' # Remove duplicate linker flags from the build dependencies. if [[ -e target/link.build ]]; then - sort -u target/link.build > target/link.build.sorted - mv target/link.build.sorted target/link.build + sort -uo target/link.build target/link.build fi # Remove duplicate linker flags from the dependencies. - sort -u target/link > target/link.sorted - mv target/link.sorted target/link + sort -uo target/link target/link tr '\n' ' ' < target/link > target/link_ # Remove duplicate linker flags from the that are written # to the derivation's output. - sort -u target/link.final > target/link.final.sorted - mv target/link.final.sorted target/link.final + sort -uo target/link.final target/link.final EXTRA_BUILD="" BUILD_OUT_DIR="" -- cgit 1.4.1