Merge pull request #113193 from danieldk/cargo-install-hook

This commit is contained in:
Jörg Thalheim 2021-02-18 00:02:03 +00:00 committed by GitHub
commit 236b56c94d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 148 additions and 78 deletions

View file

@ -196,7 +196,7 @@ sometimes it may be necessary to disable this so the tests run consecutively.
```nix
rustPlatform.buildRustPackage {
/* ... */
cargoParallelTestThreads = false;
dontUseCargoParallelTests = true;
}
```
@ -293,6 +293,12 @@ attributes can also be used:
variable `buildAndTestSubdir` can be used to build a crate in a
Cargo workspace. Additional maturin flags can be passed through
`maturinBuildFlags`.
* `cargoCheckHook`: run tests using Cargo. Additional flags can be
passed to Cargo using `checkFlags` and `checkFlagsArray`. By
default, tests are run in parallel. This can be disabled by setting
`dontUseCargoParallelTests`.
* `cargoInstallHook`: install binaries and static/shared libraries
that were built using `cargoBuildHook`.
### Examples

View file

@ -39,7 +39,7 @@ rustPlatform.buildRustPackage rec {
postInstall = "make PREFIX=$out copy-data";
# Sometimes tests fail when run in parallel
cargoParallelTestThreads = false;
dontUseCargoParallelThreads = true;
meta = with lib; {
description = "A graphical client for plain-text protocols written in Rust with GTK. It currently supports the Gemini, Gopher and Finger protocols";

View file

@ -2,8 +2,9 @@
, lib
, buildPackages
, cacert
, cargo
, cargoBuildHook
, cargoCheckHook
, cargoInstallHook
, cargoSetupHook
, fetchCargoTarball
, runCommandNoCC
@ -35,13 +36,11 @@
, nativeBuildInputs ? []
, cargoUpdateHook ? ""
, cargoDepsHook ? ""
, cargoBuildFlags ? []
, buildType ? "release"
, meta ? {}
, cargoVendorDir ? null
, checkType ? buildType
, depsExtraArgs ? {}
, cargoParallelTestThreads ? true
# Toggles whether a custom sysroot is created when the target is a .json file.
, __internal_dontAddSysroot ? false
@ -87,9 +86,6 @@ let
originalCargoToml = src + /Cargo.toml; # profile info is later extracted
};
releaseDir = "target/${shortTarget}/${buildType}";
tmpDir = "${releaseDir}-tmp";
in
# Tests don't currently work for `no_std`, and all custom sysroots are currently built without `std`.
@ -99,16 +95,21 @@ assert useSysroot -> !(args.doCheck or true);
stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs useSysroot {
RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or "");
} // {
inherit buildAndTestSubdir cargoDeps releaseDir tmpDir;
inherit buildAndTestSubdir cargoDeps;
cargoBuildFlags = lib.concatStringsSep " " cargoBuildFlags;
cargoBuildType = "--${buildType}";
cargoBuildType = buildType;
patchRegistryDeps = ./patch-registry-deps;
nativeBuildInputs = nativeBuildInputs ++
[ cacert git cargo cargoBuildHook cargoSetupHook rustc ];
nativeBuildInputs = nativeBuildInputs ++ [
cacert
git
cargoBuildHook
cargoCheckHook
cargoInstallHook
cargoSetupHook
rustc
];
buildInputs = buildInputs ++ lib.optional stdenv.hostPlatform.isMinGW windows.pthreads;
@ -128,52 +129,10 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs u
runHook postConfigure
'';
checkPhase = args.checkPhase or (let
argstr = "${lib.optionalString (checkType == "release") "--release"} --target ${target} --frozen";
threads = if cargoParallelTestThreads then "$NIX_BUILD_CORES" else "1";
in ''
${lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"}
runHook preCheck
echo "Running cargo test ${argstr} -- ''${checkFlags} ''${checkFlagsArray+''${checkFlagsArray[@]}}"
cargo test -j $NIX_BUILD_CORES ${argstr} -- --test-threads=${threads} ''${checkFlags} ''${checkFlagsArray+"''${checkFlagsArray[@]}"}
runHook postCheck
${lib.optionalString (buildAndTestSubdir != null) "popd"}
'');
doCheck = args.doCheck or true;
strictDeps = true;
installPhase = args.installPhase or ''
runHook preInstall
# 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.
mkdir -p $tmpDir
cp -r $releaseDir/* $tmpDir/
bins=$(find $tmpDir \
-maxdepth 1 \
-type f \
-executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \))
# rename the output dir to a architecture independent one
mapfile -t targets < <(find "$NIX_BUILD_TOP" -type d | grep '${tmpDir}$')
for target in "''${targets[@]}"; do
rm -rf "$target/../../${buildType}"
ln -srf "$target" "$target/../../"
done
mkdir -p $out/bin $out/lib
xargs -r cp -t $out/bin <<< $bins
find $tmpDir \
-maxdepth 1 \
-regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \
-print0 | xargs -r -0 cp -t $out/lib
rmdir --ignore-fail-on-non-empty $out/lib $out/bin
runHook postInstall
'';
passthru = { inherit cargoDeps; } // (args.passthru or {});
meta = {

View file

@ -1,3 +1,5 @@
declare -a cargoBuildFlags
cargoBuildHook() {
echo "Executing cargoBuildHook"
@ -17,16 +19,16 @@ cargoBuildHook() {
cargo build -j $NIX_BUILD_CORES \
--target @rustTargetPlatformSpec@ \
--frozen \
${cargoBuildType} \
--${cargoBuildType} \
${cargoBuildFlags}
)
runHook postBuild
if [ ! -z "${buildAndTestSubdir-}" ]; then
popd
fi
runHook postBuild
echo "Finished cargoBuildHook"
}

View file

@ -0,0 +1,41 @@
declare -a checkFlags
cargoCheckHook() {
echo "Executing cargoCheckHook"
runHook preCheck
if [[ -n "${buildAndTestSubdir-}" ]]; then
pushd "${buildAndTestSubdir}"
fi
if [[ -z ${dontUseCargoParallelTests-} ]]; then
threads=$NIX_BUILD_CORES
else
threads=1
fi
argstr="--${cargoBuildType} --target @rustTargetPlatformSpec@ --frozen";
(
set -x
cargo test \
-j $NIX_BUILD_CORES \
${argstr} -- \
--test-threads=${threads} \
${checkFlags} \
${checkFlagsArray+"${checkFlagsArray[@]}"}
)
if [[ -n "${buildAndTestSubdir-}" ]]; then
popd
fi
echo "Finished cargoCheckHook"
runHook postCheck
}
if [ -z "${checkPhase-}" ]; then
checkPhase=cargoCheckHook
fi

View file

@ -0,0 +1,49 @@
cargoInstallPostBuildHook() {
echo "Executing cargoInstallPostBuildHook"
releaseDir=target/@shortTarget@/$cargoBuildType
tmpDir="${releaseDir}-tmp";
mkdir -p $tmpDir
cp -r ${releaseDir}/* $tmpDir/
bins=$(find $tmpDir \
-maxdepth 1 \
-type f \
-executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \))
echo "Finished cargoInstallPostBuildHook"
}
cargoInstallHook() {
echo "Executing cargoInstallHook"
runHook preInstall
# rename the output dir to a architecture independent one
releaseDir=target/@shortTarget@/$cargoBuildType
tmpDir="${releaseDir}-tmp";
mapfile -t targets < <(find "$NIX_BUILD_TOP" -type d | grep "${tmpDir}$")
for target in "${targets[@]}"; do
rm -rf "$target/../../${cargoBuildType}"
ln -srf "$target" "$target/../../"
done
mkdir -p $out/bin $out/lib
xargs -r cp -t $out/bin <<< $bins
find $tmpDir \
-maxdepth 1 \
-regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \
-print0 | xargs -r -0 cp -t $out/lib
rmdir --ignore-fail-on-non-empty $out/lib $out/bin
runHook postInstall
echo "Finished cargoInstallHook"
}
if [ -z "${installPhase-}" ]; then
installPhase=cargoInstallHook
postBuildHooks+=(cargoInstallPostBuildHook)
fi

View file

@ -36,6 +36,24 @@ in {
};
} ./cargo-build-hook.sh) {};
cargoCheckHook = callPackage ({ }:
makeSetupHook {
name = "cargo-check-hook.sh";
deps = [ cargo ];
substitutions = {
inherit rustTargetPlatformSpec;
};
} ./cargo-check-hook.sh) {};
cargoInstallHook = callPackage ({ }:
makeSetupHook {
name = "cargo-install-hook.sh";
deps = [ ];
substitutions = {
inherit shortTarget;
};
} ./cargo-install-hook.sh) {};
cargoSetupHook = callPackage ({ }:
makeSetupHook {
name = "cargo-setup-hook.sh";

View file

@ -12,7 +12,8 @@ rec {
};
buildRustPackage = callPackage ../../../build-support/rust {
inherit rustc cargo cargoBuildHook cargoSetupHook fetchCargoTarball;
inherit cargoBuildHook cargoCheckHook cargoInstallHook cargoSetupHook
fetchCargoTarball rustc;
};
rustcSrc = callPackage ./rust-src.nix {
@ -26,5 +27,5 @@ rec {
# Hooks
inherit (callPackage ../../../build-support/rust/hooks {
inherit cargo;
}) cargoBuildHook cargoSetupHook maturinBuildHook;
}) cargoBuildHook cargoCheckHook cargoInstallHook cargoSetupHook maturinBuildHook;
}

View file

@ -2,7 +2,7 @@
, openssh, openssl, pkg-config, cmake, zlib, curl, libiconv
, CoreFoundation, Security }:
rustPlatform.buildRustPackage {
rustPlatform.buildRustPackage rec {
pname = "rls";
inherit (rustPlatform.rust.rustc) src version;
@ -14,7 +14,7 @@ rustPlatform.buildRustPackage {
preBuild = ''
# client tests are flaky
rm tests/client.rs
rm ${buildAndTestSubdir}/tests/client.rs
'';
# a nightly compiler is required unless we use this cheat code.

View file

@ -26,7 +26,7 @@ rustPlatform.buildRustPackage rec {
# using the [makefile](https://github.com/wasmerio/wasmer/blob/master/Makefile).
# Enabling cranelift as this used to be the old default. At least one backend is
# needed for the run subcommand to work.
cargoBuildFlags = [ "--features 'backend-cranelift'" ];
cargoBuildFlags = [ "--features" "backend-cranelift" ];
LIBCLANG_PATH = "${llvmPackages.libclang}/lib";

View file

@ -9,11 +9,9 @@ assert lib.assertMsg (sqliteSupport == true || postgresqlSupport == true || mysq
let
inherit (lib) optional optionals optionalString;
features = ''
${optionalString sqliteSupport "sqlite"} \
${optionalString postgresqlSupport "postgres"} \
${optionalString mysqlSupport "mysql"} \
'';
features = optional sqliteSupport "sqlite"
++ optional postgresqlSupport "postgres"
++ optional mysqlSupport "mysql";
in
rustPlatform.buildRustPackage rec {
@ -35,11 +33,12 @@ rustPlatform.buildRustPackage rec {
./allow-warnings.patch
];
cargoBuildFlags = [ "--no-default-features --features \"${features}\"" ];
cargoBuildFlags = [ "--no-default-features" "--features" "${lib.concatStringsSep "," features}" ];
cargoPatches = [ ./cargo-lock.patch ];
cargoSha256 = "1vbb7r0dpmq8363i040bkhf279pz51c59kcq9v5qr34hs49ish8g";
nativeBuildInputs = [ pkg-config ];
buildInputs = [ openssl ]
++ optional stdenv.isDarwin Security
++ optional (stdenv.isDarwin && mysqlSupport) libiconv
@ -47,12 +46,7 @@ rustPlatform.buildRustPackage rec {
++ optional postgresqlSupport postgresql
++ optionals mysqlSupport [ mysql zlib ];
# We must `cd diesel_cli`, we cannot use `--package diesel_cli` to build
# because --features fails to apply to the package:
# https://github.com/rust-lang/cargo/issues/5015
# https://github.com/rust-lang/cargo/issues/4753
preBuild = "cd diesel_cli";
postBuild = "cd ..";
buildAndTestSubdir = "diesel_cli";
checkPhase = optionalString sqliteSupport ''
(cd diesel_cli && cargo check --features sqlite)
@ -65,7 +59,7 @@ rustPlatform.buildRustPackage rec {
# Fix the build with mariadb, which otherwise shows "error adding symbols:
# DSO missing from command line" errors for libz and libssl.
NIX_LDFLAGS = lib.optionalString mysqlSupport "-lz -lssl -lcrypto";
NIX_LDFLAGS = optionalString mysqlSupport "-lz -lssl -lcrypto";
meta = with lib; {
description = "Database tool for working with Rust projects that use Diesel";

View file

@ -17,7 +17,7 @@ rustPlatform.buildRustPackage rec {
cargoSha256 = "sha256-jTZso61Lyt6jprBxBAhvchgOsgM9y1qBleTxUx1jCnE=";
checkFlagsArray = lib.optionals stdenv.isDarwin [ "--skip=copy" ];
cargoParallelTestThreads = false;
dontUseCargoParallelTests = true;
postInstall = ''
$out/bin/the-way config default tmp.toml