mirror of
https://github.com/ipetkov/crane.git
synced 2024-11-22 23:17:15 +03:00
Split out buildWithCargo into a lower level mkCargoDerivation
* The intention here is to split up different "responsibilities" into smaller parts which can be composed as a DAG rather than mutually recursive functions. Specifically: * `mkCargoDerivation` represents a lower-level thin wrapper around `stdenv.mkDerivation` which will - set up hooks - require the caller to define the variables needed by the hooks (like vendor dir, or artifacts to inherit) - ensure that build/check/install phases can be configured by the caller without having them remember to call pre/post hooks * This allows `buildDepsOnly` to only focus on setting some default values (like good default commands to build all artifacts, setting the derivation name, etc.) and delegating the rest to `mkCargoDerivation` * Lastly, the responsibility of `buildWithCargo` ends up ensuring that `cargoArtifacts` and `cargoVendorDir` are defined if the caller does not pass them in
This commit is contained in:
parent
10a60cc085
commit
4c1711399d
@ -1,36 +1,46 @@
|
||||
{ buildWithCargo
|
||||
, crateNameFromCargoToml
|
||||
{ crateNameFromCargoToml
|
||||
, mkCargoDerivation
|
||||
, mkDummySrc
|
||||
, vendorCargoDeps
|
||||
}:
|
||||
|
||||
args:
|
||||
{ cargoExtraArgs ? ""
|
||||
, cargoCheckCommand ? "cargo check --workspace --release"
|
||||
, cargoBuildCommand ? "cargo build --workspace --release"
|
||||
, cargoTestCommand ? "cargo test --workspace --release"
|
||||
, ...
|
||||
}@args:
|
||||
let
|
||||
crateName = crateNameFromCargoToml args;
|
||||
defaults = {
|
||||
inherit (crateName) version;
|
||||
pname = "${crateName.pname}-deps";
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
cargo check --workspace --release
|
||||
cargo build --workspace --release
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
# Don't install anything by default, but let the caller set their own if they wish
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out
|
||||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
|
||||
forced = {
|
||||
# Prevent infinite recursion, we are the root of all artifacts
|
||||
cargoArtifacts = null;
|
||||
# No point in building this if not for the cargo artifacts
|
||||
doCopyTargetToOutput = true;
|
||||
src = mkDummySrc args;
|
||||
};
|
||||
in
|
||||
buildWithCargo (defaults // args // forced)
|
||||
mkCargoDerivation (args // {
|
||||
src = mkDummySrc args;
|
||||
pname = args.pname or "${crateName.pname}-deps";
|
||||
version = args.version or crateName.version;
|
||||
|
||||
cargoArtifacts = null;
|
||||
|
||||
cargoVendorDir = args.cargoVendorDir or vendorCargoDeps {
|
||||
cargoLock = args.src + /Cargo.lock;
|
||||
};
|
||||
|
||||
# First we run `cargo check` to cache cargo's internal artifacts, fingerprints, etc. for all deps.
|
||||
# Then we run `cargo build` to actually compile the deps and cache the results
|
||||
buildPhaseCargoCommand = args.buildPhaseCargoCommand or ''
|
||||
${cargoCheckCommand} ${cargoExtraArgs}
|
||||
${cargoBuildCommand} ${cargoExtraArgs}
|
||||
'';
|
||||
|
||||
checkPhaseCargoCommand = args.checkPhaseCargoCommand or ''
|
||||
${cargoTestCommand} ${cargoExtraArgs}
|
||||
'';
|
||||
|
||||
# No point in building this if not for the cargo artifacts
|
||||
doCopyTargetToOutput = true;
|
||||
|
||||
# By default, don't install anything (else, besides the cargo target directory),
|
||||
# but let the caller set their own if they wish
|
||||
installPhaseCargoCommand = args.installPhaseCargoCommand or ''
|
||||
mkdir -p $out
|
||||
'';
|
||||
})
|
||||
|
@ -1,14 +1,7 @@
|
||||
{ buildDepsOnly
|
||||
, cargo
|
||||
, configureCargoCommonVarsHook
|
||||
, configureCargoVendoredDepsHook
|
||||
, copyCargoTargetToOutputHook
|
||||
, crateNameFromCargoToml
|
||||
, inheritCargoArtifactsHook
|
||||
, installFromCargoArtifactsHook
|
||||
, lib
|
||||
, remapSourcePathPrefixHook
|
||||
, stdenv
|
||||
, mkCargoDerivation
|
||||
, vendorCargoDeps
|
||||
}:
|
||||
let
|
||||
@ -60,47 +53,36 @@ in
|
||||
# access. Directory structure should basically follow the output of `cargo vendor`.
|
||||
# This can be inferred automatically if the `src` root has a Cargo.lock file.
|
||||
, cargoVendorDir ? vendorCargoDepsFromArgs args
|
||||
# Controls whether cargo's `target` directory should be copied as an output
|
||||
, doCopyTargetToOutput ? true
|
||||
# Controls instructing rustc to remap the path prefix of any sources it
|
||||
# captures (for example, this can include file names in panic info). This is
|
||||
# useful to omit any references to `/nix/store/...` from the final binary,
|
||||
# as including them will make Nix pull in all sources when installing any binaries.
|
||||
, doRemapSourcePathPrefix ? true
|
||||
, nativeBuildInputs ? [ ]
|
||||
, cargoBuildCommand ? "cargo build --workspace --release"
|
||||
, cargoTestCommand ? "cargo test --workspace --release"
|
||||
, cargoExtraArgs ? ""
|
||||
, ...
|
||||
}@args:
|
||||
let
|
||||
defaultValues = (crateNameFromCargoToml args) // {
|
||||
inherit
|
||||
cargoArtifacts
|
||||
cargoVendorDir
|
||||
doCopyTargetToOutput
|
||||
doRemapSourcePathPrefix;
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
cargo build --workspace --release
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
checkPhase = ''
|
||||
runHook preCheck
|
||||
cargo test --workspace --release
|
||||
runHook postCheck
|
||||
'';
|
||||
};
|
||||
|
||||
additions = {
|
||||
nativeBuildInputs = nativeBuildInputs ++ [
|
||||
cargo
|
||||
configureCargoCommonVarsHook
|
||||
configureCargoVendoredDepsHook
|
||||
copyCargoTargetToOutputHook
|
||||
inheritCargoArtifactsHook
|
||||
installFromCargoArtifactsHook
|
||||
remapSourcePathPrefixHook
|
||||
];
|
||||
};
|
||||
crateName = crateNameFromCargoToml args;
|
||||
in
|
||||
stdenv.mkDerivation (defaultValues // args // additions)
|
||||
mkCargoDerivation (args // {
|
||||
pname = args.pname or crateName.pname;
|
||||
version = args.version or crateName.version;
|
||||
|
||||
inherit cargoArtifacts cargoVendorDir;
|
||||
|
||||
# Don't copy target dir by default since we are going to be installing bins/libs
|
||||
doCopyTargetToOutput = args.doCopyTargetToOutput ? false;
|
||||
|
||||
nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
|
||||
installFromCargoArtifactsHook
|
||||
];
|
||||
|
||||
buildPhaseCargoCommand = args.buildPhaseCargoCommand or ''
|
||||
${cargoBuildCommand} ${cargoExtraArgs}
|
||||
'';
|
||||
|
||||
checkPhaseCargoCommand = args.checkPhaseCargoCommand or ''
|
||||
${cargoTestCommand} ${cargoExtraArgs}
|
||||
'';
|
||||
|
||||
installPhaseCargoCommand = args.installPhaseCargoCommand or ''
|
||||
installFromCargoArtifacts
|
||||
'';
|
||||
})
|
||||
|
@ -17,6 +17,7 @@ lib.makeScope newScope (self:
|
||||
cleanCargoToml = callPackage ./cleanCargoToml.nix { };
|
||||
crateNameFromCargoToml = callPackage ./crateNameFromCargoToml.nix { };
|
||||
downloadCargoPackage = callPackage ./downloadCargoPackage.nix { };
|
||||
mkCargoDerivation = callPackage ./mkCargoDerivation.nix { };
|
||||
mkDummySrc = callPackage ./mkDummySrc.nix { };
|
||||
urlForCargoPackage = callPackage ./urlForCargoPackage.nix { };
|
||||
vendorCargoDeps = callPackage ./vendorCargoDeps.nix { };
|
||||
|
64
lib/mkCargoDerivation.nix
Normal file
64
lib/mkCargoDerivation.nix
Normal file
@ -0,0 +1,64 @@
|
||||
{ cargo
|
||||
, configureCargoCommonVarsHook
|
||||
, configureCargoVendoredDepsHook
|
||||
, copyCargoTargetToOutputHook
|
||||
, inheritCargoArtifactsHook
|
||||
, remapSourcePathPrefixHook
|
||||
, stdenv
|
||||
}:
|
||||
|
||||
args@{
|
||||
# A directory to an existing cargo `target` directory, which will be reused
|
||||
# at the start of the derivation. Useful for caching incremental cargo builds.
|
||||
cargoArtifacts
|
||||
# A directory of vendored cargo sources which can be consumed without network
|
||||
# access. Directory structure should basically follow the output of `cargo vendor`.
|
||||
, cargoVendorDir
|
||||
# A command (likely a cargo invocation) to run during the derivation's build
|
||||
# phase. Pre and post build hooks will automatically be run.
|
||||
, buildPhaseCargoCommand
|
||||
# A command (likely a cargo invocation) to run during the derivation's check
|
||||
# phase. Pre and post check hooks will automatically be run.
|
||||
, checkPhaseCargoCommand
|
||||
# A command (likely a cargo invocation) to run during the derivation's install
|
||||
# phase. Pre and post install hooks will automatically be run.
|
||||
, installPhaseCargoCommand
|
||||
, ...
|
||||
}:
|
||||
stdenv.mkDerivation (args // {
|
||||
# Controls whether cargo's `target` directory should be copied as an output
|
||||
doCopyTargetToOutput = args.doCopyTargetToOutput or true;
|
||||
|
||||
# Controls instructing rustc to remap the path prefix of any sources it
|
||||
# captures (for example, this can include file names in panic info). This is
|
||||
# useful to omit any references to `/nix/store/...` from the final binary,
|
||||
# as including them will make Nix pull in all sources when installing any binaries.
|
||||
doRemapSourcePathPrefix = args.doRemapSourcePathPrefix or true;
|
||||
|
||||
nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
|
||||
cargo
|
||||
configureCargoCommonVarsHook
|
||||
configureCargoVendoredDepsHook
|
||||
copyCargoTargetToOutputHook
|
||||
inheritCargoArtifactsHook
|
||||
remapSourcePathPrefixHook
|
||||
];
|
||||
|
||||
buildPhase = args.buildPhase or ''
|
||||
runHook preBuild
|
||||
${buildPhaseCargoCommand}
|
||||
runHook postBuild
|
||||
'';
|
||||
|
||||
checkPhase = args.checkPhase or ''
|
||||
runHook preCheck
|
||||
${checkPhaseCargoCommand}
|
||||
runHook postCheck
|
||||
'';
|
||||
|
||||
installPhase = args.installPhase or ''
|
||||
runHook preInstall
|
||||
${installPhaseCargoCommand}
|
||||
runHook postInstall
|
||||
'';
|
||||
})
|
Loading…
Reference in New Issue
Block a user