-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustPlatform.buildRustPackage: support finalAttrs
style
#194475
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,66 +17,56 @@ | |
, windows | ||
}: | ||
|
||
{ name ? "${args.pname}-${args.version}" | ||
|
||
# Name for the vendored dependencies tarball | ||
, cargoDepsName ? name | ||
|
||
, src ? null | ||
, srcs ? null | ||
, preUnpack ? null | ||
, unpackPhase ? null | ||
, postUnpack ? null | ||
, cargoPatches ? [] | ||
, patches ? [] | ||
, sourceRoot ? null | ||
, logLevel ? "" | ||
, buildInputs ? [] | ||
, nativeBuildInputs ? [] | ||
, cargoUpdateHook ? "" | ||
, cargoDepsHook ? "" | ||
, buildType ? "release" | ||
, meta ? {} | ||
, cargoLock ? null | ||
, cargoVendorDir ? null | ||
, checkType ? buildType | ||
, buildNoDefaultFeatures ? false | ||
, checkNoDefaultFeatures ? buildNoDefaultFeatures | ||
, buildFeatures ? [ ] | ||
, checkFeatures ? buildFeatures | ||
, useNextest ? false | ||
, auditable ? true | ||
|
||
, depsExtraArgs ? {} | ||
|
||
# Toggles whether a custom sysroot is created when the target is a .json file. | ||
, __internal_dontAddSysroot ? false | ||
|
||
# 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). | ||
# Otherwise, everything from the tarball would've been built/tested. | ||
, buildAndTestSubdir ? null | ||
, ... } @ args: | ||
|
||
assert cargoVendorDir == null && cargoLock == null | ||
-> !(args ? cargoSha256 && args.cargoSha256 != null) && !(args ? cargoHash && args.cargoHash != null) | ||
-> throw "cargoSha256, cargoHash, cargoVendorDir, or cargoLock must be set"; | ||
assert buildType == "release" || buildType == "debug"; | ||
let rustOverride = | ||
|
||
finalAttrs: previousAttrs: | ||
|
||
let | ||
cargoPatches = finalAttrs.cargoPatches or []; | ||
buildType = finalAttrs.buildType or "release"; | ||
checkType = finalAttrs.checkType or buildType; | ||
cargoLock = finalAttrs.cargoLock or null; | ||
cargoVendorDir = finalAttrs.cargoVendorDir or null; | ||
buildNoDefaultFeatures = finalAttrs.buildNoDefaultFeatures or false; | ||
checkNoDefaultFeatures = finalAttrs.checkNoDefaultFeatures or buildNoDefaultFeatures; | ||
buildFeatures = finalAttrs.buildFeatures or [ ]; | ||
checkFeatures = finalAttrs.checkFeatures or buildFeatures; | ||
useNextest = finalAttrs.useNextest or false; | ||
auditable = finalAttrs.auditable or true; | ||
depsExtraArgs = finalAttrs.depsExtraArgs or { }; | ||
|
||
# Toggles whether a custom sysroot is created when the target is a .json file. | ||
__internal_dontAddSysroot = finalAttrs.__internal_dontAddSysroot or false; | ||
|
||
# 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). | ||
# Otherwise, everything from the tarball would've been built/tested. | ||
buildAndTestSubdir = finalAttrs.buildAndTestSubdir or null; | ||
|
||
cargoDeps = | ||
assert cargoVendorDir == null && cargoLock == null | ||
-> !(finalAttrs.cargoSha256 or null != null) && !(finalAttrs.cargoHash or null != null) | ||
-> throw "One of cargoSha256, cargoHash, cargoVendorDir or cargoLock must be set"; | ||
if cargoVendorDir != null then null | ||
else if cargoLock != null then importCargoLock cargoLock | ||
else fetchCargoTarball ({ | ||
inherit src srcs sourceRoot preUnpack unpackPhase postUnpack cargoUpdateHook; | ||
name = cargoDepsName; | ||
src = finalAttrs.src or ""; | ||
srcs = finalAttrs.srcs or null; | ||
sourceRoot = finalAttrs.sourceRoot or null; | ||
preUnpack = finalAttrs.preUnpack or null; | ||
unpackPhase = finalAttrs.unpackPhase or null; | ||
# TODO using previousAttrs here as we otherwise trigger rebuilds for all | ||
# FOD fetcher users as finalAttrs.postUnpack is prefixed below. | ||
postUnpack = previousAttrs.postUnpack or null; | ||
cargoUpdateHook = finalAttrs.cargoUpdateHook or ""; | ||
# Name for the vendored dependencies tarball | ||
name = finalAttrs.cargoDepsName or finalAttrs.name or "${finalAttrs.pname}-${finalAttrs.version}"; | ||
patches = cargoPatches; | ||
} // lib.optionalAttrs (args ? cargoHash) { | ||
hash = args.cargoHash; | ||
} // lib.optionalAttrs (args ? cargoSha256) { | ||
sha256 = args.cargoSha256; | ||
} // lib.optionalAttrs (finalAttrs ? cargoHash) { | ||
hash = finalAttrs.cargoHash; | ||
} // lib.optionalAttrs (finalAttrs ? cargoSha256) { | ||
sha256 = finalAttrs.cargoSha256; | ||
} // depsExtraArgs); | ||
|
||
target = rust.toRustTargetSpec stdenv.hostPlatform; | ||
|
@@ -89,24 +79,35 @@ let | |
(lib.removeSuffix ".json" (builtins.baseNameOf "${target}")) | ||
else target; | ||
|
||
sysroot = callPackage ./sysroot { } { | ||
sysroot = lib.throwIf (finalAttrs.doCheck or false) '' | ||
Tests don't currently work for `no_std`, and all custom sysroots are | ||
currently built without `std`. See https://os.phil-opp.com/testing/ for more | ||
information. | ||
'' (callPackage ./sysroot { } { | ||
inherit target shortTarget; | ||
RUSTFLAGS = args.RUSTFLAGS or ""; | ||
originalCargoToml = src + /Cargo.toml; # profile info is later extracted | ||
}; | ||
RUSTFLAGS = previousAttrs.RUSTFLAGS or ""; | ||
originalCargoToml = finalAttrs.src + /Cargo.toml; # profile info is later extracted | ||
}); | ||
|
||
in | ||
|
||
# Tests don't currently work for `no_std`, and all custom sysroots are currently built without `std`. | ||
# See https://os.phil-opp.com/testing/ for more information. | ||
assert useSysroot -> !(args.doCheck or true); | ||
{ | ||
removeFromBuilderEnv = [ "depsExtraArgs" "cargoUpdateHook" "cargoLock" ]; | ||
|
||
RUSTFLAGS = | ||
if useSysroot then | ||
lib.optionalString useSysroot "--sysroot ${sysroot} " | ||
+ (previousAttrs.RUSTFLAGS or "") | ||
else | ||
previousAttrs.RUSTFLAGS or null; | ||
|
||
stdenv.mkDerivation ((removeAttrs args [ "depsExtraArgs" "cargoUpdateHook" "cargoLock" ]) // lib.optionalAttrs useSysroot { | ||
RUSTFLAGS = "--sysroot ${sysroot} " + (args.RUSTFLAGS or ""); | ||
} // { | ||
inherit buildAndTestSubdir cargoDeps; | ||
inherit cargoDeps; | ||
|
||
cargoBuildType = buildType; | ||
buildAndTestSubdir = previousAttrs.buildAndTestSubdir or null; | ||
|
||
cargoBuildType = | ||
assert buildType == "release" || buildType == "debug"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we move the assserts after the inputs? thats a bit cleaner than inlining them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Due to the evaluation model of
|
||
buildType; | ||
|
||
cargoCheckType = checkType; | ||
|
||
|
@@ -120,7 +121,7 @@ stdenv.mkDerivation ((removeAttrs args [ "depsExtraArgs" "cargoUpdateHook" "carg | |
|
||
patchRegistryDeps = ./patch-registry-deps; | ||
|
||
nativeBuildInputs = nativeBuildInputs ++ lib.optionals auditable [ | ||
nativeBuildInputs = (previousAttrs.nativeBuildInputs or [ ]) ++ lib.optionals auditable [ | ||
(cargo-auditable-cargo-wrapper.override { | ||
inherit cargo cargo-auditable; | ||
}) | ||
|
@@ -132,32 +133,34 @@ stdenv.mkDerivation ((removeAttrs args [ "depsExtraArgs" "cargoUpdateHook" "carg | |
rustc | ||
]; | ||
|
||
buildInputs = buildInputs | ||
buildInputs = (previousAttrs.buildInputs or [ ]) | ||
++ lib.optionals stdenv.hostPlatform.isDarwin [ libiconv ] | ||
++ lib.optionals stdenv.hostPlatform.isMinGW [ windows.pthreads ]; | ||
|
||
patches = cargoPatches ++ patches; | ||
patches = cargoPatches ++ (previousAttrs.patches or [ ]); | ||
|
||
PKG_CONFIG_ALLOW_CROSS = | ||
if stdenv.buildPlatform != stdenv.hostPlatform then 1 else 0; | ||
|
||
postUnpack = '' | ||
eval "$cargoDepsHook" | ||
|
||
export RUST_LOG=${logLevel} | ||
'' + (args.postUnpack or ""); | ||
export RUST_LOG=${finalAttrs.logLevel or ""} | ||
'' + (previousAttrs.postUnpack or ""); | ||
|
||
configurePhase = args.configurePhase or '' | ||
configurePhase = previousAttrs.configurePhase or '' | ||
runHook preConfigure | ||
runHook postConfigure | ||
''; | ||
|
||
doCheck = args.doCheck or true; | ||
doCheck = previousAttrs.doCheck or true; | ||
|
||
strictDeps = true; | ||
|
||
meta = { | ||
# default to Rust's platforms | ||
platforms = rustc.meta.platforms; | ||
} // meta; | ||
}) | ||
} // (previousAttrs.meta or {}); | ||
}; | ||
|
||
in args: (stdenv.mkDerivation args).overrideAttrs rustOverride | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than passing the diff --git a/pkgs/build-support/rust/build-rust-package/default.nix b/pkgs/build-support/rust/build-rust-package/default.nix
index b7ae02daae0..23ae8f6b6ac 100644
--- a/pkgs/build-support/rust/build-rust-package/default.nix
+++ b/pkgs/build-support/rust/build-rust-package/default.nix
@@ -19,13 +19,14 @@
let rustOverride =
+rustAttrs:
finalAttrs:
let
cargoPatches = finalAttrs.cargoPatches or [];
buildType = finalAttrs.buildType or "release";
checkType = finalAttrs.checkType or buildType;
- cargoLock = finalAttrs.cargoLock or null;
+ cargoLock = rustAttrs.cargoLock or null;
cargoVendorDir = finalAttrs.cargoVendorDir or null;
buildNoDefaultFeatures = finalAttrs.buildNoDefaultFeatures or false;
checkNoDefaultFeatures = finalAttrs.checkNoDefaultFeatures or buildNoDefaultFeatures;
@@ -33,7 +34,7 @@ let
checkFeatures = finalAttrs.checkFeatures or buildFeatures;
useNextest = finalAttrs.useNextest or false;
auditable = finalAttrs.auditable or false; # TODO: change to true
- depsExtraArgs = finalAttrs.depsExtraArgs or { };
+ depsExtraArgs = rustAttrs.depsExtraArgs or { };
# Toggles whether a custom sysroot is created when the target is a .json file.
__internal_dontAddSysroot = finalAttrs.__internal_dontAddSysroot or false;
@@ -57,7 +58,7 @@ let
preUnpack = finalAttrs.preUnpack or null;
unpackPhase = finalAttrs.unpackPhase or null;
postUnpack = finalAttrs.postUnpack or null;
- cargoUpdateHook = finalAttrs.cargoUpdateHook or "";
+ cargoUpdateHook = rustAttrs.cargoUpdateHook or "";
# Name for the vendored dependencies tarball
name = finalAttrs.cargoDepsName or finalAttrs.name or "${finalAttrs.pname}-${finalAttrs.version}";
patches = cargoPatches;
@@ -85,7 +86,6 @@ let
in
-
previousAttrs:
lib.optionalAttrs useSysroot {
@@ -95,7 +95,6 @@ lib.optionalAttrs useSysroot {
information.
'' ("--sysroot ${sysroot} " + (finalAttrs.RUSTFLAGS or ""));
} // {
- removeFromBuilderEnv = [ "depsExtraArgs" "cargoUpdateHook" "cargoLock" ];
inherit cargoDeps;
@@ -159,4 +158,9 @@ lib.optionalAttrs useSysroot {
} // (previousAttrs.meta or {});
};
-in args: (stdenv.mkDerivation args).overrideAttrs rustOverride
+in
+args:
+let
+ derivationArgs = finalAttrs: builtins.removeAttrs (if builtins.isFunction finalAttrs then args finalAttrs else args) [ "depsExtraArgs" "cargoUpdateHook" "cargoLock" ];
+in
+(stdenv.mkDerivation derivationArgs).overrideAttrs (rustOverride args) Edit: Getting infinite recursion 😞 Would be nice to have NixOS/nix#4154 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, accidentally running into infinite recursions also happened to me a few times 😄 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -296,8 +296,10 @@ else let | |
"nativeCheckInputs" "nativeInstallCheckInputs" | ||
"__darwinAllowLocalNetworking" | ||
"__impureHostDeps" "__propagatedImpureHostDeps" | ||
"sandboxProfile" "propagatedSandboxProfile"] | ||
++ lib.optional (__structuredAttrs || envIsExportable) "env")) | ||
"sandboxProfile" "propagatedSandboxProfile" | ||
"removeFromBuilderEnv"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They would still become part of the JSON and part of the hash, causing rebuilds. Similarly, you may want to have a "local" variable that only affects the passthru attributes, but isn't a passthru itself; perhaps some configuration for an automatically generated That said, perhaps the name could be improved by removing the It's not a pretty solution, but it's the best we can do when we don't have an alternative place for such attributes. We could have a single attribute like |
||
++ lib.optional (__structuredAttrs || envIsExportable) "env" | ||
++ (attrs.removeFromBuilderEnv or []))) | ||
// (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) { | ||
name = | ||
let | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side effect of #221093. This is not ideal; I guess one solution would be to accept the rebuilds, but maybe there is a different approach here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attributes with
null
values are completely removed from the.drv
, so this doesn't look like a mass rebuild to me.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is a concrete example:
With this PR in its current state (48e9de7) as well as before this PR (fe2ecaf):
After applying this diff
we get
Diff:
Does that demonstrate the problem more clearly?