nixpkgs-suyu/pkgs/build-support/rust/hooks/cargo-setup-hook.sh
Ivar Scholten 987d32bbac buildRustPackage: dont rely on NIX_BUILD_TOP in cargoSetupPostPatchHook
This breaks the builder when a nix-shell or keepBuildTree is used. The
issue occurs because paths to cargo lockfiles are read with NIX_BUILD_TOP,
which is not reliable.

This breaks a nix-shell because NIX_BUILD_TOP simply is not set, causing
an invalid path to be used. This can be worked around using
NIX_BUILD_TOP=$PWD, but that obviously is not great.

This breaks keepBuildTree because it changes the working directory to a
different path than NIX_BUILD_TOP. Since the lockfiles are copied based
on the working directory, but read based on NIX_BUILD_TOP, this causes
the hook to not be able to find them.

This was solved by both reading these files based on the working directory,
using absolute paths to avoid having to traverse back in the directory tree.

Fixes: #138554
2022-09-25 16:17:36 +02:00

86 lines
2.7 KiB
Bash

cargoSetupPostUnpackHook() {
echo "Executing cargoSetupPostUnpackHook"
# Some cargo builds include build hooks that modify their own vendor
# dependencies. This copies the vendor directory into the build tree and makes
# it writable. If we're using a tarball, the unpackFile hook already handles
# this for us automatically.
if [ -z $cargoVendorDir ]; then
unpackFile "$cargoDeps"
export cargoDepsCopy="$(realpath "$(stripHash $cargoDeps)")"
else
cargoDepsCopy="$(realpath "$(pwd)/$sourceRoot/${cargoRoot:+$cargoRoot/}${cargoVendorDir}")"
fi
if [ ! -d .cargo ]; then
mkdir .cargo
fi
config="$cargoDepsCopy/.cargo/config";
if [[ ! -e $config ]]; then
config=@defaultConfig@
fi;
tmp_config=$(mktemp)
substitute $config $tmp_config \
--subst-var-by vendor "$cargoDepsCopy"
cat ${tmp_config} >> .cargo/config
cat >> .cargo/config <<'EOF'
@rustTarget@
EOF
echo "Finished cargoSetupPostUnpackHook"
}
# After unpacking and applying patches, check that the Cargo.lock matches our
# src package. Note that we do this after the patchPhase, because the
# patchPhase may create the Cargo.lock if upstream has not shipped one.
cargoSetupPostPatchHook() {
echo "Executing cargoSetupPostPatchHook"
cargoDepsLockfile="$cargoDepsCopy/Cargo.lock"
srcLockfile="$(pwd)/${cargoRoot:+$cargoRoot/}Cargo.lock"
echo "Validating consistency between $srcLockfile and $cargoDepsLockfile"
if ! @diff@ $srcLockfile $cargoDepsLockfile; then
# If the diff failed, first double-check that the file exists, so we can
# 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
if ! [ -e $cargoDepsLockfile ]; then
echo "ERROR: Missing lockfile from cargo vendor. Expected to find it at: $cargoDepsLockfile"
exit 1
fi
echo
echo "ERROR: cargoSha256 is out of date"
echo
echo "Cargo.lock is not the same in $cargoDepsCopy"
echo
echo "To fix the issue:"
echo '1. Use "0000000000000000000000000000000000000000000000000000" as the cargoSha256 value'
echo "2. Build the derivation and wait for it to fail with a hash mismatch"
echo "3. Copy the 'got: sha256:' value back into the cargoSha256 field"
echo
exit 1
fi
unset cargoDepsCopy
echo "Finished cargoSetupPostPatchHook"
}
if [ -z "${dontCargoSetupPostUnpack-}" ]; then
postUnpackHooks+=(cargoSetupPostUnpackHook)
fi
if [ -z ${cargoVendorDir-} ]; then
postPatchHooks+=(cargoSetupPostPatchHook)
fi