From f7745fd1c0e64da819e5d24c504f6746af7a84ab Mon Sep 17 00:00:00 2001 From: Kevin Cox Date: Fri, 25 Sep 2020 19:48:52 -0400 Subject: rustPlatform: Allow impure cache. I hope this isn't too controversial. Right now if you make any change to your rust source (including any non-source files) a subsequent Nix build will recompile all of your dependencies and do a full compile of your crate. This change allows using a directory of your choice to cache cargo's artifacts. This allows incremental rebuilds. The intent of this is that it can be used in CI, and possibly local development to reduce full rebuilds. This is especially useful if you depend on a large number of crates. This is not intended to be used for production releases and other cases where complete correctness is required. Concerns: - I think executables that have been removed from the source will be grabbed by the installPhase so might not be removed from the package output. --- pkgs/build-support/rust/default.nix | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pkgs/build-support/rust/default.nix b/pkgs/build-support/rust/default.nix index f6177ce198da..d85bfcaa370b 100644 --- a/pkgs/build-support/rust/default.nix +++ b/pkgs/build-support/rust/default.nix @@ -32,6 +32,11 @@ , depsExtraArgs ? {} , cargoParallelTestThreads ? true +# If set the CARGO_TARGET_DIR will be set to this directory. This will allow +# you to avoid rebuilding dependencies. +# This setting is *incompatible* with sandboxing. +, impureCacheDir ? null + # Needed to `pushd`/`popd` into a subdir of a tarball if this subdir # contains a Cargo.toml, but isn't part of a workspace (which is e.g. the # case for `rustfmt`/etc from the `rust-sources). @@ -75,8 +80,17 @@ let 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/${rustTarget}/${buildType}"; - tmpDir = "${releaseDir}-tmp"; + + releaseDirPrefix = if impureCacheDir == null + then "target" + else + assert + stdenv.lib.assertMsg (stdenv.lib.hasPrefix "/" impureCacheDir) + "impureCacheDir must be an absolute path."; + impureCacheDir; + + releaseDir = "${releaseDirPrefix}/${rustTarget}/${buildType}"; + tmpDir = "target/${rustTarget}/${buildType}-tmp"; # Specify the stdenv's `diff` by abspath to ensure that the user's build # inputs do not cause us to find the wrong `diff`. @@ -98,6 +112,8 @@ stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // { PKG_CONFIG_ALLOW_CROSS = if stdenv.buildPlatform != stdenv.hostPlatform then 1 else 0; + CARGO_TARGET_DIR = impureCacheDir; + postUnpack = '' eval "$cargoDepsHook" -- cgit v1.2.3