diff options
Diffstat (limited to 'pkgs/build-support/rust')
6 files changed, 64 insertions, 18 deletions
diff --git a/pkgs/build-support/rust/build-rust-crate/build-crate.nix b/pkgs/build-support/rust/build-rust-crate/build-crate.nix index 7484b3ad0290e..3af13fe70a7de 100644 --- a/pkgs/build-support/rust/build-rust-crate/build-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/build-crate.nix @@ -1,5 +1,5 @@ { lib, stdenv -, mkRustcDepArgs, mkRustcFeatureArgs, needUnstableCLI +, mkRustcDepArgs, mkRustcFeatureArgs, needUnstableCLI, rustc }: { crateName, @@ -27,6 +27,10 @@ # since rustc 1.42 the "proc_macro" crate is part of the default crate prelude # https://github.com/rust-lang/cargo/commit/4d64eb99a4#diff-7f98585dbf9d30aa100c8318e2c77e79R1021-R1022 ++ lib.optional (lib.elem "proc-macro" crateType) "--extern proc_macro" + ++ lib.optional (stdenv.hostPlatform.linker == "lld") # Needed when building for targets that use lld. e.g. 'wasm32-unknown-unknown' + "-C linker=${rustc.llvmPackages.lld}/bin/lld" + ++ lib.optional (stdenv.hasCC && stdenv.hostPlatform.linker != "lld") + "-C linker=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc" ; rustcMeta = "-C metadata=${metadata} -C extra-filename=-${metadata}"; @@ -39,10 +43,7 @@ ++ (map (x: "--crate-type ${x}") crateType) ); - binRustcOpts = lib.concatStringsSep " " ( - [ "-C linker=${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc" ] ++ - baseRustcOpts - ); + binRustcOpts = lib.concatStringsSep " " baseRustcOpts; build_bin = if buildTests then "build_bin_test" else "build_bin"; in '' 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 ab872bac854f8..fd61d73deb722 100644 --- a/pkgs/build-support/rust/build-rust-crate/configure-crate.nix +++ b/pkgs/build-support/rust/build-rust-crate/configure-crate.nix @@ -14,6 +14,7 @@ , crateLicenseFile , crateLinks , crateName +, crateType , crateReadme , crateRenames , crateRepository @@ -209,6 +210,11 @@ in '' 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) + ${lib.optionalString (lib.elem "cdylib" crateType) '' + CRATE_TYPE_IS_CDYLIB="true" + EXTRA_CDYLIB_LINK_ARGS=$(sed -n "s/^cargo::\{0,1\}rustc-cdylib-link-arg=\(.*\)/-C link-arg=\1/p" target/build/${crateName}.opt | tr '\n' ' ') +''} + # 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 # have spaces: we can't wrap the command in double quotes as that captures diff --git a/pkgs/build-support/rust/build-rust-crate/default.nix b/pkgs/build-support/rust/build-rust-crate/default.nix index dfe28cc334b5e..841e8e86cbfb1 100644 --- a/pkgs/build-support/rust/build-rust-crate/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/default.nix @@ -16,6 +16,16 @@ }: let + # Returns a true if the builder's rustc was built with support for the target. + targetAlreadyIncluded = lib.elem stdenv.hostPlatform.rust.rustcTarget + (lib.splitString "," (lib.removePrefix "--target=" ( + lib.elemAt (lib.filter (f: lib.hasPrefix "--target=" f) pkgsBuildBuild.rustc.unwrapped.configureFlags) 0) + )); + + # If the build's rustc was built with support for the target then reuse it. (Avoids uneeded compilation for targets like `wasm32-unknown-unknown`) + rustc' = if targetAlreadyIncluded then pkgsBuildBuild.rustc else rustc; + cargo' = if targetAlreadyIncluded then pkgsBuildBuild.cargo else cargo; + # Create rustc arguments to link against the given list of dependencies # and renames. # @@ -77,6 +87,7 @@ let buildCrate = import ./build-crate.nix { inherit lib stdenv mkRustcDepArgs mkRustcFeatureArgs needUnstableCLI; + rustc = rustc'; }; installCrate = import ./install-crate.nix { inherit stdenv; }; @@ -274,7 +285,8 @@ crate_: lib.makeOverridable name = "rust_${crate.crateName}-${crate.version}${lib.optionalString buildTests_ "-test"}"; version = crate.version; depsBuildBuild = [ pkgsBuildBuild.stdenv.cc ]; - nativeBuildInputs = [ rust stdenv.cc cargo jq ] + nativeBuildInputs = [ rustc' cargo' jq ] + ++ lib.optionals stdenv.hasCC [ stdenv.cc ] ++ lib.optionals stdenv.buildPlatform.isDarwin [ libiconv ] ++ (crate.nativeBuildInputs or [ ]) ++ nativeBuildInputs_; buildInputs = lib.optionals stdenv.isDarwin [ libiconv ] ++ (crate.buildInputs or [ ]) ++ buildInputs_; @@ -345,7 +357,7 @@ crate_: lib.makeOverridable configurePhase = configureCrate { - inherit crateName buildDependencies completeDeps completeBuildDeps crateDescription + inherit crateName crateType buildDependencies completeDeps completeBuildDeps crateDescription crateFeatures crateRenames libName build workspace_member release libPath crateVersion crateLinks extraLinkFlags extraRustcOptsForBuildRs crateLicense crateLicenseFile crateReadme crateRepository crateRustVersion @@ -380,7 +392,7 @@ crate_: lib.makeOverridable ) ) { - rust = rustc; + rust = rustc'; release = crate_.release or true; verbose = crate_.verbose or true; extraRustcOpts = [ ]; diff --git a/pkgs/build-support/rust/build-rust-crate/lib.sh b/pkgs/build-support/rust/build-rust-crate/lib.sh index 0181ae432c85b..36ddc9ac23c4f 100644 --- a/pkgs/build-support/rust/build-rust-crate/lib.sh +++ b/pkgs/build-support/rust/build-rust-crate/lib.sh @@ -114,6 +114,12 @@ setup_link_paths() { tr '\n' ' ' < target/link > target/link_ LINK=$(cat target/link_) fi + + # Add "rustc-cdylib-link-arg" as linker arguments + # https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-cdylib-link-arg + if [[ -n "$CRATE_TYPE_IS_CDYLIB" ]]; then + EXTRA_BUILD+=" $EXTRA_CDYLIB_LINK_ARGS" + fi } search_for_bin_path() { 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 d020031a92f93..dd135af919654 100644 --- a/pkgs/build-support/rust/build-rust-crate/test/default.nix +++ b/pkgs/build-support/rust/build-rust-crate/test/default.nix @@ -8,6 +8,7 @@ , stdenv , symlinkJoin , writeTextFile +, pkgsCross }: let @@ -120,7 +121,10 @@ let `name` is used as part of the derivation name that performs the checking. - `crateArgs` is passed to `mkHostCrate` to build the crate with `buildRustCrate`. + `mkCrate` can be used to override the `mkCrate` call/implementation to use to + override the `buildRustCrate`, useful for cross compilation. Uses `mkHostCrate` by default. + + `crateArgs` is passed to `mkCrate` to build the crate with `buildRustCrate` `expectedFiles` contains a list of expected file paths in the output. E.g. `[ "./bin/my_binary" ]`. @@ -129,13 +133,13 @@ let output is used but e.g. `output = "lib";` will cause the lib output to be checked instead. You do not need to specify any directories. */ - assertOutputs = { name, crateArgs, expectedFiles, output? null }: + assertOutputs = { name, mkCrate ? mkHostCrate, crateArgs, expectedFiles, output? null, }: assert (builtins.isString name); assert (builtins.isAttrs crateArgs); assert (builtins.isList expectedFiles); let - crate = mkHostCrate (builtins.removeAttrs crateArgs ["expectedTestOutput"]); + crate = mkCrate (builtins.removeAttrs crateArgs ["expectedTestOutput"]); crateOutput = if output == null then crate else crate."${output}"; expectedFilesFile = writeTextFile { name = "expected-files-${name}"; @@ -155,7 +159,7 @@ let '' # sed out the hash because it differs per platform + '' - | sed -E -e 's/-[0-9a-fA-F]{10}\.rlib/-HASH.rlib/g' \ + | sed 's/-${crate.metadata}//g' \ > "$actualFiles" diff -q ${expectedFilesFile} "$actualFiles" > /dev/null || { echo -e "\033[0;1;31mERROR: Difference in expected output files in ${crateOutput} \033[0m" >&2 @@ -651,7 +655,7 @@ let }; expectedFiles = [ "./nix-support/propagated-build-inputs" - "./lib/libtest_lib-HASH.rlib" + "./lib/libtest_lib.rlib" "./lib/link" ]; }; @@ -668,7 +672,24 @@ let }; expectedFiles = [ "./nix-support/propagated-build-inputs" - "./lib/libtest_lib-HASH.rlib" + "./lib/libtest_lib.rlib" + "./lib/link" + ]; + }; + + crateLibOutputsWasm32 = assertOutputs { + name = "wasm32-crate-lib"; + output = "lib"; + mkCrate = mkCrate pkgsCross.wasm32-unknown-none.buildRustCrate; + crateArgs = { + libName = "test_lib"; + type = [ "cdylib" ]; + libPath = "src/lib.rs"; + src = mkLib "src/lib.rs"; + }; + expectedFiles = [ + "./nix-support/propagated-build-inputs" + "./lib/test_lib.wasm" "./lib/link" ]; }; diff --git a/pkgs/build-support/rust/hooks/maturin-build-hook.sh b/pkgs/build-support/rust/hooks/maturin-build-hook.sh index b3cc1ced79647..c1e701425f00d 100644 --- a/pkgs/build-support/rust/hooks/maturin-build-hook.sh +++ b/pkgs/build-support/rust/hooks/maturin-build-hook.sh @@ -3,6 +3,9 @@ maturinBuildHook() { runHook preBuild + # Put the wheel to dist/ so that regular Python tooling can find it. + local dist="$PWD/dist" + if [ ! -z "${buildAndTestSubdir-}" ]; then pushd "${buildAndTestSubdir}" fi @@ -16,6 +19,7 @@ maturinBuildHook() { --manylinux off \ --strip \ --release \ + --out "$dist" \ ${maturinBuildFlags-} ) @@ -23,10 +27,6 @@ maturinBuildHook() { popd fi - # Move the wheel to dist/ so that regular Python tooling can find it. - mkdir -p dist - mv ${cargoRoot:+$cargoRoot/}target/wheels/*.whl dist/ - # These are python build hooks and may depend on ./dist runHook postBuild |