6 /* `overrideDerivation drv f' takes a derivation (i.e., the result
7 of a call to the builtin function `derivation') and returns a new
8 derivation in which the attributes of the original are overridden
9 according to the function `f'. The function `f' is called with
10 the original derivation attributes.
12 `overrideDerivation' allows certain "ad-hoc" customisation
13 scenarios (e.g. in ~/.config/nixpkgs/config.nix). For instance,
14 if you want to "patch" the derivation returned by a package
15 function in Nixpkgs to build another version than what the
16 function itself provides, you can do something like this:
18 mySed = overrideDerivation pkgs.gnused (oldAttrs: {
19 name = "sed-4.2.2-pre";
21 url = ftp://alpha.gnu.org/gnu/sed/sed-4.2.2-pre.tar.bz2;
22 sha256 = "11nq06d131y4wmf3drm0yk502d2xc6n5qy82cg88rb9nqd2lj41k";
27 For another application, see build-support/vm, where this
28 function is used to build arbitrary derivations inside a QEMU
31 overrideDerivation = drv: f:
33 newDrv = derivation (drv.drvAttrs // (f drv));
34 in lib.flip (extendDerivation true) newDrv (
35 { meta = drv.meta or {};
36 passthru = if drv ? passthru then drv.passthru else {};
41 (if (drv ? crossDrv && drv ? nativeDrv)
43 crossDrv = overrideDerivation drv.crossDrv f;
44 nativeDrv = overrideDerivation drv.nativeDrv f;
49 /* `makeOverridable` takes a function from attribute set to attribute set and
50 injects `override` attribute which can be used to override arguments of
53 nix-repl> x = {a, b}: { result = a + b; }
55 nix-repl> y = lib.makeOverridable x { a = 1; b = 2; }
58 { override = «lambda»; overrideDerivation = «lambda»; result = 3; }
60 nix-repl> y.override { a = 10; }
61 { override = «lambda»; overrideDerivation = «lambda»; result = 12; }
63 Please refer to "Nixpkgs Contributors Guide" section
64 "<pkg>.overrideDerivation" to learn about `overrideDerivation` and caveats
67 makeOverridable = f: origArgs:
71 # Creates a functor with the same arguments as f
72 copyArgs = g: lib.setFunctionArgs g (lib.functionArgs f);
73 # Changes the original arguments with (potentially a function that returns) a set of new attributes
74 overrideWith = newArgs: origArgs // (if lib.isFunction newArgs then newArgs origArgs else newArgs);
76 # Re-call the function but with different arguments
77 overrideArgs = copyArgs (newArgs: makeOverridable f (overrideWith newArgs));
78 # Change the result of the function call by applying g to it
79 overrideResult = g: makeOverridable (copyArgs (args: g (f args))) origArgs;
81 if builtins.isAttrs result then
83 override = overrideArgs;
84 overrideDerivation = fdrv: overrideResult (x: overrideDerivation x fdrv);
85 ${if result ? overrideAttrs then "overrideAttrs" else null} = fdrv:
86 overrideResult (x: x.overrideAttrs fdrv);
88 else if lib.isFunction result then
89 # Transform the result into a functor while propagating its arguments
90 lib.setFunctionArgs result (lib.functionArgs result) // {
91 override = overrideArgs;
96 /* Call the package function in the file `fn' with the required
97 arguments automatically. The function is called with the
98 arguments `args', but any missing arguments are obtained from
99 `autoArgs'. This function is intended to be partially
102 callPackage = callPackageWith pkgs;
104 libfoo = callPackage ./foo.nix { };
105 libbar = callPackage ./bar.nix { };
108 If the `libbar' function expects an argument named `libfoo', it is
109 automatically passed as an argument. Overrides or missing
110 arguments can be supplied in `args', e.g.
112 libbar = callPackage ./bar.nix {
117 callPackageWith = autoArgs: fn: args:
119 f = if lib.isFunction fn then fn else import fn;
120 auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
121 in makeOverridable f (auto // args);
124 /* Like callPackage, but for a function that returns an attribute
125 set of derivations. The override function is added to the
126 individual attributes. */
127 callPackagesWith = autoArgs: fn: args:
129 f = if lib.isFunction fn then fn else import fn;
130 auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
131 origArgs = auto // args;
133 mkAttrOverridable = name: _: makeOverridable (newArgs: (f newArgs).${name}) origArgs;
135 if lib.isDerivation pkgs then throw
136 ("function `callPackages` was called on a *single* derivation "
137 + ''"${pkgs.name or "<unknown-name>"}";''
138 + " did you mean to use `callPackage` instead?")
139 else lib.mapAttrs mkAttrOverridable pkgs;
142 /* Add attributes to each output of a derivation without changing
143 the derivation itself and check a given condition when evaluating. */
144 extendDerivation = condition: passthru: drv:
146 outputs = drv.outputs or [ "out" ];
148 commonAttrs = (removeAttrs drv [ "outputUnspecified" ]) //
149 (builtins.listToAttrs outputsList) //
150 ({ all = map (x: x.value) outputsList; }) // passthru;
152 outputToAttrListElement = outputName:
154 value = commonAttrs // {
155 inherit (drv.${outputName}) type outputName;
156 drvPath = assert condition; drv.${outputName}.drvPath;
157 outPath = assert condition; drv.${outputName}.outPath;
161 outputsList = map outputToAttrListElement outputs;
163 outputUnspecified = true;
164 drvPath = assert condition; drv.drvPath;
165 outPath = assert condition; drv.outPath;
168 /* Strip a derivation of all non-essential attributes, returning
169 only those needed by hydra-eval-jobs. Also strictly evaluate the
170 result to ensure that there are no thunks kept alive to prevent
171 garbage collection. */
174 outputs = drv.outputs or ["out"];
177 { inherit (drv) name system meta; inherit outputs; }
178 // lib.optionalAttrs (drv._hydraAggregate or false) {
179 _hydraAggregate = true;
180 constituents = map hydraJob (lib.flatten drv.constituents);
182 // (lib.listToAttrs outputsList);
184 makeOutput = outputName:
185 let output = drv.${outputName}; in
187 value = commonAttrs // {
188 outPath = output.outPath;
189 drvPath = output.drvPath;
195 outputsList = map makeOutput outputs;
197 drv' = (lib.head outputsList).value;
198 in lib.deepSeq drv' drv';
200 /* Make a set of packages with a common scope. All packages called
201 with the provided `callPackage' will be evaluated with the same
202 arguments. Any package in the set may depend on any other. The
203 `overrideScope'` function allows subsequent modification of the package
204 set in a consistent way, i.e. all packages in the set will be
205 called with the overridden packages. The package sets may be
206 hierarchical: the packages in the set are called with the scope
207 provided by `newScope' and the set provides a `newScope' attribute
208 which can form the parent scope for later package sets. */
209 makeScope = newScope: f:
210 let self = f self // {
211 newScope = scope: newScope (self // scope);
212 callPackage = self.newScope {};
213 overrideScope = g: lib.warn
214 "`overrideScope` (from `lib.makeScope`) is deprecated. Do `overrideScope' (self: super: { … })` instead of `overrideScope (super: self: { … })`. All other overrides have the parameters in that order, including other definitions of `overrideScope`. This was the only definition violating the pattern."
215 (makeScope newScope (lib.fixedPoints.extends (lib.flip g) f));
216 overrideScope' = g: makeScope newScope (lib.fixedPoints.extends g f);
221 /* Like the above, but aims to support cross compilation. It's still ugly, but
222 hopefully it helps a little bit. */
223 makeScopeWithSplicing = splicePackages: newScope: otherSplices: keep: extra: f:
225 spliced0 = splicePackages {
226 pkgsBuildBuild = otherSplices.selfBuildBuild;
227 pkgsBuildHost = otherSplices.selfBuildHost;
228 pkgsBuildTarget = otherSplices.selfBuildTarget;
229 pkgsHostHost = otherSplices.selfHostHost;
230 pkgsHostTarget = self; # Not `otherSplices.selfHostTarget`;
231 pkgsTargetTarget = otherSplices.selfTargetTarget;
233 spliced = extra spliced0 // spliced0 // keep self;
235 newScope = scope: newScope (spliced // scope);
236 callPackage = newScope spliced; # == self.newScope {};
237 # N.B. the other stages of the package set spliced in are *not*
239 overrideScope = g: makeScopeWithSplicing
245 (lib.fixedPoints.extends g f);