diff --git a/doc/functions.xml b/doc/functions.xml
index e3a6975f91f8..3850e58c0168 100644
--- a/doc/functions.xml
+++ b/doc/functions.xml
@@ -99,9 +99,70 @@ in ...
+
+ <pkg>.overrideAttrs
+
+
+ The function overrideAttrs allows overriding the
+ attribute set passed to a stdenv.mkDerivation call,
+ producing a new derivation based on the original one.
+ This function is available on all derivations produced by the
+ stdenv.mkDerivation function, which is most packages
+ in the nixpkgs expression pkgs.
+
+
+
+ Example usage:
+
+ helloWithDebug = pkgs.hello.overrideAttrs (oldAttrs: rec {
+ separateDebugInfo = true;
+});
+
+
+
+ In the above example, the separateDebugInfo attribute is
+ overriden to be true, thus building debug info for
+ helloWithDebug, while all other attributes will be
+ retained from the original hello package.
+
+
+
+ The argument oldAttrs is conventionally used to refer to
+ the attr set originally passed to stdenv.mkDerivation.
+
+
+
+
+ Note that separateDebugInfo is processed only by the
+ stdenv.mkDerivation function, not the generated, raw
+ Nix derivation. Thus, using overrideDerivation will
+ not work in this case, as it overrides only the attributes of the final
+ derivation. It is for this reason that overrideAttrs
+ should be preferred in (almost) all cases to
+ overrideDerivation, i.e. to allow using
+ sdenv.mkDerivation 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.
+ buildInputs vs nativeBuildInputs,
+ and involves less typing.
+
+
+
+
+
+
<pkg>.overrideDerivation
+
+ You should prefer overrideAttrs in almost all
+ cases, see its documentation for the reasons why.
+ overrideDerivation is not deprecated and will continue
+ to work, but is less nice to use and does not have as many abilities as
+ overrideAttrs.
+
+
+
Do not use this function in Nixpkgs as it evaluates a Derivation
before modifying it, which breaks package abstraction and removes
diff --git a/lib/customisation.nix b/lib/customisation.nix
index efe82d786600..3e6e279824be 100644
--- a/lib/customisation.nix
+++ b/lib/customisation.nix
@@ -56,16 +56,18 @@ rec {
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;
diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix
index c1a341dd6fa5..edd5c2785dcf 100644
--- a/pkgs/stdenv/generic/default.nix
+++ b/pkgs/stdenv/generic/default.nix
@@ -234,6 +234,7 @@ let
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