From a8efb2053fd9c1e2fea97699754b5071e94c1649 Mon Sep 17 00:00:00 2001 From: Daniƫl de Kok Date: Thu, 11 Feb 2021 17:32:47 +0100 Subject: 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. --- pkgs/build-support/rust/default.nix | 61 ++++++++--------------- pkgs/build-support/rust/hooks/cargo-build-hook.sh | 33 ++++++++++++ pkgs/build-support/rust/hooks/default.nix | 20 +++++++- 3 files changed, 71 insertions(+), 43 deletions(-) create mode 100644 pkgs/build-support/rust/hooks/cargo-build-hook.sh (limited to 'pkgs/build-support/rust') diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index 6741b329a30..19ec71261be 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -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 diff --git a/pkgs/build-support/rust/hooks/cargo-build-hook.sh b/pkgs/build-support/rust/hooks/cargo-build-hook.sh new file mode 100644 index 00000000000..55585233413 --- /dev/null +++ b/pkgs/build-support/rust/hooks/cargo-build-hook.sh @@ -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 diff --git a/pkgs/build-support/rust/hooks/default.nix b/pkgs/build-support/rust/hooks/default.nix index dea749f9393..e33d5813a13 100644 --- a/pkgs/build-support/rust/hooks/default.nix +++ b/pkgs/build-support/rust/hooks/default.nix @@ -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"; -- cgit 1.4.1