Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
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.
6#
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).
10#
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).
17#
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).
22#
23# Stages are described below along with their definitions.
24#
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.
32#
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
38#
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
46#
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";
52#
53# For a TUI (rather than CLI) view, you can use:
54#
55# $ nix-tree --derivation $(nix-instantiate -A stdenv)
56{
57 lib,
58 localSystem,
59 crossSystem,
60 config,
61 overlays,
62 crossOverlays ? [ ],
63
64 bootstrapFiles ?
65 let
66 table = {
67 glibc = {
68 i686-linux = import ./bootstrap-files/i686-unknown-linux-gnu.nix;
69 x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-gnu.nix;
70 armv5tel-linux = import ./bootstrap-files/armv5tel-unknown-linux-gnueabi.nix;
71 armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-gnueabihf.nix;
72 armv7l-linux = import ./bootstrap-files/armv7l-unknown-linux-gnueabihf.nix;
73 aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-gnu.nix;
74 mipsel-linux = import ./bootstrap-files/mipsel-unknown-linux-gnu.nix;
75 mips64el-linux = import (
76 if localSystem.isMips64n32 then
77 ./bootstrap-files/mips64el-unknown-linux-gnuabin32.nix
78 else
79 ./bootstrap-files/mips64el-unknown-linux-gnuabi64.nix
80 );
81 powerpc64-linux = import ./bootstrap-files/powerpc64-unknown-linux-gnuabielfv2.nix;
82 powerpc64le-linux = import ./bootstrap-files/powerpc64le-unknown-linux-gnu.nix;
83 riscv64-linux = import ./bootstrap-files/riscv64-unknown-linux-gnu.nix;
84 s390x-linux = import ./bootstrap-files/s390x-unknown-linux-gnu.nix;
85 loongarch64-linux = import ./bootstrap-files/loongarch64-unknown-linux-gnu.nix;
86 };
87 musl = {
88 aarch64-linux = import ./bootstrap-files/aarch64-unknown-linux-musl.nix;
89 armv6l-linux = import ./bootstrap-files/armv6l-unknown-linux-musleabihf.nix;
90 x86_64-linux = import ./bootstrap-files/x86_64-unknown-linux-musl.nix;
91 };
92 };
93
94 # Try to find an architecture compatible with our current system. We
95 # just try every bootstrap we’ve got and test to see if it is
96 # compatible with or current architecture.
97 getCompatibleTools = lib.foldl (
98 v: system:
99 if v != null then
100 v
101 else if localSystem.canExecute (lib.systems.elaborate { inherit system; }) then
102 archLookupTable.${system}
103 else
104 null
105 ) null (lib.attrNames archLookupTable);
106
107 archLookupTable = table.${localSystem.libc} or (throw "unsupported libc for the pure Linux stdenv");
108 files =
109 archLookupTable.${localSystem.system} or (
110 if getCompatibleTools != null then
111 getCompatibleTools
112 else
113 (throw "unsupported platform for the pure Linux stdenv")
114 );
115 in
116 (config.replaceBootstrapFiles or lib.id) files,
117}:
118
119assert crossSystem == localSystem;
120
121let
122 inherit (localSystem) system;
123
124 isFromNixpkgs = pkg: !(isFromBootstrapFiles pkg);
125 isFromBootstrapFiles = pkg: pkg.passthru.isFromBootstrapFiles or false;
126 isBuiltByNixpkgsCompiler = pkg: isFromNixpkgs pkg && isFromNixpkgs pkg.stdenv.cc.cc;
127 isBuiltByBootstrapFilesCompiler = pkg: isFromNixpkgs pkg && isFromBootstrapFiles pkg.stdenv.cc.cc;
128
129 commonGccOverrides = {
130 # Use a deterministically built compiler
131 # see https://github.com/NixOS/nixpkgs/issues/108475 for context
132 reproducibleBuild = true;
133 profiledCompiler = false;
134
135 # It appears that libcc1 (which is not a g++ plugin; it is a gdb plugin) gets linked against
136 # the libstdc++ from the compiler that *built* g++, not the libstdc++ which was just built.
137 # This causes a reference chain from stdenv to the bootstrapFiles:
138 #
139 # stdenv -> gcc-lib -> xgcc-lib -> bootstrapFiles
140 #
141 disableGdbPlugin = true;
142 };
143
144 commonPreHook = ''
145 export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
146 export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
147 '';
148
149 # The bootstrap process proceeds in several steps.
150
151 # Create a standard environment by downloading pre-built binaries of
152 # coreutils, GCC, etc.
153
154 # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...).
155 bootstrapTools = import ./bootstrap-tools {
156 inherit (localSystem) libc system;
157 inherit lib bootstrapFiles config;
158 isFromBootstrapFiles = true;
159 };
160
161 # This function builds the various standard environments used during
162 # the bootstrap. In all stages, we build an stdenv and the package
163 # set that can be built with that stdenv.
164 stageFun =
165 prevStage:
166 {
167 name,
168 overrides ? (self: super: { }),
169 extraNativeBuildInputs ? [ ],
170 }:
171
172 let
173
174 thisStdenv = import ../generic {
175 name = "${name}-stdenv-linux";
176 buildPlatform = localSystem;
177 hostPlatform = localSystem;
178 targetPlatform = localSystem;
179 inherit config extraNativeBuildInputs;
180 preHook = ''
181 # Don't patch #!/interpreter because it leads to retained
182 # dependencies on the bootstrapTools in the final stdenv.
183 dontPatchShebangs=1
184 ${commonPreHook}
185 '';
186 shell = "${bootstrapTools}/bin/bash";
187 initialPath = [ bootstrapTools ];
188
189 fetchurlBoot = import ../../build-support/fetchurl/boot.nix {
190 inherit system;
191 inherit (config) rewriteURL;
192 };
193
194 cc =
195 if prevStage.gcc-unwrapped == null then
196 null
197 else
198 (lib.makeOverridable (import ../../build-support/cc-wrapper) {
199 name = "${name}-gcc-wrapper";
200 nativeTools = false;
201 nativeLibc = false;
202 expand-response-params = lib.optionalString (
203 prevStage.stdenv.hasCC or false && prevStage.stdenv.cc != "/dev/null"
204 ) prevStage.expand-response-params;
205 cc = prevStage.gcc-unwrapped;
206 bintools = prevStage.binutils;
207 isGNU = true;
208 inherit (prevStage) libc;
209 inherit lib;
210 inherit (prevStage) coreutils gnugrep;
211 stdenvNoCC = prevStage.ccWrapperStdenv;
212 fortify-headers = prevStage.fortify-headers;
213 runtimeShell = prevStage.ccWrapperStdenv.shell;
214 }).overrideAttrs
215 (
216 a:
217 lib.optionalAttrs (prevStage.gcc-unwrapped.passthru.isXgcc or false) {
218 # This affects only `xgcc` (the compiler which compiles the final compiler).
219 postFixup = (a.postFixup or "") + ''
220 echo "--sysroot=${lib.getDev prevStage.libc}" >> $out/nix-support/cc-cflags
221 '';
222 }
223 );
224
225 overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; };
226 };
227
228 in
229 {
230 inherit config overlays;
231 stdenv = thisStdenv;
232 };
233
234in
235assert bootstrapTools.passthru.isFromBootstrapFiles or false; # sanity check
236[
237
238 (
239 { }:
240 {
241 __raw = true;
242
243 gcc-unwrapped = null;
244 binutils = null;
245 coreutils = null;
246 gnugrep = null;
247 }
248 )
249
250 # Build a dummy stdenv with no GCC or working fetchurl. This is
251 # because we need a stdenv to build the GCC wrapper and fetchurl.
252 (
253 prevStage:
254 stageFun prevStage {
255 name = "bootstrap-stage0";
256
257 overrides = self: super: {
258 # We thread stage0's stdenv through under this name so downstream stages
259 # can use it for wrapping gcc too. This way, downstream stages don't need
260 # to refer to this stage directly, which violates the principle that each
261 # stage should only access the stage that came before it.
262 ccWrapperStdenv = self.stdenv;
263 # The Glibc include directory cannot have the same prefix as the
264 # GCC include directory, since GCC gets confused otherwise (it
265 # will search the Glibc headers before the GCC headers). So
266 # create a dummy Glibc here, which will be used in the stdenv of
267 # stage1.
268 ${localSystem.libc} = self.stdenv.mkDerivation {
269 pname = "bootstrap-stage0-${localSystem.libc}";
270 strictDeps = true;
271 version = "bootstrapFiles";
272 enableParallelBuilding = true;
273 buildCommand = ''
274 mkdir -p $out
275 ln -s ${bootstrapTools}/lib $out/lib
276 ''
277 + lib.optionalString (localSystem.libc == "glibc") ''
278 ln -s ${bootstrapTools}/include-glibc $out/include
279 ''
280 + lib.optionalString (localSystem.libc == "musl") ''
281 ln -s ${bootstrapTools}/include-libc $out/include
282 '';
283 passthru.isFromBootstrapFiles = true;
284 };
285 gcc-unwrapped = bootstrapTools;
286 binutils = import ../../build-support/bintools-wrapper {
287 name = "bootstrap-stage0-binutils-wrapper";
288 nativeTools = false;
289 nativeLibc = false;
290 expand-response-params = "";
291 inherit lib;
292 inherit (self)
293 stdenvNoCC
294 coreutils
295 gnugrep
296 libc
297 ;
298 bintools = bootstrapTools;
299 runtimeShell = "${bootstrapTools}/bin/bash";
300 };
301 coreutils = bootstrapTools;
302 gnugrep = bootstrapTools;
303 };
304 }
305 )
306
307 # Create the first "real" standard environment. This one consists
308 # of bootstrap tools only, and a minimal Glibc to keep the GCC
309 # configure script happy.
310 #
311 # For clarity, we only use the previous stage when specifying these
312 # stages. So stageN should only ever have references for stage{N-1}.
313 #
314 # If we ever need to use a package from more than one stage back, we
315 # simply re-export those packages in the middle stage(s) using the
316 # overrides attribute and the inherit syntax.
317 (
318 prevStage:
319 # previous stage0 stdenv:
320 assert isFromBootstrapFiles prevStage.binutils.bintools;
321 assert isFromBootstrapFiles prevStage."${localSystem.libc}";
322 assert isFromBootstrapFiles prevStage.libc;
323 assert isFromBootstrapFiles prevStage.gcc-unwrapped;
324 assert isFromBootstrapFiles prevStage.coreutils;
325 assert isFromBootstrapFiles prevStage.gnugrep;
326 stageFun prevStage {
327 name = "bootstrap-stage1";
328
329 # Rebuild binutils to use from stage2 onwards.
330 overrides = self: super: {
331 binutils-unwrapped = super.binutils-unwrapped.override {
332 enableGold = false;
333 };
334 inherit (prevStage)
335 ccWrapperStdenv
336 gcc-unwrapped
337 coreutils
338 gnugrep
339 binutils
340 ;
341
342 ${localSystem.libc} = prevStage.${localSystem.libc};
343
344 # A threaded perl build needs glibc/libpthread_nonshared.a,
345 # which is not included in bootstrapTools, so disable threading.
346 # This is not an issue for the final stdenv, because this perl
347 # won't be included in the final stdenv and won't be exported to
348 # top-level pkgs as an override either.
349 perl = super.perl.override {
350 enableThreading = false;
351 enableCrypt = false;
352 };
353
354 # Let gettext "checking for working iconv" success without trying
355 # to convert between UTF-8 and EUC-JP which doesn't work here
356 # because of missing locale and gconv, same for libunistring below
357 gettext = super.gettext.overrideAttrs (attrs: {
358 env = attrs.env or { } // {
359 am_cv_func_iconv_works = "yes";
360 };
361 });
362 };
363
364 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
365 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
366 }
367 )
368
369 # First rebuild of gcc; this is linked against all sorts of junk
370 # from the bootstrap-files, but we only care about the code that
371 # this compiler *emits*. The `gcc` binary produced in this stage
372 # is not part of the final stdenv.
373 (
374 prevStage:
375 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
376 assert isFromBootstrapFiles prevStage."${localSystem.libc}";
377 assert isFromBootstrapFiles prevStage.libc;
378 assert isFromBootstrapFiles prevStage.gcc-unwrapped;
379 assert isFromBootstrapFiles prevStage.coreutils;
380 assert isFromBootstrapFiles prevStage.gnugrep;
381 assert isBuiltByBootstrapFilesCompiler prevStage.patchelf;
382 stageFun prevStage {
383 name = "bootstrap-stage-xgcc";
384 overrides = self: super: {
385 inherit (prevStage)
386 ccWrapperStdenv
387 coreutils
388 gnugrep
389 gettext
390 bison
391 texinfo
392 zlib
393 gnum4
394 perl
395 patchelf
396 ;
397 ${localSystem.libc} = prevStage.${localSystem.libc};
398 gmp = super.gmp.override { cxx = false; };
399 # This stage also rebuilds binutils which will of course be used only in the next stage.
400 # We inherit this until stage3, in stage4 it will be rebuilt using the adjacent bash/runtimeShell pkg.
401 # TODO(@sternenseemann): Can we already build the wrapper with the actual runtimeShell here?
402 # Historically, the wrapper didn't use runtimeShell, so the used shell had to be changed explicitly
403 # (or stdenvNoCC.shell would be used) which happened in stage4.
404 binutils = super.binutils.override {
405 runtimeShell = "${bootstrapTools}/bin/bash";
406 };
407 gcc-unwrapped =
408 (super.gcc-unwrapped.override (
409 commonGccOverrides
410 // {
411 # The most logical name for this package would be something like
412 # "gcc-stage1". Unfortunately "stage" is already reserved for the
413 # layers of stdenv, so using "stage" in the name of this package
414 # would cause massive confusion.
415 #
416 # Gcc calls its "stage1" compiler `xgcc` (--disable-bootstrap results
417 # in `xgcc` being copied to $prefix/bin/gcc). So we imitate that.
418 #
419 name = "xgcc";
420
421 # xgcc uses ld linked against nixpkgs' glibc and gcc built
422 # against bootstrapTools glibc. We can't allow loading
423 # $out/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so
424 # to mix libc.so:
425 # ...-binutils-patchelfed-ld-2.40/bin/ld: ...-xgcc-13.0.0/libexec/gcc/x86_64-unknown-linux-gnu/13.0.1/liblto_plugin.so:
426 # error loading plugin: ...-bootstrap-tools/lib/libpthread.so.0: undefined symbol: __libc_vfork, version GLIBC_PRIVATE
427 enableLTO = false;
428 }
429 )).overrideAttrs
430 (a: {
431
432 # This signals to cc-wrapper (as overridden above in this file) to add `--sysroot`
433 # to `$out/nix-support/cc-cflags`.
434 passthru = a.passthru // {
435 isXgcc = true;
436 };
437
438 # Gcc will look for the C library headers in
439 #
440 # ${with_build_sysroot}${native_system_header_dir}
441 #
442 # The ordinary gcc expression sets `--with-build-sysroot=/` and sets
443 # `native-system-header-dir` to `"${lib.getDev stdenv.cc.libc}/include`.
444 #
445 # Unfortunately the value of "--with-native-system-header-dir=" gets "burned in" to the
446 # compiler, and it is quite difficult to get the compiler to change or ignore it
447 # afterwards. On the other hand, the `sysroot` is very easy to change; you can just pass
448 # a `--sysroot` flag to `gcc`.
449 #
450 # So we override the expression to remove the default settings for these flags, and
451 # replace them such that the concatenated value will be the same as before, but we split
452 # the value between the two variables differently: `--native-system-header-dir=/include`,
453 # and `--with-build-sysroot=${lib.getDev stdenv.cc.libc}`.
454 #
455 configureFlags = (a.configureFlags or [ ]) ++ [
456 "--with-native-system-header-dir=/include"
457 "--with-build-sysroot=${lib.getDev self.stdenv.cc.libc}"
458 # Don't assume that `gettext` was built with iconv support, since we don't have
459 # our own `glibc` yet.
460 "--disable-nls"
461 ];
462
463 # This is a separate phase because gcc assembles its phase scripts
464 # in bash instead of nix (we should fix that).
465 preFixupPhases = (a.preFixupPhases or [ ]) ++ [ "preFixupXgccPhase" ];
466
467 # This is needed to prevent "error: cycle detected in build of '...-xgcc-....drv'
468 # in the references of output 'lib' from output 'out'"
469 preFixupXgccPhase = ''
470 find $lib/lib/ -name \*.so\* -exec patchelf --shrink-rpath {} \; || true
471 '';
472 });
473 };
474
475 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
476 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
477 }
478 )
479
480 # 2nd stdenv that contains our own rebuilt binutils and is used for
481 # compiling our own Glibc.
482 #
483 (
484 prevStage:
485 # previous stage1 stdenv:
486 assert isBuiltByBootstrapFilesCompiler prevStage.binutils-unwrapped;
487 assert isFromBootstrapFiles prevStage."${localSystem.libc}";
488 assert isFromBootstrapFiles prevStage.libc;
489 assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
490 assert isFromBootstrapFiles prevStage.coreutils;
491 assert isFromBootstrapFiles prevStage.gnugrep;
492 assert isBuiltByBootstrapFilesCompiler prevStage.patchelf;
493 stageFun prevStage {
494 name = "bootstrap-stage2";
495
496 overrides = self: super: {
497 inherit (prevStage)
498 ccWrapperStdenv
499 gettext
500 gcc-unwrapped
501 coreutils
502 gnugrep
503 perl
504 gnum4
505 bison
506 texinfo
507 which
508 ;
509 dejagnu = super.dejagnu.overrideAttrs (a: {
510 doCheck = false;
511 });
512
513 # Avoids infinite recursion, as this is in the build-time dependencies of libc.
514 libiconv = self.libcIconv prevStage.libc;
515
516 # We need libidn2 and its dependency libunistring as glibc dependency.
517 # To avoid the cycle, we build against bootstrap libc, nuke references,
518 # and use the result as input for our final glibc. We also pass this pair
519 # through, so the final package-set uses exactly the same builds.
520 libunistring = super.libunistring.overrideAttrs (attrs: {
521 postFixup = attrs.postFixup or "" + ''
522 ${self.nukeReferences}/bin/nuke-refs "$out"/lib/lib*.so.*.*
523 '';
524 # Apparently iconv won't work with bootstrap glibc, but it will be used
525 # with glibc built later where we keep *this* build of libunistring,
526 # so we need to trick it into supporting libiconv.
527 env = attrs.env or { } // {
528 am_cv_func_iconv_works = "yes";
529 };
530 });
531 libidn2 = super.libidn2.overrideAttrs (attrs: {
532 postFixup = attrs.postFixup or "" + ''
533 ${self.nukeReferences}/bin/nuke-refs -e '${lib.getLib self.libunistring}' \
534 "$out"/lib/lib*.so.*.*
535 '';
536 });
537
538 # This also contains the full, dynamically linked, final Glibc.
539 binutils = prevStage.binutils.override {
540 # Rewrap the binutils with the new glibc, so both the next
541 # stage's wrappers use it.
542 inherit (self) libc;
543
544 # Unfortunately, when building gcc in the next stage, its LTO plugin
545 # would use the final libc but `ld` would use the bootstrap one,
546 # and that can fail to load. Therefore we upgrade `ld` to use newer libc;
547 # apparently the interpreter needs to match libc, too.
548 bintools = self.stdenvNoCC.mkDerivation {
549 pname = prevStage.bintools.bintools.pname + "-patchelfed-ld";
550 inherit (prevStage.bintools.bintools) version;
551 passthru = { inherit (prevStage.bintools.passthru) isFromBootstrapFiles; };
552 enableParallelBuilding = true;
553 dontUnpack = true;
554 dontBuild = true;
555 strictDeps = true;
556 # We wouldn't need to *copy* all, but it's easier and the result is temporary anyway.
557 installPhase = ''
558 mkdir -p "$out"/bin
559 cp -a '${prevStage.bintools.bintools}'/bin/* "$out"/bin/
560 chmod +w "$out"/bin/ld.bfd
561 patchelf --set-interpreter '${self.libc}'/lib/ld*.so.? \
562 --set-rpath "${self.libc}/lib:$(patchelf --print-rpath "$out"/bin/ld.bfd)" \
563 "$out"/bin/ld.bfd
564 '';
565 };
566 };
567
568 # TODO(amjoseph): It is not yet entirely clear why this is necessary.
569 # Something strange is going on with xgcc and libstdc++ on pkgsMusl.
570 patchelf = super.patchelf.overrideAttrs (
571 previousAttrs:
572 lib.optionalAttrs super.stdenv.hostPlatform.isMusl {
573 NIX_CFLAGS_COMPILE = (previousAttrs.NIX_CFLAGS_COMPILE or "") + " -static-libstdc++";
574 }
575 );
576
577 };
578
579 # `gettext` comes with obsolete config.sub/config.guess that don't recognize LoongArch64.
580 # `libtool` comes with obsolete config.sub/config.guess that don't recognize Risc-V.
581 extraNativeBuildInputs = [ prevStage.updateAutotoolsGnuConfigScriptsHook ];
582 }
583 )
584
585 # Construct a third stdenv identical to the 2nd, except that this
586 # one uses the rebuilt Glibc from stage2. It still uses the recent
587 # binutils and rest of the bootstrap tools, including GCC.
588 (
589 prevStage:
590 # previous stage2 stdenv:
591 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
592 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
593 assert isBuiltByNixpkgsCompiler prevStage.libc;
594 assert isBuiltByBootstrapFilesCompiler prevStage.gcc-unwrapped;
595 assert isFromBootstrapFiles prevStage.coreutils;
596 assert isFromBootstrapFiles prevStage.gnugrep;
597 assert isBuiltByNixpkgsCompiler prevStage.patchelf;
598 assert lib.all isBuiltByNixpkgsCompiler [
599 prevStage.gmp
600 prevStage.isl_0_20
601 prevStage.libmpc
602 prevStage.mpfr
603 ];
604 stageFun prevStage {
605 name = "bootstrap-stage3";
606
607 overrides =
608 self: super:
609 {
610 inherit (prevStage)
611 ccWrapperStdenv
612 binutils
613 coreutils
614 gnugrep
615 perl
616 patchelf
617 linuxHeaders
618 gnum4
619 bison
620 libidn2
621 libunistring
622 libxcrypt
623 ;
624 # We build a special copy of libgmp which doesn't use libstdc++, because
625 # xgcc++'s libstdc++ references the bootstrap-files (which is what
626 # compiles xgcc++).
627 gmp = super.gmp.override { cxx = false; };
628 }
629 // {
630 ${localSystem.libc} = prevStage.${localSystem.libc};
631 gcc-unwrapped =
632 (super.gcc-unwrapped.override (
633 commonGccOverrides
634 // {
635 inherit (prevStage) which;
636 }
637 )).overrideAttrs
638 (a: {
639 # so we can add them to allowedRequisites below
640 passthru = a.passthru // {
641 inherit (self)
642 gmp
643 mpfr
644 libmpc
645 isl
646 ;
647 };
648 });
649 };
650 extraNativeBuildInputs = [
651 prevStage.patchelf
652 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
653 prevStage.updateAutotoolsGnuConfigScriptsHook
654 ];
655 }
656 )
657
658 # Construct a fourth stdenv that uses the new GCC. But coreutils is
659 # still from the bootstrap tools.
660 #
661 (
662 prevStage:
663 # previous stage3 stdenv:
664 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
665 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
666 assert isBuiltByNixpkgsCompiler prevStage.libc;
667 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
668 assert isFromBootstrapFiles prevStage.coreutils;
669 assert isFromBootstrapFiles prevStage.gnugrep;
670 assert isBuiltByNixpkgsCompiler prevStage.patchelf;
671 stageFun prevStage {
672 name = "bootstrap-stage4";
673
674 overrides = self: super: {
675 # Zlib has to be inherited and not rebuilt in this stage,
676 # because gcc (since JAR support) already depends on zlib, and
677 # then if we already have a zlib we want to use that for the
678 # other purposes (binutils and top-level pkgs) too.
679 inherit (prevStage)
680 gettext
681 gnum4
682 bison
683 perl
684 texinfo
685 zlib
686 linuxHeaders
687 libidn2
688 libunistring
689 ;
690 ${localSystem.libc} = prevStage.${localSystem.libc};
691 # Since this is the first fresh build of binutils since stage2, our own runtimeShell will be used.
692 binutils = super.binutils.override {
693 # Build expand-response-params with last stage like below
694 inherit (prevStage) expand-response-params;
695 };
696
697 # To allow users' overrides inhibit dependencies too heavy for
698 # bootstrap, like guile: https://github.com/NixOS/nixpkgs/issues/181188
699 gnumake = super.gnumake.override { inBootstrap = true; };
700
701 gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
702 nativeTools = false;
703 nativeLibc = false;
704 isGNU = true;
705 inherit (prevStage) expand-response-params;
706 cc = prevStage.gcc-unwrapped;
707 bintools = self.binutils;
708 inherit lib;
709 inherit (self)
710 stdenvNoCC
711 coreutils
712 gnugrep
713 runtimeShell
714 libc
715 ;
716 fortify-headers = self.fortify-headers;
717 };
718 };
719 extraNativeBuildInputs = [
720 prevStage.patchelf
721 prevStage.xz
722 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
723 prevStage.updateAutotoolsGnuConfigScriptsHook
724 ];
725 }
726 )
727
728 # Construct the final stdenv. It uses the Glibc and GCC, and adds
729 # in a new binutils that doesn't depend on bootstrap-tools, as well
730 # as dynamically linked versions of all other tools.
731 #
732 # When updating stdenvLinux, make sure that the result has no
733 # dependency (`nix-store -qR') on bootstrapTools or the first
734 # binutils built.
735 #
736 (
737 prevStage:
738 # previous stage4 stdenv; see stage3 comment regarding gcc,
739 # which applies here as well.
740 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
741 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
742 assert isBuiltByNixpkgsCompiler prevStage.libc;
743 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
744 assert isBuiltByNixpkgsCompiler prevStage.coreutils;
745 assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
746 assert isBuiltByNixpkgsCompiler prevStage.patchelf;
747 {
748 inherit config overlays;
749 stdenv = import ../generic rec {
750 name = "stdenv-linux";
751
752 buildPlatform = localSystem;
753 hostPlatform = localSystem;
754 targetPlatform = localSystem;
755 inherit config;
756
757 preHook = commonPreHook;
758
759 initialPath = ((import ../generic/common-path.nix) { pkgs = prevStage; });
760
761 extraNativeBuildInputs = [
762 prevStage.patchelf
763 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
764 prevStage.updateAutotoolsGnuConfigScriptsHook
765 ];
766
767 cc = prevStage.gcc;
768
769 shell = cc.shell;
770
771 inherit (prevStage.stdenv) fetchurlBoot;
772
773 extraAttrs = {
774 inherit bootstrapTools;
775 shellPackage = prevStage.bash;
776 };
777
778 disallowedRequisites = [ bootstrapTools.out ];
779
780 # Mainly avoid reference to bootstrap tools
781 allowedRequisites =
782 let
783 inherit (prevStage)
784 gzip
785 bzip2
786 xz
787 zlib
788 bashNonInteractive
789 binutils
790 coreutils
791 diffutils
792 findutils
793 gawk
794 gmp
795 gnumake
796 gnused
797 gnutar
798 gnugrep
799 gnupatch
800 patchelf
801 ed
802 file
803 glibc
804 attr
805 acl
806 libidn2
807 libunistring
808 linuxHeaders
809 gcc
810 fortify-headers
811 gcc-unwrapped
812 ;
813 in
814 # Simple executable tools
815 lib.concatMap
816 (p: [
817 (lib.getBin p)
818 (lib.getLib p)
819 ])
820 [
821 gzip
822 bzip2
823 xz
824 bashNonInteractive
825 binutils.bintools
826 coreutils
827 diffutils
828 findutils
829 gawk
830 gmp
831 gnumake
832 gnused
833 gnutar
834 gnugrep
835 gnupatch
836 patchelf
837 ed
838 file
839 ]
840 # Library dependencies
841 ++ map lib.getLib [
842 attr
843 acl
844 zlib
845 gnugrep.pcre2
846 libidn2
847 libunistring
848 ]
849 # More complicated cases
850 ++ (map (x: lib.getOutput x (prevStage.libc)) [
851 "out"
852 "dev"
853 "bin"
854 ])
855 ++ [
856 linuxHeaders # propagated from .dev
857 binutils
858 gcc
859 gcc.cc
860 gcc.cc.lib
861 gcc.expand-response-params # != (prevStage.)expand-response-params
862 gcc.cc.libgcc
863 glibc.passthru.libgcc
864 ]
865 ++ lib.optionals (localSystem.libc == "musl") [ fortify-headers ]
866 ++ [
867 prevStage.updateAutotoolsGnuConfigScriptsHook
868 prevStage.gnu-config
869 ]
870 ++ [
871 gcc-unwrapped.gmp
872 gcc-unwrapped.libmpc
873 gcc-unwrapped.mpfr
874 gcc-unwrapped.isl
875 ];
876
877 overrides =
878 self: super:
879 {
880 inherit (prevStage)
881 gzip
882 bzip2
883 xz
884 bashNonInteractive
885 coreutils
886 diffutils
887 findutils
888 gawk
889 gnused
890 gnutar
891 gnugrep
892 gnupatch
893 patchelf
894 attr
895 acl
896 zlib
897 libunistring
898 ;
899 inherit (prevStage.gnugrep) pcre2;
900 ${localSystem.libc} = prevStage.${localSystem.libc};
901
902 # Hack: avoid libidn2.{bin,dev} referencing bootstrap tools. There's a logical cycle.
903 libidn2 = import ../../development/libraries/libidn2/no-bootstrap-reference.nix {
904 inherit lib;
905 inherit (prevStage) libidn2;
906 inherit (self)
907 stdenv
908 runCommandLocal
909 patchelf
910 libunistring
911 ;
912 };
913
914 gnumake = super.gnumake.override { inBootstrap = false; };
915 }
916 // lib.optionalAttrs (super.stdenv.targetPlatform == localSystem) {
917 # Need to get rid of these when cross-compiling.
918 inherit (prevStage) binutils binutils-unwrapped;
919 gcc = cc;
920 };
921 };
922 }
923 )
924
925 # This "no-op" stage is just a place to put the assertions about stage5.
926 (
927 prevStage:
928 # previous stage5 stdenv; see stage3 comment regarding gcc,
929 # which applies here as well.
930 assert isBuiltByNixpkgsCompiler prevStage.binutils-unwrapped;
931 assert isBuiltByNixpkgsCompiler prevStage.${localSystem.libc};
932 assert isBuiltByNixpkgsCompiler prevStage.libc;
933 assert isBuiltByNixpkgsCompiler prevStage.gcc-unwrapped;
934 assert isBuiltByNixpkgsCompiler prevStage.coreutils;
935 assert isBuiltByNixpkgsCompiler prevStage.gnugrep;
936 assert isBuiltByNixpkgsCompiler prevStage.patchelf;
937 {
938 inherit (prevStage) config overlays stdenv;
939 }
940 )
941]