Merge pull request #18660 from aneeshusa/add-override-attrs

mkDerivation: add overrideAttrs function

Changed files
+74 -10
doc
lib
pkgs
stdenv
generic
+61
doc/functions.xml
···
</section>
+
<section xml:id="sec-pkg-overrideAttrs">
+
<title>&lt;pkg&gt;.overrideAttrs</title>
+
+
<para>
+
The function <varname>overrideAttrs</varname> allows overriding the
+
attribute set passed to a <varname>stdenv.mkDerivation</varname> call,
+
producing a new derivation based on the original one.
+
This function is available on all derivations produced by the
+
<varname>stdenv.mkDerivation</varname> function, which is most packages
+
in the nixpkgs expression <varname>pkgs</varname>.
+
</para>
+
+
<para>
+
Example usage:
+
+
<programlisting>helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
+
separateDebugInfo = true;
+
});</programlisting>
+
</para>
+
+
<para>
+
In the above example, the <varname>separateDebugInfo</varname> attribute is
+
overriden to be true, thus building debug info for
+
<varname>helloWithDebug</varname>, while all other attributes will be
+
retained from the original <varname>hello</varname> package.
+
</para>
+
+
<para>
+
The argument <varname>oldAttrs</varname> is conventionally used to refer to
+
the attr set originally passed to <varname>stdenv.mkDerivation</varname>.
+
</para>
+
+
<note>
+
<para>
+
Note that <varname>separateDebugInfo</varname> is processed only by the
+
<varname>stdenv.mkDerivation</varname> function, not the generated, raw
+
Nix derivation. Thus, using <varname>overrideDerivation</varname> will
+
not work in this case, as it overrides only the attributes of the final
+
derivation. It is for this reason that <varname>overrideAttrs</varname>
+
should be preferred in (almost) all cases to
+
<varname>overrideDerivation</varname>, i.e. to allow using
+
<varname>sdenv.mkDerivation</varname> to process input arguments, as well
+
as the fact that it is easier to use (you can use the same attribute
+
names you see in your Nix code, instead of the ones generated (e.g.
+
<varname>buildInputs</varname> vs <varname>nativeBuildInputs</varname>,
+
and involves less typing.
+
</para>
+
</note>
+
+
</section>
+
+
<section xml:id="sec-pkg-overrideDerivation">
<title>&lt;pkg&gt;.overrideDerivation</title>
+
+
<warning>
+
<para>You should prefer <varname>overrideAttrs</varname> in almost all
+
cases, see its documentation for the reasons why.
+
<varname>overrideDerivation</varname> is not deprecated and will continue
+
to work, but is less nice to use and does not have as many abilities as
+
<varname>overrideAttrs</varname>.
+
</para>
+
</warning>
<warning>
<para>Do not use this function in Nixpkgs as it evaluates a Derivation
+12 -10
lib/customisation.nix
···
ff = f origArgs;
overrideWith = newArgs: origArgs // (if builtins.isFunction newArgs then newArgs origArgs else newArgs);
in
-
if builtins.isAttrs ff then (ff //
-
{ override = newArgs: makeOverridable f (overrideWith newArgs);
-
overrideDerivation = fdrv:
-
makeOverridable (args: overrideDerivation (f args) fdrv) origArgs;
-
})
-
else if builtins.isFunction ff then
-
{ override = newArgs: makeOverridable f (overrideWith newArgs);
-
__functor = self: ff;
-
overrideDerivation = throw "overrideDerivation not yet supported for functors";
-
}
+
if builtins.isAttrs ff then (ff // {
+
override = newArgs: makeOverridable f (overrideWith newArgs);
+
overrideDerivation = fdrv:
+
makeOverridable (args: overrideDerivation (f args) fdrv) origArgs;
+
${if ff ? overrideAttrs then "overrideAttrs" else null} = fdrv:
+
makeOverridable (args: (f args).overrideAttrs fdrv) origArgs;
+
})
+
else if builtins.isFunction ff then {
+
override = newArgs: makeOverridable f (overrideWith newArgs);
+
__functor = self: ff;
+
overrideDerivation = throw "overrideDerivation not yet supported for functors";
+
}
else ff;
+1
pkgs/stdenv/generic/default.nix
···
outputs = outputs';
} else { })))) (
{
+
overrideAttrs = f: mkDerivation (attrs // (f attrs));
# The meta attribute is passed in the resulting attribute set,
# but it's not part of the actual derivation, i.e., it's not
# passed to the builder and is not a dependency. But since we