pytrainer: unpin python 3.10
[NixPkgs.git] / pkgs / stdenv / linux / default.nix
blobb8111f34e30afed36ee385ebc2bf9811f105d4bf
1 # This file constructs the standard build environment for the
2 # Linux platform.  It's completely pure; that is, it relies on no
3 # external (non-Nix) tools, such as /usr/bin/gcc, and it contains a C
4 # compiler and linker that do not search in default locations,
5 # ensuring purity of components produced by it.
7 # It starts from prebuilt seed bootstrapFiles and creates a series of
8 # nixpkgs instances (stages) to gradually rebuild stdenv, which
9 # is used to build all other packages (including the bootstrapFiles).
11 # Goals of the bootstrap process:
12 # 1. final stdenv must not reference any of the bootstrap files.
13 # 2. final stdenv must not contain any of the bootstrap files.
14 # 3. final stdenv must not contain any of the files directly
15 #    generated by the bootstrap code generators (assembler, linker,
16 #    compiler).
18 # These goals ensure that final packages and final stdenv are built
19 # exclusively using nixpkgs package definitions and don't depend
20 # on bootstrapTools (via direct references, inclusion
21 # of copied code, or code compiled directly by bootstrapTools).
23 # Stages are described below along with their definitions.
25 # Debugging stdenv dependency graph:
26 # An useful tool to explore dependencies across stages is to use
27 # '__bootPackages' attribute of 'stdenv. Examples of last 3 stages:
28 # - stdenv
29 # - stdenv.__bootPackages.stdenv
30 # - stdenv.__bootPackages.stdenv.__bootPackages.stdenv
31 # - ... and so on.
33 # To explore build-time dependencies in graphical form one can use
34 # the following:
35 #     $ nix-store --query --graph $(nix-instantiate -A stdenv) |
36 #         grep -P -v '[.]sh|[.]patch|bash|[.]tar' | # avoid clutter
37 #         dot -Tsvg > stdenv-final.svg
39 # To find all the packages built by a particular stdenv instance:
40 #    $ for stage in 0 1 2 3 4; do
41 #      echo "stage${stage} used in:"
42 #      nix-store --query --graph $(nix-instantiate -A stdenv) |
43 #          grep -P ".*bootstrap-stage${stage}-stdenv.*->.*" |
44 #          sed 's/"[0-9a-z]\{32\}-/"/g'
45 #      done
47 # To verify which stdenv was used to build a given final package:
48 #     $ nix-store --query --graph $(nix-instantiate -A stdenv) |
49 #       grep -P -v '[.]sh|[.]patch|bash|[.]tar' |
50 #       grep -P '.*stdenv.*->.*glibc-2'
51 #     "...-bootstrap-stage2-stdenv-linux.drv" -> "...-glibc-2.35-224.drv";
53 # For a TUI (rather than CLI) view, you can use:
55 #     $ nix-tree --derivation $(nix-instantiate -A stdenv)
56 { lib
57 , localSystem, crossSystem, config, overlays, crossOverlays ? []
59 , bootstrapFiles ?
60   let table = {
61     glibc = {
62       i686-linux = import ./bootstrap-files/i686-unknown-linux-gnu.nix;
63       x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-gnu.nix;
64       armv5tel-linux = import ./bootstrap-files/armv5tel-unknown-linux-gnueabi.nix;
65       armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-gnueabihf.nix;
66       armv7l-linux = import ./bootstrap-files/armv7l-unknown-linux-gnueabihf.nix;
67       aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-gnu.nix;
68       mipsel-linux = import ./bootstrap-files/mipsel-unknown-linux-gnu.nix;
69       mips64el-linux = import
70        (if localSystem.isMips64n32
71         then ./bootstrap-files/mips64el-unknown-linux-gnuabin32.nix
72         else ./bootstrap-files/mips64el-unknown-linux-gnuabi64.nix);
73       powerpc64-linux = import ./bootstrap-files/powerpc64-unknown-linux-gnuabielfv2.nix;
74       powerpc64le-linux = import ./bootstrap-files/powerpc64le-unknown-linux-gnu.nix;
75       riscv64-linux = import ./bootstrap-files/riscv64-unknown-linux-gnu.nix;
76       s390x-linux = import ./bootstrap-files/s390x-unknown-linux-gnu.nix;
77     };
78     musl = {
79       aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-musl.nix;
80       armv6l-linux  = import ./bootstrap-files/armv6l-unknown-linux-musleabihf.nix;
81       x86_64-linux  = import ./bootstrap-files/x86_64-unknown-linux-musl.nix;
82     };
83   };
85   # Try to find an architecture compatible with our current system. We
86   # just try every bootstrap we’ve got and test to see if it is
87   # compatible with or current architecture.
88   getCompatibleTools = lib.foldl (v: system:
89     if v != null then v
90     else if localSystem.canExecute (lib.systems.elaborate { inherit system; }) then archLookupTable.${system}
91     else null) null (lib.attrNames archLookupTable);
93   archLookupTable = table.${localSystem.libc}
94     or (throw "unsupported libc for the pure Linux stdenv");
95   files = archLookupTable.${localSystem.system} or (if getCompatibleTools != null then getCompatibleTools
96     else (throw "unsupported platform for the pure Linux stdenv"));
97   in (config.replaceBootstrapFiles or lib.id) files
100 assert crossSystem == localSystem;
103   inherit (localSystem) system;
105   isFromNixpkgs = pkg: !(isFromBootstrapFiles pkg);
106   isFromBootstrapFiles =
107     pkg: pkg.passthru.isFromBootstrapFiles or false;
108   isBuiltByNixpkgsCompiler =
109     pkg: isFromNixpkgs pkg && isFromNixpkgs pkg.stdenv.cc.cc;
110   isBuiltByBootstrapFilesCompiler =
111     pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc;
113   commonGccOverrides = {
114     # Use a deterministically built compiler
115     # see https://github.com/NixOS/nixpkgs/issues/108475 for context
116     reproducibleBuild = true;
117     profiledCompiler = false;
119     # It appears that libcc1 (which is not a g++ plugin; it is a gdb plugin) gets linked against
120     # the libstdc++ from the compiler that *built* g++, not the libstdc++ which was just built.
121     # This causes a reference chain from stdenv to the bootstrapFiles:
122     #
123     #   stdenv -> gcc-lib -> xgcc-lib -> bootstrapFiles
124     #
125     disableGdbPlugin = true;
126   };
128   commonPreHook =
129     ''
130       export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
131       export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
132     '';
135   # The bootstrap process proceeds in several steps.
138   # Create a standard environment by downloading pre-built binaries of
139   # coreutils, GCC, etc.
142   # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...).
143   bootstrapTools = import ./bootstrap-tools {
144     inherit (localSystem) libc system;
145     inherit lib bootstrapFiles config;
146     isFromBootstrapFiles = true;
147   };
149   getLibc = stage: stage.${localSystem.libc};
152   # This function builds the various standard environments used during
153   # the bootstrap.  In all stages, we build an stdenv and the package
154   # set that can be built with that stdenv.
155   stageFun = prevStage:
156     { name, overrides ? (self: super: {}), extraNativeBuildInputs ? [] }:
158     let
160       thisStdenv = import ../generic {
161         name = "${name}-stdenv-linux";
162         buildPlatform = localSystem;
163         hostPlatform = localSystem;
164         targetPlatform = localSystem;
165         inherit config extraNativeBuildInputs;
166         preHook =
167           ''
168             # Don't patch #!/interpreter because it leads to retained
169             # dependencies on the bootstrapTools in the final stdenv.
170             dontPatchShebangs=1
171             ${commonPreHook}
172           '';
173         shell = "${bootstrapTools}/bin/bash";
174         initialPath = [bootstrapTools];
176         fetchurlBoot = import ../../build-support/fetchurl/boot.nix {
177           inherit system;
178         };
180         cc = if prevStage.gcc-unwrapped == null
181              then null
182              else (lib.makeOverridable (import ../../build-support/cc-wrapper) {
183           name = "${name}-gcc-wrapper";
184           nativeTools = false;
185           nativeLibc = false;
186           expand-response-params = lib.optionalString
187             (prevStage.stdenv.hasCC or false && prevStage.stdenv.cc != "/dev/null")
188             prevStage.expand-response-params;
189           cc = prevStage.gcc-unwrapped;
190           bintools = prevStage.binutils;
191           isGNU = true;
192           libc = getLibc prevStage;
193           inherit lib;
194           inherit (prevStage) coreutils gnugrep;
195           stdenvNoCC = prevStage.ccWrapperStdenv;
196           fortify-headers = prevStage.fortify-headers;
197           runtimeShell = prevStage.ccWrapperStdenv.shell;
198         }).overrideAttrs(a: lib.optionalAttrs (prevStage.gcc-unwrapped.passthru.isXgcc or false) {
199           # This affects only `xgcc` (the compiler which compiles the final compiler).
200           postFixup = (a.postFixup or "") + ''
201             echo "--sysroot=${lib.getDev (getLibc prevStage)}" >> $out/nix-support/cc-cflags
202           '';
203         });
205         overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; };
206       };
208     in {
209       inherit config overlays;
210       stdenv = thisStdenv;
211     };
214   assert bootstrapTools.passthru.isFromBootstrapFiles or false;  # sanity check
217   ({}: {
218     __raw = true;
220     gcc-unwrapped = null;
221     binutils = null;
222     coreutils = null;
223     gnugrep = null;
224   })
226   # Build a dummy stdenv with no GCC or working fetchurl.  This is
227   # because we need a stdenv to build the GCC wrapper and fetchurl.
228   (prevStage: stageFun prevStage {
229     name = "bootstrap-stage0";
231     overrides = self: super: {
232       # We thread stage0's stdenv through under this name so downstream stages
233       # can use it for wrapping gcc too. This way, downstream stages don't need
234       # to refer to this stage directly, which violates the principle that each
235       # stage should only access the stage that came before it.
236       ccWrapperStdenv = self.stdenv;
237       # The Glibc include directory cannot have the same prefix as the
238       # GCC include directory, since GCC gets confused otherwise (it
239       # will search the Glibc headers before the GCC headers).  So
240       # create a dummy Glibc here, which will be used in the stdenv of
241       # stage1.
242       ${localSystem.libc} = self.stdenv.mkDerivation {
243         pname = "bootstrap-stage0-${localSystem.libc}";
244         strictDeps = true;
245         version = "bootstrapFiles";
246         enableParallelBuilding = true;
247         buildCommand = ''
248           mkdir -p $out
249           ln -s ${bootstrapTools}/lib $out/lib
250         '' + lib.optionalString (localSystem.libc == "glibc") ''
251           ln -s ${bootstrapTools}/include-glibc $out/include
252         '' + lib.optionalString (localSystem.libc == "musl") ''
253           ln -s ${bootstrapTools}/include-libc $out/include
254         '';
255         passthru.isFromBootstrapFiles = true;
256       };
257       gcc-unwrapped = bootstrapTools;
258       binutils = import ../../build-support/bintools-wrapper {
259         name = "bootstrap-stage0-binutils-wrapper";
260         nativeTools = false;
261         nativeLibc = false;
262         expand-response-params = "";
263         libc = getLibc self;
264         inherit lib;
265         inherit (self) stdenvNoCC coreutils gnugrep;
266         bintools = bootstrapTools;
267         runtimeShell = "${bootstrapTools}/bin/bash";
268       };
269       coreutils = bootstrapTools;
270       gnugrep = bootstrapTools;
271     };
272   })
275   # Create the first "real" standard environment.  This one consists
276   # of bootstrap tools only, and a minimal Glibc to keep the GCC
277   # configure script happy.
278   #
279   # For clarity, we only use the previous stage when specifying these
280   # stages.  So stageN should only ever have references for stage{N-1}.
281   #
282   # If we ever need to use a package from more than one stage back, we
283   # simply re-export those packages in the middle stage(s) using the
284   # overrides attribute and the inherit syntax.
285   (prevStage:
286     # previous stage0 stdenv:
287     assert isFromBootstrapFiles prevStage.binutils.bintools;
288     assert isFromBootstrapFiles prevStage."${localSystem.libc}";
289     assert isFromBootstrapFiles prevStage.gcc-unwrapped;
290     assert isFromBootstrapFiles prevStage.coreutils;
291     assert isFromBootstrapFiles prevStage.gnugrep;
292     stageFun prevStage {
293     name = "bootstrap-stage1";
295     # Rebuild binutils to use from stage2 onwards.
296     overrides = self: super: {
297       binutils-unwrapped = super.binutils-unwrapped.override {
298         enableGold = false;
299       };
300       inherit (prevStage)
301         ccWrapperStdenv
302         gcc-unwrapped coreutils gnugrep binutils;
304       ${localSystem.libc} = getLibc prevStage;
306       # A threaded perl build needs glibc/libpthread_nonshared.a,
307       # which is not included in bootstrapTools, so disable threading.
308       # This is not an issue for the final stdenv, because this perl
309       # won't be included in the final stdenv and won't be exported to
310       # top-level pkgs as an override either.
311       perl = super.perl.override { enableThreading = false; enableCrypt = false; };
312     };
314     # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
315     extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
316   })
318   # First rebuild of gcc; this is linked against all sorts of junk
319   # from the bootstrap-files, but we only care about the code that
320   # this compiler *emits*.  The `gcc` binary produced in this stage
321   # is not part of the final stdenv.
322   (prevStage:
323     assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
324     assert            isFromBootstrapFiles prevStage."${localSystem.libc}";
325     assert            isFromBootstrapFiles prevStage.gcc-unwrapped;
326     assert            isFromBootstrapFiles prevStage.coreutils;
327     assert            isFromBootstrapFiles prevStage.gnugrep;
328     assert isBuiltByBootstrapFilesCompiler prevStage.patchelf;
329     stageFun prevStage {
330       name = "bootstrap-stage-xgcc";
331       overrides = self: super: {
332         inherit (prevStage) ccWrapperStdenv coreutils gnugrep gettext bison texinfo zlib gnum4 perl patchelf;
333         ${localSystem.libc} = getLibc prevStage;
334         gmp = super.gmp.override { cxx = false; };
335         # This stage also rebuilds binutils which will of course be used only in the next stage.
336         # We inherit this until stage3, in stage4 it will be rebuilt using the adjacent bash/runtimeShell pkg.
337         # TODO(@sternenseemann): Can we already build the wrapper with the actual runtimeShell here?
338         # Historically, the wrapper didn't use runtimeShell, so the used shell had to be changed explicitly
339         # (or stdenvNoCC.shell would be used) which happened in stage4.
340         binutils = super.binutils.override {
341           runtimeShell = "${bootstrapTools}/bin/bash";
342         };
343         gcc-unwrapped =
344           (super.gcc-unwrapped.override (commonGccOverrides // {
345             # The most logical name for this package would be something like
346             # "gcc-stage1".  Unfortunately "stage" is already reserved for the
347             # layers of stdenv, so using "stage" in the name of this package
348             # would cause massive confusion.
349             #
350             # Gcc calls its "stage1" compiler `xgcc` (--disable-bootstrap results
351             # in `xgcc` being copied to $prefix/bin/gcc).  So we imitate that.
352             #
353             name = "xgcc";
355             # xgcc uses ld linked against nixpkgs' glibc and gcc built
356             # against bootstrapTools glibc. We can't allow loading
357             #   $out/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so
358             # to mix libc.so:
359             #   ...-binutils-patchelfed-ld-2.40/bin/ld: ...-xgcc-13.0.0/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so:
360             #     error loading plugin: ...-bootstrap-tools/lib/libpthread.so.0: undefined symbol: __libc_vfork, version GLIBC_PRIVATE
361             enableLTO = false;
362           })).overrideAttrs (a: {
364             # This signals to cc-wrapper (as overridden above in this file) to add `--sysroot`
365             # to `$out/nix-support/cc-cflags`.
366             passthru = a.passthru // { isXgcc = true; };
368             # Gcc will look for the C library headers in
369             #
370             #    ${with_build_sysroot}${native_system_header_dir}
371             #
372             # The ordinary gcc expression sets `--with-build-sysroot=/` and sets
373             # `native-system-header-dir` to `"${lib.getDev stdenv.cc.libc}/include`.
374             #
375             # Unfortunately the value of "--with-native-system-header-dir=" gets "burned in" to the
376             # compiler, and it is quite difficult to get the compiler to change or ignore it
377             # afterwards.  On the other hand, the `sysroot` is very easy to change; you can just pass
378             # a `--sysroot` flag to `gcc`.
379             #
380             # So we override the expression to remove the default settings for these flags, and
381             # replace them such that the concatenated value will be the same as before, but we split
382             # the value between the two variables differently: `--native-system-header-dir=/include`,
383             # and `--with-build-sysroot=${lib.getDev stdenv.cc.libc}`.
384             #
385             configureFlags = (a.configureFlags or []) ++ [
386               "--with-native-system-header-dir=/include"
387               "--with-build-sysroot=${lib.getDev self.stdenv.cc.libc}"
388             ];
390             # This is a separate phase because gcc assembles its phase scripts
391             # in bash instead of nix (we should fix that).
392             preFixupPhases = (a.preFixupPhases or []) ++ [ "preFixupXgccPhase" ];
394             # This is needed to prevent "error: cycle detected in build of '...-xgcc-....drv'
395             # in the references of output 'lib' from output 'out'"
396             preFixupXgccPhase = ''
397               find $lib/lib/ -name \*.so\* -exec patchelf --shrink-rpath {} \; || true
398             '';
399           });
400       };
402       # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
403       extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
404     })
406   # 2nd stdenv that contains our own rebuilt binutils and is used for
407   # compiling our own Glibc.
408   #
409   (prevStage:
410     # previous stage1 stdenv:
411     assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
412     assert            isFromBootstrapFiles prevStage."${localSystem.libc}";
413     assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
414     assert            isFromBootstrapFiles prevStage.coreutils;
415     assert            isFromBootstrapFiles prevStage.gnugrep;
416     assert isBuiltByBootstrapFilesCompiler prevStage.patchelf;
417     stageFun prevStage {
418     name = "bootstrap-stage2";
420     overrides = self: super: {
421       inherit (prevStage)
422         ccWrapperStdenv gettext
423         gcc-unwrapped coreutils gnugrep
424         perl gnum4 bison texinfo which;
425       dejagnu = super.dejagnu.overrideAttrs (a: { doCheck = false; } );
427       # We need libidn2 and its dependency libunistring as glibc dependency.
428       # To avoid the cycle, we build against bootstrap libc, nuke references,
429       # and use the result as input for our final glibc.  We also pass this pair
430       # through, so the final package-set uses exactly the same builds.
431       libunistring = super.libunistring.overrideAttrs (attrs: {
432         postFixup = attrs.postFixup or "" + ''
433           ${self.nukeReferences}/bin/nuke-refs "$out"/lib/lib*.so.*.*
434         '';
435         # Apparently iconv won't work with bootstrap glibc, but it will be used
436         # with glibc built later where we keep *this* build of libunistring,
437         # so we need to trick it into supporting libiconv.
438         env = attrs.env or {} // { am_cv_func_iconv_works = "yes"; };
439       });
440       libidn2 = super.libidn2.overrideAttrs (attrs: {
441         postFixup = attrs.postFixup or "" + ''
442           ${self.nukeReferences}/bin/nuke-refs -e '${lib.getLib self.libunistring}' \
443             "$out"/lib/lib*.so.*.*
444         '';
445       });
447       # This also contains the full, dynamically linked, final Glibc.
448       binutils = prevStage.binutils.override {
449         # Rewrap the binutils with the new glibc, so both the next
450         # stage's wrappers use it.
451         libc = getLibc self;
453         # Unfortunately, when building gcc in the next stage, its LTO plugin
454         # would use the final libc but `ld` would use the bootstrap one,
455         # and that can fail to load.  Therefore we upgrade `ld` to use newer libc;
456         # apparently the interpreter needs to match libc, too.
457         bintools = self.stdenvNoCC.mkDerivation {
458           pname = prevStage.bintools.bintools.pname + "-patchelfed-ld";
459           inherit (prevStage.bintools.bintools) version;
460           passthru = { inherit (prevStage.bintools.passthru) isFromBootstrapFiles; };
461           enableParallelBuilding = true;
462           dontUnpack = true;
463           dontBuild = true;
464           strictDeps = true;
465           # We wouldn't need to *copy* all, but it's easier and the result is temporary anyway.
466           installPhase = ''
467             mkdir -p "$out"/bin
468             cp -a '${prevStage.bintools.bintools}'/bin/* "$out"/bin/
469             chmod +w "$out"/bin/ld.bfd
470             patchelf --set-interpreter '${getLibc self}'/lib/ld*.so.? \
471               --set-rpath "${getLibc self}/lib:$(patchelf --print-rpath "$out"/bin/ld.bfd)" \
472               "$out"/bin/ld.bfd
473           '';
474         };
475       };
477       # TODO(amjoseph): It is not yet entirely clear why this is necessary.
478       # Something strange is going on with xgcc and libstdc++ on pkgsMusl.
479       patchelf = super.patchelf.overrideAttrs(previousAttrs:
480         lib.optionalAttrs super.stdenv.hostPlatform.isMusl {
481           NIX_CFLAGS_COMPILE = (previousAttrs.NIX_CFLAGS_COMPILE or "") + " -static-libstdc++";
482         });
484     };
486     # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
487     # `libtool` comes with obsolete config.sub/config.guess that don't recognize Risc-V.
488     extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
489   })
492   # Construct a third stdenv identical to the 2nd, except that this
493   # one uses the rebuilt Glibc from stage2.  It still uses the recent
494   # binutils and rest of the bootstrap tools, including GCC.
495   (prevStage:
496     # previous stage2 stdenv:
497     assert        isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
498     assert        isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
499     assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
500     assert            isFromBootstrapFiles prevStage.coreutils;
501     assert            isFromBootstrapFiles prevStage.gnugrep;
502     assert        isBuiltByNixpkgsCompiler prevStage.patchelf;
503     assert lib.all isBuiltByNixpkgsCompiler [ prevStage.gmp prevStage.isl_0_20 prevStage.libmpc prevStage.mpfr ];
504     stageFun prevStage {
505     name = "bootstrap-stage3";
507     overrides = self: super: rec {
508       inherit (prevStage)
509         ccWrapperStdenv
510         binutils coreutils gnugrep gettext
511         perl patchelf linuxHeaders gnum4 bison libidn2 libunistring libxcrypt;
512         # We build a special copy of libgmp which doesn't use libstdc++, because
513         # xgcc++'s libstdc++ references the bootstrap-files (which is what
514         # compiles xgcc++).
515         gmp = super.gmp.override { cxx = false; };
516       } // {
517       ${localSystem.libc} = getLibc prevStage;
518       gcc-unwrapped = (super.gcc-unwrapped.override (commonGccOverrides // {
519         inherit (prevStage) which;
520       }
521       )).overrideAttrs (a: {
522         # so we can add them to allowedRequisites below
523         passthru = a.passthru // { inherit (self) gmp mpfr libmpc isl; };
524       });
525     };
526     extraNativeBuildInputs = [
527       prevStage.patchelf
528       # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
529       prevStage.updateAutotoolsGnuConfigScriptsHook
530     ];
531   })
534   # Construct a fourth stdenv that uses the new GCC.  But coreutils is
535   # still from the bootstrap tools.
536   #
537   (prevStage:
538     # previous stage3 stdenv:
539     assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
540     assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
541     assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
542     assert     isFromBootstrapFiles prevStage.coreutils;
543     assert     isFromBootstrapFiles prevStage.gnugrep;
544     assert isBuiltByNixpkgsCompiler prevStage.patchelf;
545     stageFun prevStage {
546     name = "bootstrap-stage4";
548     overrides = self: super: {
549       # Zlib has to be inherited and not rebuilt in this stage,
550       # because gcc (since JAR support) already depends on zlib, and
551       # then if we already have a zlib we want to use that for the
552       # other purposes (binutils and top-level pkgs) too.
553       inherit (prevStage) gettext gnum4 bison perl texinfo zlib linuxHeaders libidn2 libunistring;
554       ${localSystem.libc} = getLibc prevStage;
555       # Since this is the first fresh build of binutils since stage2, our own runtimeShell will be used.
556       binutils = super.binutils.override {
557         # Build expand-response-params with last stage like below
558         inherit (prevStage) expand-response-params;
559       };
561       # To allow users' overrides inhibit dependencies too heavy for
562       # bootstrap, like guile: https://github.com/NixOS/nixpkgs/issues/181188
563       gnumake = super.gnumake.override { inBootstrap = true; };
565       gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
566         nativeTools = false;
567         nativeLibc = false;
568         isGNU = true;
569         inherit (prevStage) expand-response-params;
570         cc = prevStage.gcc-unwrapped;
571         bintools = self.binutils;
572         libc = getLibc self;
573         inherit lib;
574         inherit (self) stdenvNoCC coreutils gnugrep runtimeShell;
575         fortify-headers = self.fortify-headers;
576       };
577     };
578     extraNativeBuildInputs = [
579       prevStage.patchelf prevStage.xz
580       # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
581       prevStage.updateAutotoolsGnuConfigScriptsHook
582     ];
583   })
585   # Construct the final stdenv.  It uses the Glibc and GCC, and adds
586   # in a new binutils that doesn't depend on bootstrap-tools, as well
587   # as dynamically linked versions of all other tools.
588   #
589   # When updating stdenvLinux, make sure that the result has no
590   # dependency (`nix-store -qR') on bootstrapTools or the first
591   # binutils built.
592   #
593   (prevStage:
594     # previous stage4 stdenv; see stage3 comment regarding gcc,
595     # which applies here as well.
596     assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
597     assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
598     assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
599     assert isBuiltByNixpkgsCompiler prevStage.coreutils;
600     assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
601     assert isBuiltByNixpkgsCompiler prevStage.patchelf;
602     {
603     inherit config overlays;
604     stdenv = import ../generic rec {
605       name = "stdenv-linux";
607       buildPlatform = localSystem;
608       hostPlatform = localSystem;
609       targetPlatform = localSystem;
610       inherit config;
612       preHook = commonPreHook;
614       initialPath =
615         ((import ../generic/common-path.nix) {pkgs = prevStage;});
617       extraNativeBuildInputs = [
618         prevStage.patchelf
619         # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
620         prevStage.updateAutotoolsGnuConfigScriptsHook
621       ];
623       cc = prevStage.gcc;
625       shell = cc.shell;
627       inherit (prevStage.stdenv) fetchurlBoot;
629       extraAttrs = {
630         inherit bootstrapTools;
631         shellPackage = prevStage.bash;
632       };
634       disallowedRequisites = [ bootstrapTools.out ];
636       # Mainly avoid reference to bootstrap tools
637       allowedRequisites = let
638         inherit (prevStage) gzip bzip2 xz zlib bash binutils coreutils diffutils findutils
639           gawk gmp gnumake gnused gnutar gnugrep gnupatch patchelf ed file glibc
640           attr acl libidn2 libunistring linuxHeaders gcc fortify-headers gcc-unwrapped
641           ;
642       in
643         # Simple executable tools
644         lib.concatMap (p: [ (lib.getBin p) (lib.getLib p) ]) [
645             gzip bzip2 xz bash binutils.bintools coreutils diffutils findutils
646             gawk gmp gnumake gnused gnutar gnugrep gnupatch patchelf ed file
647           ]
648         # Library dependencies
649         ++ map lib.getLib [ attr acl zlib gnugrep.pcre2 libidn2 libunistring ]
650         # More complicated cases
651         ++ (map (x: lib.getOutput x (getLibc prevStage)) [ "out" "dev" "bin" ] )
652         ++  [ linuxHeaders # propagated from .dev
653               binutils gcc gcc.cc gcc.cc.lib
654               gcc.expand-response-params # != (prevStage.)expand-response-params
655               gcc.cc.libgcc glibc.passthru.libgcc
656           ]
657         ++ lib.optionals (localSystem.libc == "musl") [ fortify-headers ]
658         ++ [ prevStage.updateAutotoolsGnuConfigScriptsHook prevStage.gnu-config ]
659         ++ [
660           gcc-unwrapped.gmp gcc-unwrapped.libmpc gcc-unwrapped.mpfr gcc-unwrapped.isl
661         ]
662       ;
664       overrides = self: super: {
665         inherit (prevStage)
666           gzip bzip2 xz bash coreutils diffutils findutils gawk
667           gnused gnutar gnugrep gnupatch patchelf
668           attr acl zlib libunistring;
669         inherit (prevStage.gnugrep) pcre2;
670         ${localSystem.libc} = getLibc prevStage;
672         # Hack: avoid libidn2.{bin,dev} referencing bootstrap tools.  There's a logical cycle.
673         libidn2 = import ../../development/libraries/libidn2/no-bootstrap-reference.nix {
674           inherit lib;
675           inherit (prevStage) libidn2;
676           inherit (self) stdenv runCommandLocal patchelf libunistring;
677         };
679         gnumake = super.gnumake.override { inBootstrap = false; };
680       } // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
681         # Need to get rid of these when cross-compiling.
682         inherit (prevStage) binutils binutils-unwrapped;
683         gcc = cc;
684       };
685     };
686   })
688   # This "no-op" stage is just a place to put the assertions about stage5.
689   (prevStage:
690     # previous stage5 stdenv; see stage3 comment regarding gcc,
691     # which applies here as well.
692     assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
693     assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
694     assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
695     assert isBuiltByNixpkgsCompiler prevStage.coreutils;
696     assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
697     assert isBuiltByNixpkgsCompiler prevStage.patchelf;
698     { inherit (prevStage) config overlays stdenv; })