buildRustPackage: factor out build phase to cargoBuildHook

- API change: remove the `target` argument of `buildRustPackage`, the
  target should always be in sync with the C/C++ compiler that is used.

- Gathering of binaries has moved from `buildPhase` to `installPhase`,
  this simplifies the hook and orders this functionality logically
  with the installation logic.
This commit is contained in:
Daniël de Kok 2021-02-11 17:32:47 +01:00
parent 198dd77635
commit a8efb2053f
4 changed files with 75 additions and 45 deletions

View File

@ -3,6 +3,7 @@
, buildPackages
, cacert
, cargo
, cargoBuildHook
, cargoSetupHook
, fetchCargoTarball
, runCommandNoCC
@ -37,7 +38,6 @@
, cargoBuildFlags ? []
, buildType ? "release"
, meta ? {}
, target ? rust.toRustTargetSpec stdenv.hostPlatform
, cargoVendorDir ? null
, checkType ? buildType
, depsExtraArgs ? {}
@ -71,6 +71,7 @@ let
# against the src fixed-output derivation to check consistency.
validateCargoDeps = !(cargoHash == "" && cargoSha256 == "");
target = rust.toRustTargetSpec stdenv.hostPlatform;
targetIsJSON = lib.hasSuffix ".json" target;
useSysroot = targetIsJSON && !__internal_dontAddSysroot;
@ -86,10 +87,6 @@ let
originalCargoToml = src + /Cargo.toml; # profile info is later extracted
};
ccForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
cxxForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++";
ccForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
cxxForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
releaseDir = "target/${shortTarget}/${buildType}";
tmpDir = "${releaseDir}-tmp";
@ -102,11 +99,17 @@ assert useSysroot -> !(args.doCheck or true);
stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs useSysroot {
RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or "");
} // {
inherit cargoDeps;
inherit buildAndTestSubdir cargoDeps releaseDir tmpDir;
cargoBuildFlags = lib.concatStringsSep " " cargoBuildFlags;
cargoBuildType = "--${buildType}";
patchRegistryDeps = ./patch-registry-deps;
nativeBuildInputs = nativeBuildInputs ++ [ cacert git cargo cargoSetupHook rustc ];
nativeBuildInputs = nativeBuildInputs ++
[ cacert git cargo cargoBuildHook cargoSetupHook rustc ];
buildInputs = buildInputs ++ lib.optional stdenv.hostPlatform.isMinGW windows.pthreads;
patches = cargoPatches ++ patches;
@ -125,38 +128,6 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs u
runHook postConfigure
'';
buildPhase = with builtins; args.buildPhase or ''
${lib.optionalString (buildAndTestSubdir != null) "pushd ${buildAndTestSubdir}"}
runHook preBuild
(
set -x
env \
"CC_${rust.toRustTarget stdenv.buildPlatform}"="${ccForBuild}" \
"CXX_${rust.toRustTarget stdenv.buildPlatform}"="${cxxForBuild}" \
"CC_${rust.toRustTarget stdenv.hostPlatform}"="${ccForHost}" \
"CXX_${rust.toRustTarget stdenv.hostPlatform}"="${cxxForHost}" \
cargo build -j $NIX_BUILD_CORES \
${lib.optionalString (buildType == "release") "--release"} \
--target ${target} \
--frozen ${concatStringsSep " " cargoBuildFlags}
)
runHook postBuild
${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.
mkdir -p $tmpDir
cp -r $releaseDir/* $tmpDir/
bins=$(find $tmpDir \
-maxdepth 1 \
-type f \
-executable ! \( -regex ".*\.\(so.[0-9.]+\|so\|a\|dylib\)" \))
'';
checkPhase = args.checkPhase or (let
argstr = "${lib.optionalString (checkType == "release") "--release"} --target ${target} --frozen";
threads = if cargoParallelTestThreads then "$NIX_BUILD_CORES" else "1";
@ -173,11 +144,19 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs u
strictDeps = true;
inherit releaseDir tmpDir;
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

View File

@ -0,0 +1,33 @@
cargoBuildHook() {
echo "Executing cargoBuildHook"
runHook preBuild
if [ ! -z "${buildAndTestSubdir-}" ]; then
pushd "${buildAndTestSubdir}"
fi
(
set -x
env \
"CC_@rustBuildPlatform@=@ccForBuild@" \
"CXX_@rustBuildPlatform@=@cxxForBuild@" \
"CC_@rustTargetPlatform@=@ccForHost@" \
"CXX_@rustTargetPlatform@=@cxxForHost@" \
cargo build -j $NIX_BUILD_CORES \
--target @rustTargetPlatformSpec@ \
--frozen \
${cargoBuildType} \
${cargoBuildFlags}
)
runHook postBuild
if [ ! -z "${buildAndTestSubdir-}" ]; then
popd
fi
echo "Finished cargoBuildHook"
}
buildPhase=cargoBuildHook

View File

@ -1,5 +1,6 @@
{ buildPackages
, callPackage
, cargo
, diffutils
, lib
, makeSetupHook
@ -16,9 +17,24 @@ let
shortTarget = if targetIsJSON then
(lib.removeSuffix ".json" (builtins.baseNameOf "${target}"))
else target;
ccForBuild="${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
ccForHost="${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
ccForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}cc";
cxxForBuild = "${buildPackages.stdenv.cc}/bin/${buildPackages.stdenv.cc.targetPrefix}c++";
ccForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
cxxForHost = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}c++";
rustBuildPlatform = rust.toRustTarget stdenv.buildPlatform;
rustTargetPlatform = rust.toRustTarget stdenv.hostPlatform;
rustTargetPlatformSpec = rust.toRustTargetSpec stdenv.hostPlatform;
in {
cargoBuildHook = callPackage ({ }:
makeSetupHook {
name = "cargo-build-hook.sh";
deps = [ cargo ];
substitutions = {
inherit ccForBuild ccForHost cxxForBuild cxxForHost
rustBuildPlatform rustTargetPlatform rustTargetPlatformSpec;
};
} ./cargo-build-hook.sh) {};
cargoSetupHook = callPackage ({ }:
makeSetupHook {
name = "cargo-setup-hook.sh";

View File

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