Merge pull request #268619 from tweag/lib-descriptions
[NixPkgs.git] / pkgs / top-level / stage.nix
blob1cc05167cee837183fed97eab0b0342774784af3
1 /* This file composes a single bootstrapping stage of the Nix Packages
2    collection. That is, it imports the functions that build the various
3    packages, and calls them with appropriate arguments. The result is a set of
4    all the packages in the Nix Packages collection for some particular platform
5    for some particular stage.
7    Default arguments are only provided for bootstrapping
8    arguments. Normal users should not import this directly but instead
9    import `pkgs/default.nix` or `default.nix`. */
11 let
12   # An overlay to auto-call packages in ../by-name.
13   # By defining it at the top of the file,
14   # this value gets reused even if this file is imported multiple times,
15   # thanks to Nix's import-value cache.
16   autoCalledPackages = import ./by-name-overlay.nix ../by-name;
19 { ## Misc parameters kept the same for all stages
20   ##
22   # Utility functions, could just import but passing in for efficiency
23   lib
25 , # Use to reevaluate Nixpkgs
26   nixpkgsFun
28   ## Other parameters
29   ##
31 , # Either null or an object in the form:
32   #
33   #   {
34   #     pkgsBuildBuild = ...;
35   #     pkgsBuildHost = ...;
36   #     pkgsBuildTarget = ...;
37   #     pkgsHostHost = ...;
38   #     # pkgsHostTarget skipped on purpose.
39   #     pkgsTargetTarget ...;
40   #   }
41   #
42   # These are references to adjacent bootstrapping stages. The more familiar
43   # `buildPackages` and `targetPackages` are defined in terms of them. If null,
44   # they are instead defined internally as the current stage. This allows us to
45   # avoid expensive splicing. `pkgsHostTarget` is skipped because it is always
46   # defined as the current stage.
47   adjacentPackages
49 , # The standard environment to use for building packages.
50   stdenv
52 , # This is used because stdenv replacement and the stdenvCross do benefit from
53   # the overridden configuration provided by the user, as opposed to the normal
54   # bootstrapping stdenvs.
55   allowCustomOverrides
57 , # Non-GNU/Linux OSes are currently "impure" platforms, with their libc
58   # outside of the store.  Thus, GCC, GFortran, & co. must always look for files
59   # in standard system directories (/usr/include, etc.)
60   noSysDirs ? stdenv.buildPlatform.system != "x86_64-freebsd"
61            && stdenv.buildPlatform.system != "i686-freebsd"
62            && stdenv.buildPlatform.system != "x86_64-solaris"
63            && stdenv.buildPlatform.system != "x86_64-kfreebsd-gnu"
65 , # The configuration attribute set
66   config
68 , # A list of overlays (Additional `self: super: { .. }` customization
69   # functions) to be fixed together in the produced package set
70   overlays
71 } @args:
73 let
74   # This is a function from parsed platforms (like
75   # stdenv.hostPlatform.parsed) to parsed platforms.
76   makeMuslParsedPlatform = parsed:
77     # The following line guarantees that the output of this function
78     # is a well-formed platform with no missing fields.  It will be
79     # uncommented in a separate PR, in case it breaks the build.
80     #(x: lib.trivial.pipe x [ (x: builtins.removeAttrs x [ "_type" ]) lib.systems.parse.mkSystem ])
81       (parsed // {
82         abi = {
83           gnu = lib.systems.parse.abis.musl;
84           gnueabi = lib.systems.parse.abis.musleabi;
85           gnueabihf = lib.systems.parse.abis.musleabihf;
86           gnuabin32 = lib.systems.parse.abis.muslabin32;
87           gnuabi64 = lib.systems.parse.abis.muslabi64;
88           gnuabielfv2 = lib.systems.parse.abis.musl;
89           gnuabielfv1 = lib.systems.parse.abis.musl;
90           # The following two entries ensure that this function is idempotent.
91           musleabi = lib.systems.parse.abis.musleabi;
92           musleabihf = lib.systems.parse.abis.musleabihf;
93           muslabin32 = lib.systems.parse.abis.muslabin32;
94           muslabi64 = lib.systems.parse.abis.muslabi64;
95         }.${parsed.abi.name}
96           or lib.systems.parse.abis.musl;
97       });
100   stdenvAdapters = self: super:
101     let
102       res = import ../stdenv/adapters.nix {
103         inherit lib config;
104         pkgs = self;
105       };
106     in res // {
107       stdenvAdapters = res;
108     };
110   trivialBuilders = self: super:
111     import ../build-support/trivial-builders {
112       inherit lib;
113       inherit (self) runtimeShell stdenv stdenvNoCC;
114       inherit (self.pkgsBuildHost) shellcheck-minimal;
115       inherit (self.pkgsBuildHost.xorg) lndir;
116     };
118   stdenvBootstappingAndPlatforms = self: super: let
119     withFallback = thisPkgs:
120       (if adjacentPackages == null then self else thisPkgs)
121       // { recurseForDerivations = false; };
122   in {
123     # Here are package sets of from related stages. They are all in the form
124     # `pkgs{theirHost}{theirTarget}`. For example, `pkgsBuildHost` means their
125     # host platform is our build platform, and their target platform is our host
126     # platform. We only care about their host/target platforms, not their build
127     # platform, because the the former two alone affect the interface of the
128     # final package; the build platform is just an implementation detail that
129     # should not leak.
130     pkgsBuildBuild = withFallback adjacentPackages.pkgsBuildBuild;
131     pkgsBuildHost = withFallback adjacentPackages.pkgsBuildHost;
132     pkgsBuildTarget = withFallback adjacentPackages.pkgsBuildTarget;
133     pkgsHostHost = withFallback adjacentPackages.pkgsHostHost;
134     pkgsHostTarget = self // { recurseForDerivations = false; }; # always `self`
135     pkgsTargetTarget = withFallback adjacentPackages.pkgsTargetTarget;
137     # Older names for package sets. Use these when only the host platform of the
138     # package set matter (i.e. use `buildPackages` where any of `pkgsBuild*`
139     # would do, and `targetPackages` when any of `pkgsTarget*` would do (if we
140     # had more than just `pkgsTargetTarget`).)
141     buildPackages = self.pkgsBuildHost;
142     pkgs = self.pkgsHostTarget;
143     targetPackages = self.pkgsTargetTarget;
145     inherit stdenv;
146   };
148   splice = self: super: import ./splice.nix lib self (adjacentPackages != null);
150   allPackages = self: super:
151     let res = import ./all-packages.nix
152       { inherit lib noSysDirs config overlays; }
153       res self super;
154     in res;
156   aliases = self: super: lib.optionalAttrs config.allowAliases (import ./aliases.nix lib self super);
158   # stdenvOverrides is used to avoid having multiple of versions
159   # of certain dependencies that were used in bootstrapping the
160   # standard environment.
161   stdenvOverrides = self: super:
162     (super.stdenv.overrides or (_: _: {})) self super;
164   # Allow packages to be overridden globally via the `packageOverrides'
165   # configuration option, which must be a function that takes `pkgs'
166   # as an argument and returns a set of new or overridden packages.
167   # The `packageOverrides' function is called with the *original*
168   # (un-overridden) set of packages, allowing packageOverrides
169   # attributes to refer to the original attributes (e.g. "foo =
170   # ... pkgs.foo ...").
171   configOverrides = self: super:
172     lib.optionalAttrs allowCustomOverrides
173       ((config.packageOverrides or (super: {})) super);
175   # Convenience attributes for instantitating package sets. Each of
176   # these will instantiate a new version of allPackages. Currently the
177   # following package sets are provided:
178   #
179   # - pkgsCross.<system> where system is a member of lib.systems.examples
180   # - pkgsMusl
181   # - pkgsi686Linux
182   otherPackageSets = self: super: {
183     # This maps each entry in lib.systems.examples to its own package
184     # set. Each of these will contain all packages cross compiled for
185     # that target system. For instance, pkgsCross.raspberryPi.hello,
186     # will refer to the "hello" package built for the ARM6-based
187     # Raspberry Pi.
188     pkgsCross = lib.mapAttrs (n: crossSystem:
189                               nixpkgsFun { inherit crossSystem; })
190                               lib.systems.examples;
192     pkgsLLVM = nixpkgsFun {
193       overlays = [
194         (self': super': {
195           pkgsLLVM = super';
196         })
197       ] ++ overlays;
198       # Bootstrap a cross stdenv using the LLVM toolchain.
199       # This is currently not possible when compiling natively,
200       # so we don't need to check hostPlatform != buildPlatform.
201       crossSystem = stdenv.hostPlatform // {
202         useLLVM = true;
203         linker = "lld";
204       };
205     };
207     # All packages built with the Musl libc. This will override the
208     # default GNU libc on Linux systems. Non-Linux systems are not
209     # supported. 32-bit is also not supported.
210     pkgsMusl = if stdenv.hostPlatform.isLinux && stdenv.buildPlatform.is64bit then nixpkgsFun {
211       overlays = [ (self': super': {
212         pkgsMusl = super';
213       })] ++ overlays;
214       ${if stdenv.hostPlatform == stdenv.buildPlatform
215         then "localSystem" else "crossSystem"} = {
216         parsed = makeMuslParsedPlatform stdenv.hostPlatform.parsed;
217       };
218     } else throw "Musl libc only supports 64-bit Linux systems.";
220     # All packages built for i686 Linux.
221     # Used by wine, firefox with debugging version of Flash, ...
222     pkgsi686Linux = if stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isx86 then nixpkgsFun {
223       overlays = [ (self': super': {
224         pkgsi686Linux = super';
225       })] ++ overlays;
226       ${if stdenv.hostPlatform == stdenv.buildPlatform
227         then "localSystem" else "crossSystem"} = {
228         parsed = stdenv.hostPlatform.parsed // {
229           cpu = lib.systems.parse.cpuTypes.i686;
230         };
231       };
232     } else throw "i686 Linux package set can only be used with the x86 family.";
234     # x86_64-darwin packages for aarch64-darwin users to use with Rosetta for incompatible packages
235     pkgsx86_64Darwin = if stdenv.hostPlatform.isDarwin then nixpkgsFun {
236       overlays = [ (self': super': {
237         pkgsx86_64Darwin = super';
238       })] ++ overlays;
239       localSystem = {
240         parsed = stdenv.hostPlatform.parsed // {
241           cpu = lib.systems.parse.cpuTypes.x86_64;
242         };
243       };
244     } else throw "x86_64 Darwin package set can only be used on Darwin systems.";
246     # Extend the package set with zero or more overlays. This preserves
247     # preexisting overlays. Prefer to initialize with the right overlays
248     # in one go when calling Nixpkgs, for performance and simplicity.
249     appendOverlays = extraOverlays:
250       if extraOverlays == []
251       then self
252       else nixpkgsFun { overlays = args.overlays ++ extraOverlays; };
254     # NOTE: each call to extend causes a full nixpkgs rebuild, adding ~130MB
255     #       of allocations. DO NOT USE THIS IN NIXPKGS.
256     #
257     # Extend the package set with a single overlay. This preserves
258     # preexisting overlays. Prefer to initialize with the right overlays
259     # in one go when calling Nixpkgs, for performance and simplicity.
260     # Prefer appendOverlays if used repeatedly.
261     extend = f: self.appendOverlays [f];
263     # Fully static packages.
264     # Currently uses Musl on Linux (couldn’t get static glibc to work).
265     pkgsStatic = nixpkgsFun ({
266       overlays = [ (self': super': {
267         pkgsStatic = super';
268       })] ++ overlays;
269       crossSystem = {
270         isStatic = true;
271         parsed =
272           if stdenv.isLinux
273           then makeMuslParsedPlatform stdenv.hostPlatform.parsed
274           else stdenv.hostPlatform.parsed;
275       } // lib.optionalAttrs (stdenv.hostPlatform.system == "powerpc64-linux") {
276         gcc.abi = "elfv2";
277       };
278     });
279   };
281   # The complete chain of package set builders, applied from top to bottom.
282   # stdenvOverlays must be last as it brings package forward from the
283   # previous bootstrapping phases which have already been overlayed.
284   toFix = lib.foldl' (lib.flip lib.extends) (self: {}) ([
285     stdenvBootstappingAndPlatforms
286     stdenvAdapters
287     trivialBuilders
288     splice
289     autoCalledPackages
290     allPackages
291     otherPackageSets
292     aliases
293     configOverrides
294   ] ++ overlays ++ [
295     stdenvOverrides ]);
298   # Return the complete set of packages.
299   lib.fix toFix