sdrangel: fix build on x86_64-darwin
[NixPkgs.git] / pkgs / stdenv / generic / make-derivation.nix
blobaf68bf890ed291f8adc14ca096070451d5c00861
1 { lib, config }:
3 stdenv:
5 let
6   # Lib attributes are inherited to the lexical scope for performance reasons.
7   inherit (lib)
8     any
9     assertMsg
10     attrNames
11     boolToString
12     concatLists
13     concatMap
14     concatMapStrings
15     concatStringsSep
16     elem
17     elemAt
18     extendDerivation
19     filter
20     findFirst
21     getDev
22     head
23     imap1
24     isAttrs
25     isBool
26     isDerivation
27     isInt
28     isList
29     isString
30     mapAttrs
31     mapNullable
32     optional
33     optionalAttrs
34     optionalString
35     optionals
36     remove
37     splitString
38     subtractLists
39     unique
40   ;
42   inherit (import ../../build-support/lib/cmake.nix { inherit lib stdenv; }) makeCMakeFlags;
43   inherit (import ../../build-support/lib/meson.nix { inherit lib stdenv; }) makeMesonFlags;
45   mkDerivation =
46     fnOrAttrs:
47       if builtins.isFunction fnOrAttrs
48       then makeDerivationExtensible fnOrAttrs
49       else makeDerivationExtensibleConst fnOrAttrs;
51   checkMeta = import ./check-meta.nix {
52     inherit lib config;
53     # Nix itself uses the `system` field of a derivation to decide where
54     # to build it. This is a bit confusing for cross compilation.
55     inherit (stdenv) hostPlatform;
56   };
58   # Based off lib.makeExtensible, with modifications:
59   makeDerivationExtensible = rattrs:
60     let
61       # NOTE: The following is a hint that will be printed by the Nix cli when
62       # encountering an infinite recursion. It must not be formatted into
63       # separate lines, because Nix would only show the last line of the comment.
65       # An infinite recursion here can be caused by having the attribute names of expression `e` in `.overrideAttrs(finalAttrs: previousAttrs: e)` depend on `finalAttrs`. Only the attribute values of `e` can depend on `finalAttrs`.
66       args = rattrs (args // { inherit finalPackage overrideAttrs; });
67       #              ^^^^
69       overrideAttrs = f0:
70         let
71           f = self: super:
72             # Convert f0 to an overlay. Legacy is:
73             #   overrideAttrs (super: {})
74             # We want to introduce self. We follow the convention of overlays:
75             #   overrideAttrs (self: super: {})
76             # Which means the first parameter can be either self or super.
77             # This is surprising, but far better than the confusion that would
78             # arise from flipping an overlay's parameters in some cases.
79             let x = f0 super;
80             in
81               if builtins.isFunction x
82               then
83                 # Can't reuse `x`, because `self` comes first.
84                 # Looks inefficient, but `f0 super` was a cheap thunk.
85                 f0 self super
86               else x;
87         in
88           makeDerivationExtensible
89             (self: let super = rattrs self; in super // (if builtins.isFunction f0 || f0?__functor then f self super else f0));
91       finalPackage =
92         mkDerivationSimple overrideAttrs args;
94     in finalPackage;
96   #makeDerivationExtensibleConst = attrs: makeDerivationExtensible (_: attrs);
97   # but pre-evaluated for a slight improvement in performance.
98   makeDerivationExtensibleConst = attrs:
99     mkDerivationSimple
100       (f0:
101         let
102           f = self: super:
103             let x = f0 super;
104             in
105               if builtins.isFunction x
106               then
107                 f0 self super
108               else x;
109         in
110           makeDerivationExtensible (self: attrs // (if builtins.isFunction f0 || f0?__functor then f self attrs else f0)))
111       attrs;
113   knownHardeningFlags = [
114     "bindnow"
115     "format"
116     "fortify"
117     "fortify3"
118     "pic"
119     "pie"
120     "relro"
121     "stackprotector"
122     "strictoverflow"
123     "trivialautovarinit"
124     "zerocallusedregs"
125   ];
127   removedOrReplacedAttrNames = [
128     "checkInputs" "installCheckInputs"
129     "nativeCheckInputs" "nativeInstallCheckInputs"
130     "__contentAddressed"
131     "__darwinAllowLocalNetworking"
132     "__impureHostDeps" "__propagatedImpureHostDeps"
133     "sandboxProfile" "propagatedSandboxProfile"
134   ];
136   # Turn a derivation into its outPath without a string context attached.
137   # See the comment at the usage site.
138   unsafeDerivationToUntrackedOutpath = drv:
139     if isDerivation drv
140     then builtins.unsafeDiscardStringContext drv.outPath
141     else drv;
143   makeDerivationArgument =
146 # `makeDerivationArgument` is responsible for the `mkDerivation` arguments that
147 # affect the actual derivation, excluding a few behaviors that are not
148 # essential, and specific to `mkDerivation`: `env`, `cmakeFlags`, `mesonFlags`.
150 # See also:
152 # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv
153 #   Details on how to use this mkDerivation function
155 # * https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations
156 #   Explanation about derivations in general
159 # These types of dependencies are all exhaustively documented in
160 # the "Specifying Dependencies" section of the "Standard
161 # Environment" chapter of the Nixpkgs manual.
163 # TODO(@Ericson2314): Stop using legacy dep attribute names
165 #                                 host offset -> target offset
166   depsBuildBuild                    ? [] # -1 -> -1
167 , depsBuildBuildPropagated          ? [] # -1 -> -1
168 , nativeBuildInputs                 ? [] # -1 ->  0  N.B. Legacy name
169 , propagatedNativeBuildInputs       ? [] # -1 ->  0  N.B. Legacy name
170 , depsBuildTarget                   ? [] # -1 ->  1
171 , depsBuildTargetPropagated         ? [] # -1 ->  1
173 , depsHostHost                      ? [] #  0 ->  0
174 , depsHostHostPropagated            ? [] #  0 ->  0
175 , buildInputs                       ? [] #  0 ->  1  N.B. Legacy name
176 , propagatedBuildInputs             ? [] #  0 ->  1  N.B. Legacy name
178 , depsTargetTarget                  ? [] #  1 ->  1
179 , depsTargetTargetPropagated        ? [] #  1 ->  1
181 , checkInputs                       ? []
182 , installCheckInputs                ? []
183 , nativeCheckInputs                 ? []
184 , nativeInstallCheckInputs          ? []
186 # Configure Phase
187 , configureFlags ? []
188 , # Target is not included by default because most programs don't care.
189   # Including it then would cause needless mass rebuilds.
190   #
191   # TODO(@Ericson2314): Make [ "build" "host" ] always the default / resolve #87909
192   configurePlatforms ? optionals
193     (stdenv.hostPlatform != stdenv.buildPlatform || config.configurePlatformsByDefault)
194     [ "build" "host" ]
196 # TODO(@Ericson2314): Make unconditional / resolve #33599
197 # Check phase
198 , doCheck ? config.doCheckByDefault or false
200 # TODO(@Ericson2314): Make unconditional / resolve #33599
201 # InstallCheck phase
202 , doInstallCheck ? config.doCheckByDefault or false
204 , # TODO(@Ericson2314): Make always true and remove / resolve #178468
205   strictDeps ? if config.strictDepsByDefault then true else stdenv.hostPlatform != stdenv.buildPlatform
207 , enableParallelBuilding ? config.enableParallelBuildingByDefault
209 , separateDebugInfo ? false
210 , outputs ? [ "out" ]
211 , __darwinAllowLocalNetworking ? false
212 , __impureHostDeps ? []
213 , __propagatedImpureHostDeps ? []
214 , sandboxProfile ? ""
215 , propagatedSandboxProfile ? ""
217 , hardeningEnable ? []
218 , hardeningDisable ? []
220 , patches ? []
222 , __contentAddressed ?
223   (! attrs ? outputHash) # Fixed-output drvs can't be content addressed too
224   && config.contentAddressedByDefault
226 # Experimental.  For simple packages mostly just works,
227 # but for anything complex, be prepared to debug if enabling.
228 , __structuredAttrs ? config.structuredAttrsByDefault or false
230 , ... } @ attrs:
232 # Policy on acceptable hash types in nixpkgs
233 assert attrs ? outputHash -> (
234   let algo =
235     attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash));
236   in
237   if algo == "md5" then
238     throw "Rejected insecure ${algo} hash '${attrs.outputHash}'"
239   else
240     true
244   # TODO(@oxij, @Ericson2314): This is here to keep the old semantics, remove when
245   # no package has `doCheck = true`.
246   doCheck' = doCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform;
247   doInstallCheck' = doInstallCheck && stdenv.buildPlatform.canExecute stdenv.hostPlatform;
249   separateDebugInfo' = separateDebugInfo && stdenv.hostPlatform.isLinux;
250   outputs' = outputs ++ optional separateDebugInfo' "debug";
252   noNonNativeDeps = builtins.length (depsBuildTarget ++ depsBuildTargetPropagated
253                                   ++ depsHostHost ++ depsHostHostPropagated
254                                   ++ buildInputs ++ propagatedBuildInputs
255                                   ++ depsTargetTarget ++ depsTargetTargetPropagated) == 0;
256   dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC;
258   hardeningDisable' = if any (x: x == "fortify") hardeningDisable
259     # disabling fortify implies fortify3 should also be disabled
260     then unique (hardeningDisable ++ [ "fortify3" ])
261     else hardeningDisable;
262   defaultHardeningFlags =
263     (if stdenv.hasCC then stdenv.cc else {}).defaultHardeningFlags or
264       # fallback safe-ish set of flags
265       (remove "pie" knownHardeningFlags);
266   enabledHardeningOptions =
267     if builtins.elem "all" hardeningDisable'
268     then []
269     else subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable);
270   # hardeningDisable additionally supports "all".
271   erroneousHardeningFlags = subtractLists knownHardeningFlags (hardeningEnable ++ remove "all" hardeningDisable);
273   checkDependencyList = checkDependencyList' [];
274   checkDependencyList' = positions: name: deps:
275     imap1
276       (index: dep:
277         if isDerivation dep || dep == null || builtins.isString dep || builtins.isPath dep then dep
278         else if isList dep then checkDependencyList' ([index] ++ positions) name dep
279         else throw "Dependency is not of a valid type: ${concatMapStrings (ix: "element ${toString ix} of ") ([index] ++ positions)}${name} for ${attrs.name or attrs.pname}")
280       deps;
281 in if builtins.length erroneousHardeningFlags != 0
282 then abort ("mkDerivation was called with unsupported hardening flags: " + lib.generators.toPretty {} {
283   inherit erroneousHardeningFlags hardeningDisable hardeningEnable knownHardeningFlags;
285 else let
286   doCheck = doCheck';
287   doInstallCheck = doInstallCheck';
288   buildInputs' = buildInputs
289          ++ optionals doCheck checkInputs
290          ++ optionals doInstallCheck installCheckInputs;
291   nativeBuildInputs' = nativeBuildInputs
292          ++ optional separateDebugInfo' ../../build-support/setup-hooks/separate-debug-info.sh
293          ++ optional stdenv.hostPlatform.isWindows ../../build-support/setup-hooks/win-dll-link.sh
294          ++ optionals doCheck nativeCheckInputs
295          ++ optionals doInstallCheck nativeInstallCheckInputs;
297   outputs = outputs';
299   dependencies = [
300     [
301       (map (drv: getDev drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuild" depsBuildBuild))
302       (map (drv: getDev drv.__spliced.buildHost or drv) (checkDependencyList "nativeBuildInputs" nativeBuildInputs'))
303       (map (drv: getDev drv.__spliced.buildTarget or drv) (checkDependencyList "depsBuildTarget" depsBuildTarget))
304     ]
305     [
306       (map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHost" depsHostHost))
307       (map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "buildInputs" buildInputs'))
308     ]
309     [
310       (map (drv: getDev drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTarget" depsTargetTarget))
311     ]
312   ];
313   propagatedDependencies = [
314     [
315       (map (drv: getDev drv.__spliced.buildBuild or drv) (checkDependencyList "depsBuildBuildPropagated" depsBuildBuildPropagated))
316       (map (drv: getDev drv.__spliced.buildHost or drv) (checkDependencyList "propagatedNativeBuildInputs" propagatedNativeBuildInputs))
317       (map (drv: getDev drv.__spliced.buildTarget or drv) (checkDependencyList "depsBuildTargetPropagated" depsBuildTargetPropagated))
318     ]
319     [
320       (map (drv: getDev drv.__spliced.hostHost or drv) (checkDependencyList "depsHostHostPropagated" depsHostHostPropagated))
321       (map (drv: getDev drv.__spliced.hostTarget or drv) (checkDependencyList "propagatedBuildInputs" propagatedBuildInputs))
322     ]
323     [
324       (map (drv: getDev drv.__spliced.targetTarget or drv) (checkDependencyList "depsTargetTargetPropagated" depsTargetTargetPropagated))
325     ]
326   ];
328   derivationArg =
329     removeAttrs attrs removedOrReplacedAttrNames
330     // (optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
331       name =
332         let
333           # Indicate the host platform of the derivation if cross compiling.
334           # Fixed-output derivations like source tarballs shouldn't get a host
335           # suffix. But we have some weird ones with run-time deps that are
336           # just used for their side-affects. Those might as well since the
337           # hash can't be the same. See #32986.
338           hostSuffix = optionalString
339             (stdenv.hostPlatform != stdenv.buildPlatform && !dontAddHostSuffix)
340             "-${stdenv.hostPlatform.config}";
342           # Disambiguate statically built packages. This was originally
343           # introduce as a means to prevent nix-env to get confused between
344           # nix and nixStatic. This should be also achieved by moving the
345           # hostSuffix before the version, so we could contemplate removing
346           # it again.
347           staticMarker = optionalString stdenv.hostPlatform.isStatic "-static";
348         in
349         lib.strings.sanitizeDerivationName (
350           if attrs ? name
351           then attrs.name + hostSuffix
352           else
353             # we cannot coerce null to a string below
354             assert assertMsg (attrs ? version && attrs.version != null) "The ‘version’ attribute cannot be null.";
355             "${attrs.pname}${staticMarker}${hostSuffix}-${attrs.version}"
356         );
357     }) // {
358       builder = attrs.realBuilder or stdenv.shell;
359       args = attrs.args or ["-e" (attrs.builder or ./default-builder.sh)];
360       inherit stdenv;
362       # The `system` attribute of a derivation has special meaning to Nix.
363       # Derivations set it to choose what sort of machine could be used to
364       # execute the build, The build platform entirely determines this,
365       # indeed more finely than Nix knows or cares about. The `system`
366       # attribute of `buildPlatfom` matches Nix's degree of specificity.
367       # exactly.
368       inherit (stdenv.buildPlatform) system;
370       userHook = config.stdenv.userHook or null;
371       __ignoreNulls = true;
372       inherit __structuredAttrs strictDeps;
374       depsBuildBuild              = elemAt (elemAt dependencies 0) 0;
375       nativeBuildInputs           = elemAt (elemAt dependencies 0) 1;
376       depsBuildTarget             = elemAt (elemAt dependencies 0) 2;
377       depsHostHost                = elemAt (elemAt dependencies 1) 0;
378       buildInputs                 = elemAt (elemAt dependencies 1) 1;
379       depsTargetTarget            = elemAt (elemAt dependencies 2) 0;
381       depsBuildBuildPropagated    = elemAt (elemAt propagatedDependencies 0) 0;
382       propagatedNativeBuildInputs = elemAt (elemAt propagatedDependencies 0) 1;
383       depsBuildTargetPropagated   = elemAt (elemAt propagatedDependencies 0) 2;
384       depsHostHostPropagated      = elemAt (elemAt propagatedDependencies 1) 0;
385       propagatedBuildInputs       = elemAt (elemAt propagatedDependencies 1) 1;
386       depsTargetTargetPropagated  = elemAt (elemAt propagatedDependencies 2) 0;
388       # This parameter is sometimes a string, sometimes null, and sometimes a list, yuck
389       configureFlags =
390         configureFlags
391         ++ optional (elem "build"  configurePlatforms) "--build=${stdenv.buildPlatform.config}"
392         ++ optional (elem "host"   configurePlatforms) "--host=${stdenv.hostPlatform.config}"
393         ++ optional (elem "target" configurePlatforms) "--target=${stdenv.targetPlatform.config}";
395       inherit patches;
397       inherit doCheck doInstallCheck;
399       inherit outputs;
400     } // optionalAttrs (__contentAddressed) {
401       inherit __contentAddressed;
402       # Provide default values for outputHashMode and outputHashAlgo because
403       # most people won't care about these anyways
404       outputHashAlgo = attrs.outputHashAlgo or "sha256";
405       outputHashMode = attrs.outputHashMode or "recursive";
406     } // optionalAttrs (enableParallelBuilding) {
407       inherit enableParallelBuilding;
408       enableParallelChecking = attrs.enableParallelChecking or true;
409       enableParallelInstalling = attrs.enableParallelInstalling or true;
410     } // optionalAttrs (hardeningDisable != [] || hardeningEnable != [] || stdenv.hostPlatform.isMusl) {
411       NIX_HARDENING_ENABLE = enabledHardeningOptions;
412     } // optionalAttrs (stdenv.hostPlatform.isx86_64 && stdenv.hostPlatform ? gcc.arch) {
413       requiredSystemFeatures = attrs.requiredSystemFeatures or [] ++ [ "gccarch-${stdenv.hostPlatform.gcc.arch}" ];
414     } // optionalAttrs (stdenv.buildPlatform.isDarwin) (
415       let
416         allDependencies = concatLists (concatLists dependencies);
417         allPropagatedDependencies = concatLists (concatLists propagatedDependencies);
419         computedSandboxProfile =
420           concatMap (input: input.__propagatedSandboxProfile or [])
421             (stdenv.extraNativeBuildInputs
422             ++ stdenv.extraBuildInputs
423             ++ allDependencies);
425         computedPropagatedSandboxProfile =
426           concatMap (input: input.__propagatedSandboxProfile or [])
427             allPropagatedDependencies;
429         computedImpureHostDeps =
430           unique (concatMap (input: input.__propagatedImpureHostDeps or [])
431             (stdenv.extraNativeBuildInputs
432             ++ stdenv.extraBuildInputs
433             ++ allDependencies));
435         computedPropagatedImpureHostDeps =
436           unique (concatMap (input: input.__propagatedImpureHostDeps or [])
437             allPropagatedDependencies);
438     in {
439       inherit __darwinAllowLocalNetworking;
440       # TODO: remove `unique` once nix has a list canonicalization primitive
441       __sandboxProfile =
442       let profiles = [ stdenv.extraSandboxProfile ] ++ computedSandboxProfile ++ computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile sandboxProfile ];
443           final = concatStringsSep "\n" (filter (x: x != "") (unique profiles));
444       in final;
445       __propagatedSandboxProfile = unique (computedPropagatedSandboxProfile ++ [ propagatedSandboxProfile ]);
446       __impureHostDeps = computedImpureHostDeps ++ computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps ++ __impureHostDeps ++ stdenv.__extraImpureHostDeps ++ [
447         "/dev/zero"
448         "/dev/random"
449         "/dev/urandom"
450         "/bin/sh"
451       ];
452       __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps;
453     }) //
454     # If we use derivations directly here, they end up as build-time dependencies.
455     # This is especially problematic in the case of disallowed*, since the disallowed
456     # derivations will be built by nix as build-time dependencies, while those
457     # derivations might take a very long time to build, or might not even build
458     # successfully on the platform used.
459     # We can improve on this situation by instead passing only the outPath,
460     # without an attached string context, to nix. The out path will be a placeholder
461     # which will be replaced by the actual out path if the derivation in question
462     # is part of the final closure (and thus needs to be built). If it is not
463     # part of the final closure, then the placeholder will be passed along,
464     # but in that case we know for a fact that the derivation is not part of the closure.
465     # This means that passing the out path to nix does the right thing in either
466     # case, both for disallowed and allowed references/requisites, and we won't
467     # build the derivation if it wouldn't be part of the closure, saving time and resources.
468     # While the problem is less severe for allowed*, since we want the derivation
469     # to be built eventually, we would still like to get the error early and without
470     # having to wait while nix builds a derivation that might not be used.
471     # See also https://github.com/NixOS/nix/issues/4629
472     optionalAttrs (attrs ? disallowedReferences) {
473       disallowedReferences =
474         map unsafeDerivationToUntrackedOutpath attrs.disallowedReferences;
475     } //
476     optionalAttrs (attrs ? disallowedRequisites) {
477       disallowedRequisites =
478         map unsafeDerivationToUntrackedOutpath attrs.disallowedRequisites;
479     } //
480     optionalAttrs (attrs ? allowedReferences) {
481       allowedReferences =
482         mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedReferences;
483     } //
484     optionalAttrs (attrs ? allowedRequisites) {
485       allowedRequisites =
486         mapNullable unsafeDerivationToUntrackedOutpath attrs.allowedRequisites;
487     };
490   derivationArg;
492 mkDerivationSimple = overrideAttrs:
494 # `mkDerivation` wraps the builtin `derivation` function to
495 # produce derivations that use this stdenv and its shell.
497 # Internally, it delegates most of its behavior to `makeDerivationArgument`,
498 # except for the `env`, `cmakeFlags`, and `mesonFlags` attributes, as well
499 # as the attributes `meta` and `passthru` that affect [package attributes],
500 # and not the derivation itself.
502 # See also:
504 # * https://nixos.org/nixpkgs/manual/#sec-using-stdenv
505 #   Details on how to use this mkDerivation function
507 # * https://nixos.org/manual/nix/stable/expressions/derivations.html#derivations
508 #   Explanation about derivations in general
510 # * [package attributes]: https://nixos.org/manual/nix/stable/glossary#package-attribute-set
513 # Configure Phase
514   cmakeFlags ? []
515 , mesonFlags ? []
517 , meta ? {}
518 , passthru ? {}
519 , pos ? # position used in error messages and for meta.position
520     (if attrs.meta.description or null != null
521       then builtins.unsafeGetAttrPos "description" attrs.meta
522       else if attrs.version or null != null
523       then builtins.unsafeGetAttrPos "version" attrs
524       else builtins.unsafeGetAttrPos "name" attrs)
526 # Experimental.  For simple packages mostly just works,
527 # but for anything complex, be prepared to debug if enabling.
528 , __structuredAttrs ? config.structuredAttrsByDefault or false
530 , env ? { }
532 , ... } @ attrs:
534 # Policy on acceptable hash types in nixpkgs
535 assert attrs ? outputHash -> (
536   let algo =
537     attrs.outputHashAlgo or (head (splitString "-" attrs.outputHash));
538   in
539   if algo == "md5" then
540     throw "Rejected insecure ${algo} hash '${attrs.outputHash}'"
541   else
542     true
546   envIsExportable = isAttrs env && !isDerivation env;
548   derivationArg = makeDerivationArgument
549     (removeAttrs
550       attrs
551         (["meta" "passthru" "pos"]
552         ++ optional (__structuredAttrs || envIsExportable) "env"
553         )
554     // optionalAttrs __structuredAttrs { env = checkedEnv; }
555     // {
556       cmakeFlags = makeCMakeFlags attrs;
557       mesonFlags = makeMesonFlags attrs;
558     });
560   meta = checkMeta.commonMeta {
561     inherit validity attrs pos;
562     references = attrs.nativeBuildInputs or [] ++ attrs.buildInputs or []
563               ++ attrs.propagatedNativeBuildInputs or [] ++ attrs.propagatedBuildInputs or [];
564   };
565   validity = checkMeta.assertValidity { inherit meta attrs; };
567   checkedEnv =
568     let
569       overlappingNames = attrNames (builtins.intersectAttrs env derivationArg);
570     in
571     assert assertMsg envIsExportable
572       "When using structured attributes, `env` must be an attribute set of environment variables.";
573     assert assertMsg (overlappingNames == [ ])
574       "The ‘env’ attribute set cannot contain any attributes passed to derivation. The following attributes are overlapping: ${concatStringsSep ", " overlappingNames}";
575     mapAttrs
576       (n: v: assert assertMsg (isString v || isBool v || isInt v || isDerivation v)
577         "The ‘env’ attribute set can only contain derivation, string, boolean or integer attributes. The ‘${n}’ attribute is of type ${builtins.typeOf v}."; v)
578       env;
580   # Fixed-output derivations may not reference other paths, which means that
581   # for a fixed-output derivation, the corresponding inputDerivation should
582   # *not* be fixed-output. To achieve this we simply delete the attributes that
583   # would make it fixed-output.
584   deleteFixedOutputRelatedAttrs = lib.flip builtins.removeAttrs [ "outputHashAlgo" "outputHash" "outputHashMode" ];
588 extendDerivation
589   validity.handled
590   ({
591      # A derivation that always builds successfully and whose runtime
592      # dependencies are the original derivations build time dependencies
593      # This allows easy building and distributing of all derivations
594      # needed to enter a nix-shell with
595      #   nix-build shell.nix -A inputDerivation
596      inputDerivation = derivation (deleteFixedOutputRelatedAttrs derivationArg // {
597        # Add a name in case the original drv didn't have one
598        name = derivationArg.name or "inputDerivation";
599        # This always only has one output
600        outputs = [ "out" ];
602        # Propagate the original builder and arguments, since we override
603        # them and they might contain references to build inputs
604        _derivation_original_builder = derivationArg.builder;
605        _derivation_original_args = derivationArg.args;
607        builder = stdenv.shell;
608        # The bash builtin `export` dumps all current environment variables,
609        # which is where all build input references end up (e.g. $PATH for
610        # binaries). By writing this to $out, Nix can find and register
611        # them as runtime dependencies (since Nix greps for store paths
612        # through $out to find them)
613        args = [ "-c" ''
614          export > $out
615          for var in $passAsFile; do
616              pathVar="''${var}Path"
617              printf "%s" "$(< "''${!pathVar}")" >> $out
618          done
619        '' ];
621        # inputDerivation produces the inputs; not the outputs, so any
622        # restrictions on what used to be the outputs don't serve a purpose
623        # anymore.
624        allowedReferences = null;
625        allowedRequisites = null;
626        disallowedReferences = [ ];
627        disallowedRequisites = [ ];
628      });
630      inherit passthru overrideAttrs;
631      inherit meta;
632    } //
633    # Pass through extra attributes that are not inputs, but
634    # should be made available to Nix expressions using the
635    # derivation (e.g., in assertions).
636    passthru)
637   (derivation (derivationArg // optionalAttrs envIsExportable checkedEnv));
641   inherit mkDerivation;