stdenv.mkDerivation: small performance wins (#513729)

This commit is contained in:
Emily
2026-04-26 22:11:41 +00:00
committed by GitHub
2 changed files with 135 additions and 153 deletions
+2
View File
@@ -274,6 +274,8 @@
- The default packages in `services.jenkins.packages` have been dropped, since not every Jenkins installation needs any package at all. It's more reasonable to leave it empty and let users configure what they need.
- The `pie` hardening flag has been removed and will now error, after being deprecated in 25.11. Compilers are expected to enable PIE by default, as has been common practice since 2016 outside of Nixpkgs. If a package needs `pie` disabled pass `-no-pie` in `CFLAGS`. It is unlikely this will be necessary in many cases; due to the prevalence of default PIE toolchains, most packages incompatible with PIE already pass `-no-pie`.
## Other Notable Changes {#sec-nixpkgs-release-26.05-notable-changes}
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
+133 -153
View File
@@ -20,7 +20,6 @@ let
concatMapStrings
concatStringsSep
elem
elemAt
extendDerivation
filter
filterAttrs
@@ -95,51 +94,46 @@ let
# NOTE: the above documentation had to be duplicated in `lib/customisation.nix`: `makeOverridable`.
overrideAttrs =
f0:
let
extends' =
overlay: f:
makeDerivationExtensible (
final:
let
prev = rattrs final;
thisOverlay = lib.toExtension f0 final prev;
pos = builtins.unsafeGetAttrPos "version" thisOverlay;
in
lib.warnIf
(
final:
let
prev = f final;
thisOverlay = overlay final prev;
warnForBadVersionOverride = (
prev ? src
&& thisOverlay ? version
&& prev ? version
# We could check that the version is actually distinct, but that
# would probably just delay the inevitable, or preserve tech debt.
# && prev.version != thisOverlay.version
&& !(thisOverlay ? src)
&& !(thisOverlay.__intentionallyOverridingVersion or false)
);
pname = args.pname or "<unknown name>";
version = args.version or "<unknown version>";
pos = builtins.unsafeGetAttrPos "version" thisOverlay;
in
lib.warnIf warnForBadVersionOverride ''
${
args.name or "${pname}-${version}"
} was overridden with `version` but not `src` at ${pos.file or "<unknown file>"}:${
toString pos.line or "<unknown line>"
}:${toString pos.column or "<unknown column>"}.
prev ? src
&& thisOverlay ? version
&& prev ? version
# We could check that the version is actually distinct, but that
# would probably just delay the inevitable, or preserve tech debt.
# && prev.version != thisOverlay.version
&& !(thisOverlay ? src)
&& !(thisOverlay.__intentionallyOverridingVersion or false)
)
''
${
args.name or "${args.pname or "<unknown name>"}-${args.version or "<unknown version>"}"
} was overridden with `version` but not `src` at ${pos.file or "<unknown file>"}:${
toString pos.line or "<unknown line>"
}:${toString pos.column or "<unknown column>"}.
This is most likely not what you want. In order to properly change the version of a package, override
both the `version` and `src` attributes:
This is most likely not what you want. In order to properly change the version of a package, override
both the `version` and `src` attributes:
hello.overrideAttrs (oldAttrs: rec {
version = "1.0.0";
src = pkgs.fetchurl {
url = "mirror://gnu/hello/hello-''${version}.tar.gz";
hash = "...";
};
})
hello.overrideAttrs (oldAttrs: rec {
version = "1.0.0";
src = pkgs.fetchurl {
url = "mirror://gnu/hello/hello-''${version}.tar.gz";
hash = "...";
};
})
(To silence this warning, set `__intentionallyOverridingVersion = true` in your `overrideAttrs` call.)
'' (prev // (removeAttrs thisOverlay [ "__intentionallyOverridingVersion" ]))
);
in
makeDerivationExtensible (extends' (lib.toExtension f0) rattrs);
(To silence this warning, set `__intentionallyOverridingVersion = true` in your `overrideAttrs` call.)
''
(prev // (removeAttrs thisOverlay [ "__intentionallyOverridingVersion" ]))
);
finalPackage = mkDerivationSimple overrideAttrs args;
@@ -375,17 +369,6 @@ let
...
}@attrs:
# Policy on acceptable hash types in nixpkgs
assert
attrs ? outputHash
-> (
let
algo = attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash));
in
if algo == "md5" then throw "Rejected insecure ${algo} hash '${attrs.outputHash}'" else true
);
let
# TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when
# no package has `doCheck = true`.
@@ -395,13 +378,17 @@ let
separateDebugInfo' =
let
actualValue = separateDebugInfo && isLinux;
conflictingOption =
in
if
actualValue
&& (
attrs ? "disallowedReferences"
|| attrs ? "disallowedRequisites"
|| attrs ? "allowedRequisites"
|| attrs ? "allowedReferences";
in
if actualValue && conflictingOption && !__structuredAttrs then
|| attrs ? "allowedReferences"
)
&& !__structuredAttrs
then
throw "separateDebugInfo = true in ${
attrs.pname or "mkDerivation argument"
} requires __structuredAttrs if {dis,}allowedRequisites or {dis,}allowedReferences is set"
@@ -410,7 +397,7 @@ let
outputs' = outputs ++ optional separateDebugInfo' "debug";
noNonNativeDeps =
builtins.length (
(
depsBuildTarget
++ depsBuildTargetPropagated
++ depsHostHost
@@ -419,12 +406,12 @@ let
++ propagatedBuildInputs
++ depsTargetTarget
++ depsTargetTargetPropagated
) == 0;
) == [ ];
dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenvHasCC;
concretizeFlagImplications =
flag: impliesFlags: list:
if builtins.elem flag list then (list ++ impliesFlags) else list;
if elem flag list then (list ++ impliesFlags) else list;
hardeningDisable' = unique (
pipe hardeningDisable [
@@ -437,12 +424,12 @@ let
]
);
enabledHardeningOptions =
if builtins.elem "all" hardeningDisable' then
if elem "all" hardeningDisable' then
[ ]
else
subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable);
# hardeningDisable additionally supports "all".
erroneousHardeningFlags = subtractLists (knownHardeningFlags ++ [ "pie" ]) (
erroneousHardeningFlags = subtractLists knownHardeningFlags (
hardeningEnable ++ remove "all" hardeningDisable
);
@@ -451,7 +438,7 @@ let
positions: name: deps:
imap1 (
index: dep:
if dep == null || isDerivation dep || builtins.isString dep || builtins.isPath dep then
if dep == null || isDerivation dep || isString dep || builtins.isPath dep then
dep
else if isList dep then
checkDependencyList' ([ index ] ++ positions) name dep
@@ -461,7 +448,7 @@ let
}${name} for ${attrs.name or attrs.pname}"
) deps;
in
if builtins.length erroneousHardeningFlags != 0 then
if erroneousHardeningFlags != [ ] then
abort (
"mkDerivation was called with unsupported hardening flags: "
+ lib.generators.toPretty { } {
@@ -488,53 +475,58 @@ let
outputs = outputs';
dependencies = [
[
(map (drv: getDev drv.__spliced.buildBuild or drv) (
checkDependencyList "depsBuildBuild" depsBuildBuild
))
(map (drv: getDev drv.__spliced.buildHost or drv) (
checkDependencyList "nativeBuildInputs" nativeBuildInputs'
))
(map (drv: getDev drv.__spliced.buildTarget or drv) (
checkDependencyList "depsBuildTarget" depsBuildTarget
))
]
[
(map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost))
(map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs'))
]
[
(map (drv: getDev drv.__spliced.targetTarget or drv) (
checkDependencyList "depsTargetTarget" depsTargetTarget
))
]
buildBuildOutputs = map (drv: getDev drv.__spliced.buildBuild or drv) (
checkDependencyList "depsBuildBuild" depsBuildBuild
);
buildHostOutputs = map (drv: getDev drv.__spliced.buildHost or drv) (
checkDependencyList "nativeBuildInputs" nativeBuildInputs'
);
buildTargetOutputs = map (drv: getDev drv.__spliced.buildTarget or drv) (
checkDependencyList "depsBuildTarget" depsBuildTarget
);
hostHostOutputs = map (drv: getDev drv.__spliced.hostHost or drv) (
checkDependencyList "depsHostHost" depsHostHost
);
hostTargetOutputs = map (drv: getDev drv.__spliced.hostTarget or drv) (
checkDependencyList "buildInputs" buildInputs'
);
targetTargetOutputs = map (drv: getDev drv.__spliced.targetTarget or drv) (
checkDependencyList "depsTargetTarget" depsTargetTarget
);
allDependencies = concatLists [
buildBuildOutputs
buildHostOutputs
buildTargetOutputs
hostHostOutputs
hostTargetOutputs
targetTargetOutputs
];
propagatedDependencies = [
[
(map (drv: getDev drv.__spliced.buildBuild or drv) (
checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated
))
(map (drv: getDev drv.__spliced.buildHost or drv) (
checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs
))
(map (drv: getDev drv.__spliced.buildTarget or drv) (
checkDependencyList "depsBuildTargetPropagated" depsBuildTargetPropagated
))
]
[
(map (drv: getDev drv.__spliced.hostHost or drv) (
checkDependencyList "depsHostHostPropagated" depsHostHostPropagated
))
(map (drv: getDev drv.__spliced.hostTarget or drv) (
checkDependencyList "propagatedBuildInputs" propagatedBuildInputs
))
]
[
(map (drv: getDev drv.__spliced.targetTarget or drv) (
checkDependencyList "depsTargetTargetPropagated" depsTargetTargetPropagated
))
]
propagatedBuildBuildOutputs = map (drv: getDev drv.__spliced.buildBuild or drv) (
checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated
);
propagatedBuildHostOutputs = map (drv: getDev drv.__spliced.buildHost or drv) (
checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs
);
propagatedBuildTargetOutputs = map (drv: getDev drv.__spliced.buildTarget or drv) (
checkDependencyList "depsBuildTargetPropagated" depsBuildTargetPropagated
);
propagatedHostHostOutputs = map (drv: getDev drv.__spliced.hostHost or drv) (
checkDependencyList "depsHostHostPropagated" depsHostHostPropagated
);
propagatedHostTargetOutputs = map (drv: getDev drv.__spliced.hostTarget or drv) (
checkDependencyList "propagatedBuildInputs" propagatedBuildInputs
);
propagatedTargetTargetOutputs = map (drv: getDev drv.__spliced.targetTarget or drv) (
checkDependencyList "depsTargetTargetPropagated" depsTargetTargetPropagated
);
allPropagatedDependencies = concatLists [
propagatedBuildBuildOutputs
propagatedBuildHostOutputs
propagatedBuildTargetOutputs
propagatedHostHostOutputs
propagatedHostTargetOutputs
propagatedTargetTargetOutputs
];
derivationArg = removeAttrs attrs removedOrReplacedAttrNames // {
@@ -586,19 +578,19 @@ let
__ignoreNulls = true;
inherit __structuredAttrs strictDeps;
depsBuildBuild = elemAt (elemAt dependencies 0) 0;
nativeBuildInputs = elemAt (elemAt dependencies 0) 1;
depsBuildTarget = elemAt (elemAt dependencies 0) 2;
depsHostHost = elemAt (elemAt dependencies 1) 0;
buildInputs = elemAt (elemAt dependencies 1) 1;
depsTargetTarget = elemAt (elemAt dependencies 2) 0;
depsBuildBuild = buildBuildOutputs;
nativeBuildInputs = buildHostOutputs;
depsBuildTarget = buildTargetOutputs;
depsHostHost = hostHostOutputs;
buildInputs = hostTargetOutputs;
depsTargetTarget = targetTargetOutputs;
depsBuildBuildPropagated = elemAt (elemAt propagatedDependencies 0) 0;
propagatedNativeBuildInputs = elemAt (elemAt propagatedDependencies 0) 1;
depsBuildTargetPropagated = elemAt (elemAt propagatedDependencies 0) 2;
depsHostHostPropagated = elemAt (elemAt propagatedDependencies 1) 0;
propagatedBuildInputs = elemAt (elemAt propagatedDependencies 1) 1;
depsTargetTargetPropagated = elemAt (elemAt propagatedDependencies 2) 0;
depsBuildBuildPropagated = propagatedBuildBuildOutputs;
propagatedNativeBuildInputs = propagatedBuildHostOutputs;
depsBuildTargetPropagated = propagatedBuildTargetOutputs;
depsHostHostPropagated = propagatedHostHostOutputs;
propagatedBuildInputs = propagatedHostTargetOutputs;
depsTargetTargetPropagated = propagatedTargetTargetOutputs;
# This parameter is sometimes a string, sometimes null, and sometimes a list, yuck
configureFlags =
@@ -637,9 +629,7 @@ let
else
null
} =
lib.warnIf ((builtins.elem "pie" hardeningEnable) || (builtins.elem "pie" hardeningDisable))
"The 'pie' hardening flag has been removed in favor of enabling PIE by default in compilers and should no longer be used. PIE can be disabled with the -no-pie compiler flag, but this is usually not necessary as most build systems pass this if needed. Usage of the 'pie' hardening flag will become an error in future."
(builtins.concatStringsSep " " enabledHardeningOptions);
concatStringsSep " " enabledHardeningOptions;
# TODO: remove platform condition
# Enabling this check could be a breaking change as it requires to edit nix.conf
@@ -651,8 +641,6 @@ let
${if buildIsDarwin then "__darwinAllowLocalNetworking" else null} = __darwinAllowLocalNetworking;
${if buildIsDarwin then "__sandboxProfile" else null} =
let
allDependencies = concatLists (concatLists dependencies);
allPropagatedDependencies = concatLists (concatLists propagatedDependencies);
computedSandboxProfile = concatMap (input: input.__propagatedSandboxProfile or [ ]) (
extraNativeBuildInputs ++ extraBuildInputs ++ allDependencies
);
@@ -673,7 +661,6 @@ let
concatStringsSep "\n" (filter (x: x != "") (unique profiles));
${if buildIsDarwin then "__propagatedSandboxProfile" else null} =
let
allPropagatedDependencies = concatLists (concatLists propagatedDependencies);
computedPropagatedSandboxProfile = concatMap (
input: input.__propagatedSandboxProfile or [ ]
) allPropagatedDependencies;
@@ -681,8 +668,6 @@ let
unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]);
${if buildIsDarwin then "__impureHostDeps" else null} =
let
allDependencies = concatLists (concatLists dependencies);
allPropagatedDependencies = concatLists (concatLists propagatedDependencies);
computedImpureHostDeps = unique (
concatMap (input: input.__propagatedImpureHostDeps or [ ]) (
extraNativeBuildInputs ++ extraBuildInputs ++ allDependencies
@@ -705,7 +690,6 @@ let
];
${if buildIsDarwin then "__propagatedImpureHostDeps" else null} =
let
allPropagatedDependencies = concatLists (concatLists propagatedDependencies);
computedPropagatedImpureHostDeps = unique (
concatMap (input: input.__propagatedImpureHostDeps or [ ]) allPropagatedDependencies
);
@@ -715,7 +699,7 @@ let
# -- Windows/Cygwin-specific attrs --
${if isWindows || isCygwin then "allowedImpureDLLs" else null} =
allowedImpureDLLs
++ lib.optionals isCygwin [
++ optionals isCygwin [
"KERNEL32.dll"
];
@@ -738,7 +722,7 @@ let
inherit name;
value =
let
raw = zipAttrsWith (_: builtins.concatLists) [
raw = zipAttrsWith (_: concatLists) [
attrsOutputChecksFiltered
(makeOutputChecks attrs.outputChecks.${name} or { })
];
@@ -820,9 +804,8 @@ let
);
let
mainProgram = meta.mainProgram or null;
env' = env // {
${if mainProgram != null then "NIX_MAIN_PROGRAM" else null} = mainProgram;
${if meta ? mainProgram then "NIX_MAIN_PROGRAM" else null} = meta.mainProgram;
};
derivationArg = makeDerivationArgument (
@@ -852,13 +835,12 @@ let
checkedEnv =
let
overlappingNames = attrNames (builtins.intersectAttrs env' derivationArg);
prettyPrint = lib.generators.toPretty { };
makeError =
errors = lib.concatMapStringsSep "\n" (
name:
" - ${name}: in `env`: ${prettyPrint env'.${name}}; in derivation arguments: ${
prettyPrint derivationArg.${name}
}";
errors = lib.concatMapStringsSep "\n" makeError overlappingNames;
" - ${name}: in `env`: ${lib.generators.toPretty { } env'.${name}}; in derivation arguments: ${
lib.generators.toPretty { } derivationArg.${name}
}"
) overlappingNames;
in
assert assertMsg (isAttrs env && !isDerivation env)
"`env` must be an attribute set of environment variables. Set `env.env` or pick a more specific name.";
@@ -871,20 +853,18 @@ let
v
) env';
# Fixed-output derivations may not reference other paths, which means that
# for a fixed-output derivation, the corresponding inputDerivation should
# *not* be fixed-output. To achieve this we simply delete the attributes that
# would make it fixed-output.
fixedOutputRelatedAttrs = [
attrsToRemove = [
# Fixed-output derivations may not reference other paths, which means that
# for a fixed-output derivation, the corresponding inputDerivation should
# *not* be fixed-output. To achieve this we simply delete the attributes that
# would make it fixed-output.
"outputHashAlgo"
"outputHash"
"outputHashMode"
];
# inputDerivation produces the inputs; not the outputs, so any
# restrictions on what used to be the outputs don't serve a purpose
# anymore.
outputCheckAttrs = [
# inputDerivation produces the inputs; not the outputs, so any
# restrictions on what used to be the outputs don't serve a purpose
# anymore.
"allowedReferences"
"allowedRequisites"
"disallowedReferences"
@@ -902,10 +882,10 @@ let
# needed to enter a nix-shell with
# nix-build shell.nix -A inputDerivation
inputDerivation = derivation (
removeAttrs derivationArg (fixedOutputRelatedAttrs ++ outputCheckAttrs)
removeAttrs derivationArg attrsToRemove
// {
# Add a name in case the original drv didn't have one
name = "inputDerivation" + lib.optionalString (derivationArg ? name) "-${derivationArg.name}";
name = "inputDerivation" + optionalString (derivationArg ? name) "-${derivationArg.name}";
# This always only has one output
outputs = [ "out" ];
# This doesnt require any system features even if the original