stdenv: don't include drvs in disallowedRefs as build-time deps.

Derivations listed as disallowedReferences or disallowedRequisites,
currently end up as build-time dependencies.
This is problematic since the disallowed derivations will be built by nix as
build-time dependencies, while those derivations might take a very long time
to build, or might not even build successfully on the platform used.
However, in order to scan for disallowed references in the final output,
knowing the out path is sufficient, and the out path can be calculated from
the derivation without needing to build it, saving time and resources.

While the problem is less severe for allowedReferences and allowedRequisites,
since we want the derivation to be built eventually, we would still like to
get the error early and without having to wait while nix builds a derivation
that might not be used (e.g. if we listed the wrong one).
This commit is contained in:
R-VdP 2023-01-20 15:56:31 +01:00
parent 645af55243
commit 51acc6245e
No known key found for this signature in database

View File

@ -173,6 +173,13 @@ let
separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux && !(stdenv.hostPlatform.useLLVM or false);
outputs' = outputs ++ lib.optional separateDebugInfo' "debug";
# Turn a derivation into its outPath without a string context attached.
# See the comment at the usage site.
unsafeDerivationToUntrackedOutpath = drv:
if lib.isDerivation drv
then builtins.unsafeDiscardStringContext drv.outPath
else drv;
noNonNativeDeps = builtins.length (depsBuildTarget ++ depsBuildTargetPropagated
++ depsHostHost ++ depsHostHostPropagated
++ buildInputs ++ propagatedBuildInputs
@ -446,6 +453,40 @@ else let
"/bin/sh"
];
__propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps;
} //
# If we use derivations directly here, they end up as build-time dependencies.
# This is especially problematic in the case of disallowed*, since the disallowed
# derivations will be built by nix as build-time dependencies, while those
# derivations might take a very long time to build, or might not even build
# successfully on the platform used.
# We can improve on this situation by instead passing only the outPath,
# without an attached string context, to nix. The out path will be a placeholder
# which will be replaced by the actual out path if the derivation in question
# is part of the final closure (and thus needs to be built). If it is not
# part of the final closure, then the placeholder will be passed along,
# but in that case we know for a fact that the derivation is not part of the closure.
# This means that passing the out path to nix does the right thing in either
# case, both for disallowed and allowed references/requisites, and we won't
# build the derivation if it wouldn't be part of the closure, saving time and resources.
# While the problem is less severe for allowed*, since we want the derivation
# to be built eventually, we would still like to get the error early and without
# having to wait while nix builds a derivation that might not be used.
# See also https://github.com/NixOS/nix/issues/4629
lib.optionalAttrs (attrs ? disallowedReferences) {
disallowedReferences =
map unsafeDerivationToUntrackedOutpath attrs.disallowedReferences;
} //
lib.optionalAttrs (attrs ? disallowedRequisites) {
disallowedRequisites =
map unsafeDerivationToUntrackedOutpath attrs.disallowedRequisites;
} //
lib.optionalAttrs (attrs ? allowedReferences) {
allowedReferences =
lib.mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences;
} //
lib.optionalAttrs (attrs ? allowedRequisites) {
allowedRequisites =
lib.mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites;
};
validity = checkMeta { inherit meta attrs; };