Skip to content

Commit 39b64b5

Browse files
committed
mkDerivation: add overrideAttrs function
This is similar to `overrideDerivation`, but overrides the arguments to `mkDerivation` instead of the underlying `derivation` call. Also update `makeOverridable` so that uses of `overrideAttrs` can be followed by `override` and `overrideDerivation`, i.e. they can be mix-and-matched.
1 parent fbcb938 commit 39b64b5

3 files changed

Lines changed: 74 additions & 10 deletions

File tree

doc/functions.xml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,70 @@ in ...</programlisting>
8585

8686
</section>
8787

88+
<section xml:id="sec-pkg-overrideAttrs">
89+
<title>&lt;pkg&gt;.overrideAttrs</title>
90+
91+
<para>
92+
The function <varname>overrideAttrs</varname> allows overriding the
93+
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
94+
producing a new derivation based on the original one.
95+
This function is available on all derivations produced by the
96+
<varname>stdenv.mkDerivation</varname> function, which is most packages
97+
in the nixpkgs expression <varname>pkgs</varname>.
98+
</para>
99+
100+
<para>
101+
Example usage:
102+
103+
<programlisting>helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
104+
separateDebugInfo = true;
105+
});</programlisting>
106+
</para>
107+
108+
<para>
109+
In the above example, the <varname>separateDebugInfo</varname> attribute is
110+
overriden to be true, thus building debug info for
111+
<varname>helloWithDebug</varname>, while all other attributes will be
112+
retained from the original <varname>hello</varname> package.
113+
</para>
114+
115+
<para>
116+
The argument <varname>oldAttrs</varname> is conventionally used to refer to
117+
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
118+
</para>
119+
120+
<note>
121+
<para>
122+
Note that <varname>separateDebugInfo</varname> is processed only by the
123+
<varname>stdenv.mkDerivation</varname> function, not the generated, raw
124+
Nix derivation. Thus, using <varname>overrideDerivation</varname> will
125+
not work in this case, as it overrides only the attributes of the final
126+
derivation. It is for this reason that <varname>overrideAttrs</varname>
127+
should be preferred in (almost) all cases to
128+
<varname>overrideDerivation</varname>, i.e. to allow using
129+
<varname>sdenv.mkDerivation</varname> to process input arguments, as well
130+
as the fact that it is easier to use (you can use the same attribute
131+
names you see in your Nix code, instead of the ones generated (e.g.
132+
<varname>buildInputs</varname> vs <varname>nativeBuildInputs</varname>,
133+
and involves less typing.
134+
</para>
135+
</note>
136+
137+
</section>
138+
139+
88140
<section xml:id="sec-pkg-overrideDerivation">
89141
<title>&lt;pkg&gt;.overrideDerivation</title>
90142

143+
<warning>
144+
<para>You should prefer <varname>overrideAttrs</varname> in almost all
145+
cases, see its documentation for the reasons why.
146+
<varname>overrideDerivation</varname> is not deprecated and will continue
147+
to work, but is less nice to use and does not have as many abilities as
148+
<varname>overrideAttrs</varname>.
149+
</para>
150+
</warning>
151+
91152
<warning>
92153
<para>Do not use this function in Nixpkgs as it evaluates a Derivation
93154
before modifying it, which breaks package abstraction and removes

lib/customisation.nix

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,18 @@ rec {
5656
ff = f origArgs;
5757
overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs);
5858
in
59-
if builtins.isAttrs ff then (ff //
60-
{ override = newArgs: makeOverridable f (overrideWith newArgs);
61-
overrideDerivation = fdrv:
62-
makeOverridable (args: overrideDerivation (f args) fdrv) origArgs;
63-
})
64-
else if builtins.isFunction ff then
65-
{ override = newArgs: makeOverridable f (overrideWith newArgs);
66-
__functor = self: ff;
67-
overrideDerivation = throw "overrideDerivation not yet supported for functors";
68-
}
59+
if builtins.isAttrs ff then (ff // {
60+
override = newArgs: makeOverridable f (overrideWith newArgs);
61+
overrideDerivation = fdrv:
62+
makeOverridable (args: overrideDerivation (f args) fdrv) origArgs;
63+
${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
64+
makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
65+
})
66+
else if builtins.isFunction ff then {
67+
override = newArgs: makeOverridable f (overrideWith newArgs);
68+
__functor = self: ff;
69+
overrideDerivation = throw "overrideDerivation not yet supported for functors";
70+
}
6971
else ff;
7072

7173

pkgs/stdenv/generic/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ let
227227
outputs = outputs';
228228
} else { })))) (
229229
{
230+
overrideAttrs = f: mkDerivation (attrs // (f attrs));
230231
# The meta attribute is passed in the resulting attribute set,
231232
# but it's not part of the actual derivation, i.e., it's not
232233
# passed to the builder and is not a dependency. But since we

0 commit comments

Comments
 (0)