rustPlatform.buildRustPackage: support direct use of Cargo.lock

This change introduces the cargoLock argument to buildRustPackage,
which can be used in place of cargo{Sha256,Hash} or cargoVendorDir. It
uses the importCargoLock function to build the vendor
directory. Differences compared to cargo{Sha256,Hash}:

- Requires a Cargo.lock file.
- Does not require a Cargo hash.
- Retrieves all dependencies as fixed-output derivations.

This makes buildRustPackage much easier to use as part of a Rust
project, since it does not require updating cargo{Sha256,Hash} for
every change to the lock file.
This commit is contained in:
Daniël de Kok 2021-05-08 07:44:31 +02:00
parent 2f46d77e28
commit b3969f3ad7
3 changed files with 64 additions and 11 deletions

View File

@ -107,6 +107,54 @@ rustPlatform.buildRustPackage rec {
}
```
### Importing a `Cargo.lock` file
Using `cargoSha256` or `cargoHash` is tedious when using
`buildRustPackage` within a project, since it requires that the hash
is updated after every change to `Cargo.lock`. Therefore,
`buildRustPackage` also supports vendoring dependencies directly from
a `Cargo.lock` file using the `cargoLock` argument. For example:
```nix
rustPlatform.buildRustPackage rec {
pname = "myproject";
version = "1.0.0";
cargoLock = {
lockFile = ./Cargo.lock;
}
# ...
}
```
This will retrieve the dependencies using fixed-output derivations from
the specified lockfile.
The output hash of each dependency that uses a git source must be
specified in the `outputHashes` attribute. For example:
```nix
rustPlatform.buildRustPackage rec {
pname = "myproject";
version = "1.0.0";
cargoLock = {
lockFile = ./Cargo.lock;
outputHashes = {
"finalfusion-0.14.0" = "17f4bsdzpcshwh74w5z119xjy2if6l2wgyjy56v621skr2r8y904";
};
}
# ...
}
```
If you do not specify an output hash for a git dependency, building
the package will fail and inform you of which crate needs to be
added. To find the correct hash, you can first use `lib.fakeSha256` or
`lib.fakeHash` as a stub hash. Building the package (and thus the
vendored dependencies) will then inform you of the correct hash.
### Cross compilation

View File

@ -7,6 +7,7 @@
, cargoInstallHook
, cargoSetupHook
, fetchCargoTarball
, importCargoLock
, runCommandNoCC
, rustPlatform
, callPackage
@ -41,6 +42,7 @@
, cargoDepsHook ? ""
, buildType ? "release"
, meta ? {}
, cargoLock ? null
, cargoVendorDir ? null
, checkType ? buildType
, depsExtraArgs ? {}
@ -55,19 +57,22 @@
, buildAndTestSubdir ? null
, ... } @ args:
assert cargoVendorDir == null -> !(cargoSha256 == "" && cargoHash == "");
assert cargoVendorDir == null && cargoLock == null -> cargoSha256 == "" && cargoHash == ""
-> throw "cargoSha256, cargoHash, cargoVendorDir, or cargoLock must be set";
assert buildType == "release" || buildType == "debug";
let
cargoDeps = if cargoVendorDir == null
then fetchCargoTarball ({
inherit src srcs sourceRoot unpackPhase cargoUpdateHook;
name = cargoDepsName;
hash = cargoHash;
patches = cargoPatches;
sha256 = cargoSha256;
} // depsExtraArgs)
cargoDeps =
if cargoVendorDir == null
then if cargoLock != null then importCargoLock cargoLock
else fetchCargoTarball ({
inherit src srcs sourceRoot unpackPhase cargoUpdateHook;
name = cargoDepsName;
hash = cargoHash;
patches = cargoPatches;
sha256 = cargoSha256;
} // depsExtraArgs)
else null;
# If we have a cargoSha256 fixed-output derivation, validate it at build time
@ -96,7 +101,7 @@ in
# See https://os.phil-opp.com/testing/ for more information.
assert useSysroot -> !(args.doCheck or true);
stdenv.mkDerivation ((removeAttrs args ["depsExtraArgs"]) // lib.optionalAttrs useSysroot {
stdenv.mkDerivation ((removeAttrs args [ "depsExtraArgs" "cargoLock" ]) // lib.optionalAttrs useSysroot {
RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or "");
} // {
inherit buildAndTestSubdir cargoDeps;

View File

@ -13,7 +13,7 @@ rec {
buildRustPackage = callPackage ../../../build-support/rust {
inherit cargoBuildHook cargoCheckHook cargoInstallHook cargoSetupHook
fetchCargoTarball rustc;
fetchCargoTarball importCargoLock rustc;
};
importCargoLock = buildPackages.callPackage ../../../build-support/rust/import-cargo-lock.nix {};