Fix copying cargo artifacts from deps

* Previously the CARGO_TARGET_DIR environment was set to the `out`
  directory which resulted in cargo placing all of its artifacts there
  instead of the default `target` directory
* Later on, the build scripts would then copy the (empty) `target`
  directory to `$out` resulting in cargo rebuilding the entire
  dependency tree from scratch whenever the top level crate's source was
  changed
* Now we omit the CARGO_TARGET_DIR environment variable and inspect the
  `target` directory for any binaries instead of the `out` directory
This commit is contained in:
Ivan Petkov 2021-11-11 15:09:17 -08:00 committed by Julian Stecklina
parent 5378c7de4d
commit 93097326ee
2 changed files with 49 additions and 3 deletions

View file

@ -240,7 +240,6 @@ let
# threads as there are cores. This is often too much parallelism so we
# reduce it to $NIX_BUILD_CORES if not specified by the caller.
export RUST_TEST_THREADS="''${RUST_TEST_THREADS:-$NIX_BUILD_CORES}"
export CARGO_TARGET_DIR="out"
log "cargo_version (read): $cargo_version"
log "cargo_message_format (set): $cargo_message_format"
@ -369,7 +368,7 @@ let
done < <(jq -cMr "$cargo_bins_jq_filter" <"$cargo_build_output_json")
else
log "$cargo_build_output_json: file wasn't written, using less reliable copying method"
find out -type f -executable \
find target -type f -executable \
-not -name '*.so' -a -not -name '*.dylib' \
-exec cp {} $out/bin \;
fi
@ -390,7 +389,7 @@ let
done < <(jq -cMr "$cargo_libs_jq_filter" <"$cargo_build_output_json")
else
log "$cargo_build_output_json: file wasn't written, using less reliable copying method"
find out -type f \
find target -type f \
-name '*.so' -or -name '*.dylib' -or -name '*.a' \
-exec cp {} $out/lib \;
fi

View file

@ -97,11 +97,58 @@ let
touch $out
'';
# Tests that the builtDependencies derivation can successfully be unpacked
# and that it actually contains cargo's output artifacts. If the result is
# ever empty, cargo will still succeed in building the top level crate, except
# it will need to rebuild all dependencies from scratch, which is wasteful.
# See https://github.com/nix-community/naersk/issues/202
depsTargetNotEmpty = pkgs.runCommand "depsTargetNotEmpty"
{ inherit (simple-dep) builtDependencies; }
''
for dep in $builtDependencies; do
# Make destination directory for unarchiving
mkdir dst
${pkgs.zstd}/bin/zstd -d "$dep/target.tar.zst" --stdout | tar -x -C ./dst
if [ -z "$(ls -A ./dst)" ]; then
echo target directory is empty: "$dep"
return 1
fi
rm -rf ./dst
done
# Success
touch $out
'';
# Same as the test above except checks when the builtDependencies
# derivation is not compressed.
depsUncompressedTargetNotEmpty = pkgs.runCommand "depsUncompressedTargetNotEmpty"
{ inherit (simple-dep-no-compress) builtDependencies; }
''
for dep in $builtDependencies; do
if [ -z "$(ls -A "$dep"/target)" ]; then
echo target directory is empty: "$dep"
return 1
fi
done
# Success
touch $out
'';
simple-dep = naersk.buildPackage {
src = ./test/simple-dep;
doCheck = true;
};
simple-dep-no-compress = naersk.buildPackage {
src = ./test/simple-dep;
doCheck = true;
compressTarget = false;
};
simple-dep-doc = naersk.buildPackage
{
src = ./test/simple-dep;