7 functionArgs isFunction mirrorFunctionArgs isAttrs setFunctionArgs
8 optionalAttrs attrNames filter elemAt concatStringsSep sortOn take length
9 filterAttrs optionalString flip pathIsDirectory head pipe isDerivation listToAttrs
10 mapAttrs seq flatten deepSeq warnIf isInOldestRelease extends
12 inherit (lib.strings) levenshtein levenshteinAtMost;
19 `overrideDerivation drv f` takes a derivation (i.e., the result
20 of a call to the builtin function `derivation`) and returns a new
21 derivation in which the attributes of the original are overridden
22 according to the function `f`. The function `f` is called with
23 the original derivation attributes.
25 `overrideDerivation` allows certain "ad-hoc" customisation
26 scenarios (e.g. in ~/.config/nixpkgs/config.nix). For instance,
27 if you want to "patch" the derivation returned by a package
28 function in Nixpkgs to build another version than what the
29 function itself provides.
31 For another application, see build-support/vm, where this
32 function is used to build arbitrary derivations inside a QEMU
35 Note that in order to preserve evaluation errors, the new derivation's
36 outPath depends on the old one's, which means that this function cannot
37 be used in circular situations when the old derivation also depends on the
40 You should in general prefer `drv.overrideAttrs` over this function;
41 see the nixpkgs manual for more information on overriding.
48 : 1\. Function argument
52 : 2\. Function argument
57 overrideDerivation :: Derivation -> ( Derivation -> AttrSet ) -> Derivation
62 ## `lib.customisation.overrideDerivation` usage example
65 mySed = overrideDerivation pkgs.gnused (oldAttrs: {
66 name = "sed-4.2.2-pre";
68 url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
69 hash = "sha256-MxBJRcM2rYzQYwJ5XKxhXTQByvSg5jZc5cSHEZoB2IY=";
77 overrideDerivation = drv: f:
79 newDrv = derivation (drv.drvAttrs // (f drv));
80 in flip (extendDerivation (seq drv.drvPath true)) newDrv (
81 { meta = drv.meta or {};
82 passthru = if drv ? passthru then drv.passthru else {};
87 optionalAttrs (drv ? __spliced) {
88 __spliced = {} // (mapAttrs (_: sDrv: overrideDerivation sDrv f) drv.__spliced);
93 `makeOverridable` takes a function from attribute set to attribute set and
94 injects `override` attribute which can be used to override arguments of
97 Please refer to documentation on [`<pkg>.overrideDerivation`](#sec-pkg-overrideDerivation) to learn about `overrideDerivation` and caveats
105 : 1\. Function argument
110 makeOverridable :: (AttrSet -> a) -> AttrSet -> a
115 ## `lib.customisation.makeOverridable` usage example
118 nix-repl> x = {a, b}: { result = a + b; }
120 nix-repl> y = lib.makeOverridable x { a = 1; b = 2; }
123 { override = «lambda»; overrideDerivation = «lambda»; result = 3; }
125 nix-repl> y.override { a = 10; }
126 { override = «lambda»; overrideDerivation = «lambda»; result = 12; }
133 # Creates a functor with the same arguments as f
134 mirrorArgs = mirrorFunctionArgs f;
136 mirrorArgs (origArgs:
140 # Changes the original arguments with (potentially a function that returns) a set of new attributes
141 overrideWith = newArgs: origArgs // (if isFunction newArgs then newArgs origArgs else newArgs);
143 # Re-call the function but with different arguments
144 overrideArgs = mirrorArgs (newArgs: makeOverridable f (overrideWith newArgs));
145 # Change the result of the function call by applying g to it
146 overrideResult = g: makeOverridable (mirrorArgs (args: g (f args))) origArgs;
148 if isAttrs result then
150 override = overrideArgs;
151 overrideDerivation = fdrv: overrideResult (x: overrideDerivation x fdrv);
152 ${if result ? overrideAttrs then "overrideAttrs" else null} = fdrv:
153 overrideResult (x: x.overrideAttrs fdrv);
155 else if isFunction result then
156 # Transform the result into a functor while propagating its arguments
157 setFunctionArgs result (functionArgs result) // {
158 override = overrideArgs;
164 Call the package function in the file `fn` with the required
165 arguments automatically. The function is called with the
166 arguments `args`, but any missing arguments are obtained from
167 `autoArgs`. This function is intended to be partially
171 callPackage = callPackageWith pkgs;
173 libfoo = callPackage ./foo.nix { };
174 libbar = callPackage ./bar.nix { };
178 If the `libbar` function expects an argument named `libfoo`, it is
179 automatically passed as an argument. Overrides or missing
180 arguments can be supplied in `args`, e.g.
183 libbar = callPackage ./bar.nix {
189 <!-- TODO: Apply "Example:" tag to the examples above -->
196 : 1\. Function argument
200 : 2\. Function argument
204 : 3\. Function argument
209 callPackageWith :: AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a
212 callPackageWith = autoArgs: fn: args:
214 f = if isFunction fn then fn else import fn;
215 fargs = functionArgs f;
217 # All arguments that will be passed to the function
218 # This includes automatic ones and ones passed explicitly
219 allArgs = intersectAttrs fargs autoArgs // args;
221 # a list of argument names that the function requires, but
222 # wouldn't be passed to it
224 # Filter out arguments that have a default value
225 (filterAttrs (name: value: ! value)
226 # Filter out arguments that would be passed
227 (removeAttrs fargs (attrNames allArgs)));
229 # Get a list of suggested argument names for a given missing one
230 getSuggestions = arg: pipe (autoArgs // args) [
232 # Only use ones that are at most 2 edits away. While mork would work,
233 # levenshteinAtMost is only fast for 2 or less.
234 (filter (levenshteinAtMost 2 arg))
235 # Put strings with shorter distance first
236 (sortOn (levenshtein arg))
237 # Only take the first couple results
240 (map (x: "\"" + x + "\""))
243 prettySuggestions = suggestions:
244 if suggestions == [] then ""
245 else if length suggestions == 1 then ", did you mean ${elemAt suggestions 0}?"
246 else ", did you mean ${concatStringsSep ", " (lib.init suggestions)} or ${lib.last suggestions}?";
250 loc = builtins.unsafeGetAttrPos arg fargs;
251 # loc' can be removed once lib/minver.nix is >2.3.4, since that includes
252 # https://github.com/NixOS/nix/pull/3468 which makes loc be non-null
253 loc' = if loc != null then loc.file + ":" + toString loc.line
254 else if ! isFunction fn then
255 toString fn + optionalString (pathIsDirectory fn) "/default.nix"
256 else "<unknown location>";
257 in "Function called without required argument \"${arg}\" at "
258 + "${loc'}${prettySuggestions (getSuggestions arg)}";
260 # Only show the error for the first missing argument
261 error = errorForArg (head (attrNames missingArgs));
263 in if missingArgs == {}
264 then makeOverridable f allArgs
265 # This needs to be an abort so it can't be caught with `builtins.tryEval`,
266 # which is used by nix-env and ofborg to filter out packages that don't evaluate.
267 # This way we're forced to fix such errors in Nixpkgs,
268 # which is especially relevant with allowAliases = false
269 else abort "lib.customisation.callPackageWith: ${error}";
273 Like callPackage, but for a function that returns an attribute
274 set of derivations. The override function is added to the
275 individual attributes.
282 : 1\. Function argument
286 : 2\. Function argument
290 : 3\. Function argument
295 callPackagesWith :: AttrSet -> ((AttrSet -> AttrSet) | Path) -> AttrSet -> AttrSet
298 callPackagesWith = autoArgs: fn: args:
300 f = if isFunction fn then fn else import fn;
301 auto = intersectAttrs (functionArgs f) autoArgs;
302 mirrorArgs = mirrorFunctionArgs f;
303 origArgs = auto // args;
305 mkAttrOverridable = name: _: makeOverridable (mirrorArgs (newArgs: (f newArgs).${name})) origArgs;
307 if isDerivation pkgs then throw
308 ("function `callPackages` was called on a *single* derivation "
309 + ''"${pkgs.name or "<unknown-name>"}";''
310 + " did you mean to use `callPackage` instead?")
311 else mapAttrs mkAttrOverridable pkgs;
315 Add attributes to each output of a derivation without changing
316 the derivation itself and check a given condition when evaluating.
323 : 1\. Function argument
327 : 2\. Function argument
331 : 3\. Function argument
336 extendDerivation :: Bool -> Any -> Derivation -> Derivation
339 extendDerivation = condition: passthru: drv:
341 outputs = drv.outputs or [ "out" ];
343 commonAttrs = drv // (listToAttrs outputsList) //
344 ({ all = map (x: x.value) outputsList; }) // passthru;
346 outputToAttrListElement = outputName:
348 value = commonAttrs // {
349 inherit (drv.${outputName}) type outputName;
350 outputSpecified = true;
351 drvPath = assert condition; drv.${outputName}.drvPath;
352 outPath = assert condition; drv.${outputName}.outPath;
354 # TODO: give the derivation control over the outputs.
355 # `overrideAttrs` may not be the only attribute that needs
356 # updating when switching outputs.
357 optionalAttrs (passthru?overrideAttrs) {
358 # TODO: also add overrideAttrs when overrideAttrs is not custom, e.g. when not splicing.
359 overrideAttrs = f: (passthru.overrideAttrs f).${outputName};
363 outputsList = map outputToAttrListElement outputs;
365 drvPath = assert condition; drv.drvPath;
366 outPath = assert condition; drv.outPath;
370 Strip a derivation of all non-essential attributes, returning
371 only those needed by hydra-eval-jobs. Also strictly evaluate the
372 result to ensure that there are no thunks kept alive to prevent
380 : 1\. Function argument
385 hydraJob :: (Derivation | Null) -> (Derivation | Null)
390 outputs = drv.outputs or ["out"];
393 { inherit (drv) name system meta; inherit outputs; }
394 // optionalAttrs (drv._hydraAggregate or false) {
395 _hydraAggregate = true;
396 constituents = map hydraJob (flatten drv.constituents);
398 // (listToAttrs outputsList);
400 makeOutput = outputName:
401 let output = drv.${outputName}; in
403 value = commonAttrs // {
404 outPath = output.outPath;
405 drvPath = output.drvPath;
411 outputsList = map makeOutput outputs;
413 drv' = (head outputsList).value;
414 in if drv == null then null else
418 Make an attribute set (a "scope") from functions that take arguments from that same attribute set.
419 See [](#ex-makeScope) for how to use it.
423 1. `newScope` (`AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a`)
425 A function that takes an attribute set `attrs` and returns what ends up as `callPackage` in the output.
427 Typical values are `callPackageWith` or the output attribute `newScope`.
429 2. `f` (`AttrSet -> AttrSet`)
431 A function that takes an attribute set as returned by `makeScope newScope f` (a "scope") and returns any attribute set.
433 This function is used to compute the fixpoint of the resulting scope using `callPackage`.
434 Its argument is the lazily evaluated reference to the value of that fixpoint, and is typically called `self` or `final`.
436 See [](#ex-makeScope) for how to use it.
437 See [](#sec-functions-library-fixedPoints) for details on fixpoint computation.
441 `makeScope` returns an attribute set of a form called `scope`, which also contains the final attributes produced by `f`:
445 callPackage :: ((AttrSet -> a) | Path) -> AttrSet -> a
446 newScope = AttrSet -> scope
447 overrideScope = (scope -> scope -> AttrSet) -> scope
448 packages :: AttrSet -> AttrSet
452 - `callPackage` (`((AttrSet -> a) | Path) -> AttrSet -> a`)
456 1. Takes a function `p`, or a path to a Nix file that contains a function `p`, which takes an attribute set and returns value of arbitrary type `a`,
457 2. Takes an attribute set `args` with explicit attributes to pass to `p`,
458 3. Calls `f` with attributes from the original attribute set `attrs` passed to `newScope` updated with `args, i.e. `attrs // args`, if they match the attributes in the argument of `p`.
460 All such functions `p` will be called with the same value for `attrs`.
462 See [](#ex-makeScope-callPackage) for how to use it.
464 - `newScope` (`AttrSet -> scope`)
466 Takes an attribute set `attrs` and returns a scope that extends the original scope.
468 - `overrideScope` (`(scope -> scope -> AttrSet) -> scope`)
470 Takes a function `g` of the form `final: prev: { # attributes }` to act as an overlay on `f`, and returns a new scope with values determined by `extends g f`.
471 See [](https://nixos.org/manual/nixpkgs/unstable/#function-library-lib.fixedPoints.extends) for details.
473 This allows subsequent modification of the final attribute set in a consistent way, i.e. all functions `p` invoked with `callPackage` will be called with the modified values.
475 - `packages` (`AttrSet -> AttrSet`)
477 The value of the argument `f` to `makeScope`.
481 The final values returned by `f`.
485 :::{#ex-makeScope .example}
486 # Create an interdependent package set on top of `pkgs`
488 The functions in `foo.nix` and `bar.nix` can depend on each other, in the sense that `foo.nix` can contain a function that expects `bar` as an attribute in its argument.
492 pkgs = import <nixpkgs> { };
494 pkgs.lib.makeScope pkgs.newScope (self: {
495 foo = self.callPackage ./foo.nix { };
496 bar = self.callPackage ./bar.nix { };
504 callPackage = «lambda»;
506 overrideScope = «lambda»;
514 :::{#ex-makeScope-callPackage .example}
515 # Using `callPackage` from a scope
519 pkgs = import <nixpkgs> { };
521 scope = lib.makeScope lib.callPackageWith (self: { a = 1; b = 2; });
522 three = scope.callPackage ({ a, b }: a + b) { };
523 four = scope.callPackage ({ a, b }: a + b) { a = 2; };
538 makeScope :: (AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a) -> (AttrSet -> AttrSet) -> scope
541 makeScope = newScope: f:
542 let self = f self // {
543 newScope = scope: newScope (self // scope);
544 callPackage = self.newScope {};
545 overrideScope = g: makeScope newScope (extends g f);
546 # Remove after 24.11 is released.
547 overrideScope' = g: warnIf (isInOldestRelease 2311)
548 "`overrideScope'` (from `lib.makeScope`) has been renamed to `overrideScope`."
549 (makeScope newScope (extends g f));
555 backward compatibility with old uncurried form; deprecated
562 : 1\. Function argument
566 : 2\. Function argument
570 : 3\. Function argument
574 : 4\. Function argument
578 : 5\. Function argument
582 : 6\. Function argument
584 makeScopeWithSplicing =
585 splicePackages: newScope: otherSplices: keep: extra: f:
586 makeScopeWithSplicing'
587 { inherit splicePackages newScope; }
588 { inherit otherSplices keep extra f; };
591 Like makeScope, but aims to support cross compilation. It's still ugly, but
592 hopefully it helps a little bit.
597 makeScopeWithSplicing' ::
598 { splicePackages :: Splice -> AttrSet
599 , newScope :: AttrSet -> ((AttrSet -> a) | Path) -> AttrSet -> a
601 -> { otherSplices :: Splice, keep :: AttrSet -> AttrSet, extra :: AttrSet -> AttrSet }
605 { pkgsBuildBuild :: AttrSet
606 , pkgsBuildHost :: AttrSet
607 , pkgsBuildTarget :: AttrSet
608 , pkgsHostHost :: AttrSet
609 , pkgsHostTarget :: AttrSet
610 , pkgsTargetTarget :: AttrSet
614 makeScopeWithSplicing' =
619 # Attrs from `self` which won't be spliced.
620 # Avoid using keep, it's only used for a python hook workaround, added in PR #104201.
621 # ex: `keep = (self: { inherit (self) aAttr; })`
623 # Additional attrs to add to the sets `callPackage`.
624 # When the package is from a subset (but not a subset within a package IS #211340)
625 # within `spliced0` it will be spliced.
626 # When using an package outside the set but it's available from `pkgs`, use the package from `pkgs.__splicedPackages`.
627 # If the package is not available within the set or in `pkgs`, such as a package in a let binding, it will not be spliced
630 # nix-repl> darwin.apple_sdk.frameworks.CoreFoundation
631 # «derivation ...CoreFoundation-11.0.0.drv»
632 # nix-repl> darwin.CoreFoundation
633 # error: attribute 'CoreFoundation' missing
634 # nix-repl> darwin.callPackage ({ CoreFoundation }: CoreFoundation) { }
635 # «derivation ...CoreFoundation-11.0.0.drv»
637 , extra ? (_spliced0: {})
641 spliced0 = splicePackages {
642 pkgsBuildBuild = otherSplices.selfBuildBuild;
643 pkgsBuildHost = otherSplices.selfBuildHost;
644 pkgsBuildTarget = otherSplices.selfBuildTarget;
645 pkgsHostHost = otherSplices.selfHostHost;
646 pkgsHostTarget = self; # Not `otherSplices.selfHostTarget`;
647 pkgsTargetTarget = otherSplices.selfTargetTarget;
649 spliced = extra spliced0 // spliced0 // keep self;
651 newScope = scope: newScope (spliced // scope);
652 callPackage = newScope spliced; # == self.newScope {};
653 # N.B. the other stages of the package set spliced in are *not*
655 overrideScope = g: (makeScopeWithSplicing'
656 { inherit splicePackages newScope; }
657 { inherit otherSplices keep extra;