about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support/rust/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/build-support/rust/default.nix')
-rw-r--r--nixpkgs/pkgs/build-support/rust/default.nix54
1 files changed, 37 insertions, 17 deletions
diff --git a/nixpkgs/pkgs/build-support/rust/default.nix b/nixpkgs/pkgs/build-support/rust/default.nix
index 6f399beab23b..17ab24bc6a21 100644
--- a/nixpkgs/pkgs/build-support/rust/default.nix
+++ b/nixpkgs/pkgs/build-support/rust/default.nix
@@ -30,6 +30,13 @@ let
     , meta ? {}
     , target ? null
     , cargoVendorDir ? null
+    , checkType ? buildType
+
+    # Needed to `pushd`/`popd` into a subdir of a tarball if this subdir
+    # contains a Cargo.toml, but isn't part of a workspace (which is e.g. the
+    # case for `rustfmt`/etc from the `rust-sources).
+    # Otherwise, everything from the tarball would've been built/tested.
+    , buildAndTestSubdir ? null
     , ... } @ args:
 
     assert cargoVendorDir == null -> cargoSha256 != "unset";
@@ -72,7 +79,8 @@ let
 
       # Specify the stdenv's `diff` by abspath to ensure that the user's build
       # inputs do not cause us to find the wrong `diff`.
-      diff = "${diffutils}/bin/diff";
+      # The `.nativeDrv` stanza works like nativeBuildInputs and ensures cross-compiling has the right version available.
+      diff = "${diffutils.nativeDrv or diffutils}/bin/diff";
 
     in
 
@@ -132,6 +140,7 @@ let
           # give a friendlier error msg.
           if ! [ -e $srcLockfile ]; then
             echo "ERROR: Missing Cargo.lock from src. Expected to find it at: $srcLockfile"
+            echo "Hint: You can use the cargoPatches attribute to add a Cargo.lock manually to the build."
             exit 1
           fi
 
@@ -163,6 +172,7 @@ let
       '';
 
       buildPhase = with builtins; args.buildPhase or ''
+        ${stdenv.lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"}
         runHook preBuild
 
         (
@@ -178,22 +188,29 @@ let
             --frozen ${concatStringsSep " " cargoBuildFlags}
         )
 
-        # rename the output dir to a architecture independent one
-        mapfile -t targets < <(find "$NIX_BUILD_TOP" -type d | grep '${releaseDir}$')
-        for target in "''${targets[@]}"; do
-          rm -rf "$target/../../${buildType}"
-          ln -srf "$target" "$target/../../"
-        done
-
         runHook postBuild
+
+        ${stdenv.lib.optionalString (buildAndTestSubdir != null) "popd"}
+
+        # This needs to be done after postBuild: packages like `cargo` do a pushd/popd in
+        # the pre/postBuild-hooks that need to be taken into account before gathering
+        # all binaries to install.
+        bins=$(find $releaseDir \
+          -maxdepth 1 \
+          -type f \
+          -executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \))
       '';
 
-      checkPhase = args.checkPhase or ''
+      checkPhase = args.checkPhase or (let
+        argstr = "${stdenv.lib.optionalString (checkType == "release") "--release"} --target ${rustTarget} --frozen";
+      in ''
+        ${stdenv.lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"}
         runHook preCheck
-        echo "Running cargo cargo test -- ''${checkFlags} ''${checkFlagsArray+''${checkFlagsArray[@]}}"
-        cargo test -- ''${checkFlags} ''${checkFlagsArray+"''${checkFlagsArray[@]}"}
+        echo "Running cargo test ${argstr} -- ''${checkFlags} ''${checkFlagsArray+''${checkFlagsArray[@]}}"
+        cargo test ${argstr} -- ''${checkFlags} ''${checkFlagsArray+"''${checkFlagsArray[@]}"}
         runHook postCheck
-      '';
+        ${stdenv.lib.optionalString (buildAndTestSubdir != null) "popd"}
+      '');
 
       doCheck = args.doCheck or true;
 
@@ -203,13 +220,16 @@ let
 
       installPhase = args.installPhase or ''
         runHook preInstall
+
+        # rename the output dir to a architecture independent one
+        mapfile -t targets < <(find "$NIX_BUILD_TOP" -type d | grep '${releaseDir}$')
+        for target in "''${targets[@]}"; do
+          rm -rf "$target/../../${buildType}"
+          ln -srf "$target" "$target/../../"
+        done
         mkdir -p $out/bin $out/lib
 
-        find $releaseDir \
-          -maxdepth 1 \
-          -type f \
-          -executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \) \
-          -print0 | xargs -r -0 cp -t $out/bin
+        xargs -r cp -t $out/bin <<< $bins
         find $releaseDir \
           -maxdepth 1 \
           -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \