diff options
Diffstat (limited to 'pkgs/stdenv')
-rw-r--r-- | pkgs/stdenv/generic/make-derivation.nix | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index 517cfc03aea5..c53eed3dfa12 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -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; }; |