top-level: Make overridePackages extend rather than replace existing overrides

This commit is contained in:
John Ericson 2016-10-12 15:14:49 -04:00
parent da36847d92
commit e4cd45a30c
4 changed files with 77 additions and 64 deletions

View file

@ -52,6 +52,20 @@ in ...</programlisting>
It's equivalent to <varname>pkgs</varname> in the above example. It's equivalent to <varname>pkgs</varname> in the above example.
</para> </para>
<para>
Note that in previous versions of nixpkgs, this method replaced any changes from <link
linkend="sec-modify-via-packageOverrides">config.packageOverrides</link>,
along with that from previous calls if this function was called repeatedly.
Now those previous changes will be preserved so this function can be "chained" meaningfully.
To recover the old behavior, make sure <varname>config.packageOverrides<varname> is unset,
and call this only once off a "freshly" imported nixpkgs:
<programlisting>let
pkgs = import &lt;nixpkgs&gt; { config: {}; };
newpkgs = pkgs.overridePackages ...;
in ...</programlisting>
</para>
</section> </section>
<section xml:id="sec-pkg-override"> <section xml:id="sec-pkg-override">

View file

@ -69,9 +69,13 @@ rec {
# #
# nix-repl> obj # nix-repl> obj
# { __unfix__ = «lambda»; bar = "bar"; extend = «lambda»; foo = "foo + "; foobar = "foo + bar"; } # { __unfix__ = «lambda»; bar = "bar"; extend = «lambda»; foo = "foo + "; foobar = "foo + bar"; }
makeExtensible = rattrs: makeExtensible = makeExtensibleWithCustomName "extend";
# Same as `makeExtensible` but the name of the extending attribute is
# customized.
makeExtensibleWithCustomName = extenderName: rattrs:
fix' rattrs // { fix' rattrs // {
extend = f: makeExtensible (extends f rattrs); ${extenderName} = f: makeExtensibleWithCustomName extenderName (extends f rattrs);
}; };
# Flip the order of the arguments of a binary function. # Flip the order of the arguments of a binary function.

View file

@ -6,7 +6,6 @@
* Hint: ### starts category names. * Hint: ### starts category names.
*/ */
{ system, bootStdenv, noSysDirs, config, crossSystem, platform, lib { system, bootStdenv, noSysDirs, config, crossSystem, platform, lib
, pkgsWithOverrides
, ... }: , ... }:
self: pkgs: self: pkgs:
@ -35,19 +34,6 @@ in
newScope = extra: lib.callPackageWith (defaultScope // extra); newScope = extra: lib.callPackageWith (defaultScope // extra);
# Easily override this package set.
# Warning: this function is very expensive and must not be used
# from within the nixpkgs repository.
#
# Example:
# pkgs.overridePackages (self: super: {
# foo = super.foo.override { ... };
# }
#
# The result is `pkgs' where all the derivations depending on `foo'
# will use the new version.
overridePackages = f: pkgsWithOverrides f;
# Override system. This is useful to build i686 packages on x86_64-linux. # Override system. This is useful to build i686 packages on x86_64-linux.
forceSystem = system: kernel: (import ../..) { forceSystem = system: kernel: (import ../..) {
inherit system; inherit system;

View file

@ -61,6 +61,35 @@ let
inherit system bootStdenv noSysDirs config crossSystem platform lib; inherit system bootStdenv noSysDirs config crossSystem platform lib;
}; };
stdenvAdapters = self: super:
let res = import ../stdenv/adapters.nix self; in res // {
stdenvAdapters = res;
};
trivialBuilders = self: super:
(import ../build-support/trivial-builders.nix {
inherit lib; inherit (self) stdenv stdenvNoCC; inherit (self.xorg) lndir;
});
stdenvDefault = self: super: (import ./stdenv.nix topLevelArguments) {} pkgs;
allPackages = self: super:
let res = import ./all-packages.nix topLevelArguments res self;
in res;
aliases = self: super: import ./aliases.nix super;
# stdenvOverrides is used to avoid circular dependencies for building
# the standard build environment. This mechanism uses the override
# mechanism to implement some staged compilation of the stdenv.
#
# We don't want stdenv overrides in the case of cross-building, or
# otherwise the basic overridden packages will not be built with the
# crossStdenv adapter.
stdenvOverrides = self: super:
lib.optionalAttrs (crossSystem == null && super.stdenv ? overrides)
(super.stdenv.overrides super);
# Allow packages to be overridden globally via the `packageOverrides' # Allow packages to be overridden globally via the `packageOverrides'
# configuration option, which must be a function that takes `pkgs' # configuration option, which must be a function that takes `pkgs'
# as an argument and returns a set of new or overridden packages. # as an argument and returns a set of new or overridden packages.
@ -68,54 +97,34 @@ let
# (un-overridden) set of packages, allowing packageOverrides # (un-overridden) set of packages, allowing packageOverrides
# attributes to refer to the original attributes (e.g. "foo = # attributes to refer to the original attributes (e.g. "foo =
# ... pkgs.foo ..."). # ... pkgs.foo ...").
pkgs = pkgsWithOverrides (self: config.packageOverrides or (super: {})); configOverrides = self: super:
lib.optionalAttrs (bootStdenv == null)
((config.packageOverrides or (super: {})) super);
# Return the complete set of packages, after applying the overrides # The complete chain of package set builders, applied from bottom to top
# returned by the `overrider' function (see above). Warning: this toFix = lib.fold lib.extends (self: {}) [
# function is very expensive! configOverrides
pkgsWithOverrides = overrider: stdenvOverrides
let aliases
stdenvAdapters = self: super: allPackages
let res = import ../stdenv/adapters.nix self; in res // { stdenvDefault
stdenvAdapters = res; trivialBuilders
}; stdenvAdapters
];
trivialBuilders = self: super: # Use `overridePackages` to easily override this package set.
(import ../build-support/trivial-builders.nix { # Warning: this function is very expensive and must not be used
inherit lib; inherit (self) stdenv stdenvNoCC; inherit (self.xorg) lndir; # from within the nixpkgs repository.
}); #
# Example:
# pkgs.overridePackages (self: super: {
# foo = super.foo.override { ... };
# }
#
# The result is `pkgs' where all the derivations depending on `foo'
# will use the new version.
stdenvDefault = self: super: (import ./stdenv.nix topLevelArguments) {} pkgs; # Return the complete set of packages. Warning: this function is very
# expensive!
allPackagesArgs = topLevelArguments // { inherit pkgsWithOverrides; }; pkgs = lib.makeExtensibleWithCustomName "overridePackages" toFix;
allPackages = self: super: in pkgs
let res = import ./all-packages.nix allPackagesArgs res self;
in res;
aliases = self: super: import ./aliases.nix super;
# stdenvOverrides is used to avoid circular dependencies for building
# the standard build environment. This mechanism uses the override
# mechanism to implement some staged compilation of the stdenv.
#
# We don't want stdenv overrides in the case of cross-building, or
# otherwise the basic overridden packages will not be built with the
# crossStdenv adapter.
stdenvOverrides = self: super:
lib.optionalAttrs (crossSystem == null && super.stdenv ? overrides)
(super.stdenv.overrides super);
customOverrides = self: super:
lib.optionalAttrs (bootStdenv == null) (overrider self super);
in
lib.fix' (
lib.extends customOverrides (
lib.extends stdenvOverrides (
lib.extends aliases (
lib.extends allPackages (
lib.extends stdenvDefault (
lib.extends trivialBuilders (
lib.extends stdenvAdapters (
self: {}))))))));
in
pkgs