lol
1# This file constructs the standard build environment for the
2# Linux/i686 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{ lib
7, localSystem, crossSystem, config, overlays
8
9, bootstrapFiles ? { # switch
10 "i686-linux" = import ./bootstrap-files/i686.nix;
11 "x86_64-linux" = import ./bootstrap-files/x86_64.nix;
12 "armv5tel-linux" = import ./bootstrap-files/armv5tel.nix;
13 "armv6l-linux" = import ./bootstrap-files/armv6l.nix;
14 "armv7l-linux" = import ./bootstrap-files/armv7l.nix;
15 "aarch64-linux" = import ./bootstrap-files/aarch64.nix;
16 "mips64el-linux" = import ./bootstrap-files/loongson2f.nix;
17 }.${localSystem.system}
18 or (abort "unsupported platform for the pure Linux stdenv")
19}:
20
21assert crossSystem == null;
22
23let
24 inherit (localSystem) system platform;
25
26 commonPreHook =
27 ''
28 export NIX_ENFORCE_PURITY="''${NIX_ENFORCE_PURITY-1}"
29 export NIX_ENFORCE_NO_NATIVE="''${NIX_ENFORCE_NO_NATIVE-1}"
30 ${if system == "x86_64-linux" then "NIX_LIB64_IN_SELF_RPATH=1" else ""}
31 ${if system == "mips64el-linux" then "NIX_LIB32_IN_SELF_RPATH=1" else ""}
32 '';
33
34
35 # The bootstrap process proceeds in several steps.
36
37
38 # Create a standard environment by downloading pre-built binaries of
39 # coreutils, GCC, etc.
40
41
42 # Download and unpack the bootstrap tools (coreutils, GCC, Glibc, ...).
43 bootstrapTools = import ./bootstrap-tools { inherit system bootstrapFiles; };
44
45
46 # This function builds the various standard environments used during
47 # the bootstrap. In all stages, we build an stdenv and the package
48 # set that can be built with that stdenv.
49 stageFun = prevStage:
50 { name, overrides ? (self: super: {}), extraNativeBuildInputs ? [] }:
51
52 let
53
54 thisStdenv = import ../generic {
55 name = "stdenv-linux-boot";
56 buildPlatform = localSystem;
57 hostPlatform = localSystem;
58 targetPlatform = localSystem;
59 inherit config extraNativeBuildInputs;
60 preHook =
61 ''
62 # Don't patch #!/interpreter because it leads to retained
63 # dependencies on the bootstrapTools in the final stdenv.
64 dontPatchShebangs=1
65 ${commonPreHook}
66 '';
67 shell = "${bootstrapTools}/bin/bash";
68 initialPath = [bootstrapTools];
69
70 fetchurlBoot = import ../../build-support/fetchurl/boot.nix {
71 inherit system;
72 };
73
74 cc = if isNull prevStage.gcc-unwrapped
75 then null
76 else lib.makeOverridable (import ../../build-support/cc-wrapper) {
77 nativeTools = false;
78 nativeLibc = false;
79 buildPackages = lib.optionalAttrs (prevStage ? stdenv) {
80 inherit (prevStage) stdenv;
81 };
82 cc = prevStage.gcc-unwrapped;
83 isGNU = true;
84 libc = prevStage.glibc;
85 inherit (prevStage) binutils coreutils gnugrep;
86 name = name;
87 stdenv = prevStage.ccWrapperStdenv;
88 };
89
90 extraAttrs = {
91 # Having the proper 'platform' in all the stdenvs allows getting proper
92 # linuxHeaders for example.
93 inherit platform;
94
95 # stdenv.glibc is used by GCC build to figure out the system-level
96 # /usr/include directory.
97 inherit (prevStage) glibc;
98 };
99 overrides = self: super: (overrides self super) // { fetchurl = thisStdenv.fetchurlBoot; };
100 };
101
102 in {
103 inherit config overlays;
104 stdenv = thisStdenv;
105 };
106
107in
108
109[
110
111 ({}: {
112 __raw = true;
113
114 gcc-unwrapped = null;
115 glibc = null;
116 binutils = null;
117 coreutils = null;
118 gnugrep = null;
119 })
120
121 # Build a dummy stdenv with no GCC or working fetchurl. This is
122 # because we need a stdenv to build the GCC wrapper and fetchurl.
123 (prevStage: stageFun prevStage {
124 name = null;
125
126 overrides = self: super: {
127 # We thread stage0's stdenv through under this name so downstream stages
128 # can use it for wrapping gcc too. This way, downstream stages don't need
129 # to refer to this stage directly, which violates the principle that each
130 # stage should only access the stage that came before it.
131 ccWrapperStdenv = self.stdenv;
132 # The Glibc include directory cannot have the same prefix as the
133 # GCC include directory, since GCC gets confused otherwise (it
134 # will search the Glibc headers before the GCC headers). So
135 # create a dummy Glibc here, which will be used in the stdenv of
136 # stage1.
137 glibc = self.stdenv.mkDerivation {
138 name = "bootstrap-glibc";
139 buildCommand = ''
140 mkdir -p $out
141 ln -s ${bootstrapTools}/lib $out/lib
142 ln -s ${bootstrapTools}/include-glibc $out/include
143 '';
144 };
145 gcc-unwrapped = bootstrapTools;
146 binutils = bootstrapTools;
147 coreutils = bootstrapTools;
148 gnugrep = bootstrapTools;
149 };
150 })
151
152
153 # Create the first "real" standard environment. This one consists
154 # of bootstrap tools only, and a minimal Glibc to keep the GCC
155 # configure script happy.
156 #
157 # For clarity, we only use the previous stage when specifying these
158 # stages. So stageN should only ever have references for stage{N-1}.
159 #
160 # If we ever need to use a package from more than one stage back, we
161 # simply re-export those packages in the middle stage(s) using the
162 # overrides attribute and the inherit syntax.
163 (prevStage: stageFun prevStage {
164 name = "bootstrap-gcc-wrapper";
165
166 # Rebuild binutils to use from stage2 onwards.
167 overrides = self: super: {
168 binutils = super.binutils.override { gold = false; };
169 inherit (prevStage)
170 ccWrapperStdenv
171 glibc gcc-unwrapped coreutils gnugrep;
172
173 # A threaded perl build needs glibc/libpthread_nonshared.a,
174 # which is not included in bootstrapTools, so disable threading.
175 # This is not an issue for the final stdenv, because this perl
176 # won't be included in the final stdenv and won't be exported to
177 # top-level pkgs as an override either.
178 perl = super.perl.override { enableThreading = false; };
179 };
180 })
181
182
183 # 2nd stdenv that contains our own rebuilt binutils and is used for
184 # compiling our own Glibc.
185 (prevStage: stageFun prevStage {
186 name = "bootstrap-gcc-wrapper";
187
188 overrides = self: super: {
189 inherit (prevStage)
190 ccWrapperStdenv
191 binutils gcc-unwrapped coreutils gnugrep
192 perl paxctl gnum4 bison;
193 # This also contains the full, dynamically linked, final Glibc.
194 };
195 })
196
197
198 # Construct a third stdenv identical to the 2nd, except that this
199 # one uses the rebuilt Glibc from stage2. It still uses the recent
200 # binutils and rest of the bootstrap tools, including GCC.
201 (prevStage: stageFun prevStage {
202 name = "bootstrap-gcc-wrapper";
203
204 overrides = self: super: rec {
205 inherit (prevStage)
206 ccWrapperStdenv
207 binutils glibc coreutils gnugrep
208 perl patchelf linuxHeaders gnum4 bison;
209 # Link GCC statically against GMP etc. This makes sense because
210 # these builds of the libraries are only used by GCC, so it
211 # reduces the size of the stdenv closure.
212 gmp = super.gmp.override { stdenv = self.makeStaticLibraries self.stdenv; };
213 mpfr = super.mpfr.override { stdenv = self.makeStaticLibraries self.stdenv; };
214 libmpc = super.libmpc.override { stdenv = self.makeStaticLibraries self.stdenv; };
215 isl_0_14 = super.isl_0_14.override { stdenv = self.makeStaticLibraries self.stdenv; };
216 gcc-unwrapped = super.gcc-unwrapped.override {
217 isl = isl_0_14;
218 };
219 };
220 extraNativeBuildInputs = [ prevStage.patchelf prevStage.paxctl ] ++
221 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
222 lib.optional (system == "aarch64-linux") prevStage.updateAutotoolsGnuConfigScriptsHook;
223 })
224
225
226 # Construct a fourth stdenv that uses the new GCC. But coreutils is
227 # still from the bootstrap tools.
228 (prevStage: stageFun prevStage {
229 name = "";
230
231 overrides = self: super: {
232 # Zlib has to be inherited and not rebuilt in this stage,
233 # because gcc (since JAR support) already depends on zlib, and
234 # then if we already have a zlib we want to use that for the
235 # other purposes (binutils and top-level pkgs) too.
236 inherit (prevStage) gettext gnum4 bison gmp perl glibc zlib linuxHeaders;
237
238 gcc = lib.makeOverridable (import ../../build-support/cc-wrapper) {
239 nativeTools = false;
240 nativeLibc = false;
241 isGNU = true;
242 buildPackages = {
243 inherit (prevStage) stdenv;
244 };
245 cc = prevStage.gcc-unwrapped;
246 libc = self.glibc;
247 inherit (self) stdenv binutils coreutils gnugrep;
248 name = "";
249 shell = self.bash + "/bin/bash";
250 };
251 };
252 extraNativeBuildInputs = [ prevStage.patchelf prevStage.xz ] ++
253 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
254 lib.optional (system == "aarch64-linux") prevStage.updateAutotoolsGnuConfigScriptsHook;
255 })
256
257 # Construct the final stdenv. It uses the Glibc and GCC, and adds
258 # in a new binutils that doesn't depend on bootstrap-tools, as well
259 # as dynamically linked versions of all other tools.
260 #
261 # When updating stdenvLinux, make sure that the result has no
262 # dependency (`nix-store -qR') on bootstrapTools or the first
263 # binutils built.
264 (prevStage: {
265 inherit config overlays;
266 stdenv = import ../generic rec {
267 buildPlatform = localSystem;
268 hostPlatform = localSystem;
269 targetPlatform = localSystem;
270 inherit config;
271
272 preHook = ''
273 # Make "strip" produce deterministic output, by setting
274 # timestamps etc. to a fixed value.
275 commonStripFlags="--enable-deterministic-archives"
276 ${commonPreHook}
277 '';
278
279 initialPath =
280 ((import ../common-path.nix) {pkgs = prevStage;});
281
282 extraNativeBuildInputs = [ prevStage.patchelf prevStage.paxctl ] ++
283 # Many tarballs come with obsolete config.sub/config.guess that don't recognize aarch64.
284 lib.optional (system == "aarch64-linux") prevStage.updateAutotoolsGnuConfigScriptsHook;
285
286 cc = prevStage.gcc;
287
288 shell = cc.shell;
289
290 inherit (prevStage.stdenv) fetchurlBoot;
291
292 extraAttrs = {
293 inherit (prevStage) glibc;
294 inherit platform bootstrapTools;
295 shellPackage = prevStage.bash;
296 };
297
298 # Mainly avoid reference to bootstrap tools
299 allowedRequisites = with prevStage; with lib;
300 # Simple executable tools
301 concatMap (p: [ (getBin p) (getLib p) ])
302 [ gzip bzip2 xz bash binutils coreutils diffutils findutils gawk
303 gnumake gnused gnutar gnugrep gnupatch patchelf ed paxctl
304 ]
305 # Library dependencies
306 ++ map getLib (
307 [ attr acl zlib pcre ]
308 ++ lib.optional (gawk.libsigsegv != null) gawk.libsigsegv
309 )
310 # More complicated cases
311 ++ [
312 glibc.out glibc.dev glibc.bin/*propagated from .dev*/ linuxHeaders
313 gcc gcc.cc gcc.cc.lib gcc.expand-response-params
314 ]
315 ++ lib.optionals (system == "aarch64-linux")
316 [ prevStage.updateAutotoolsGnuConfigScriptsHook prevStage.gnu-config ];
317
318 overrides = self: super: {
319 inherit (prevStage)
320 gzip bzip2 xz bash coreutils diffutils findutils gawk
321 glibc gnumake gnused gnutar gnugrep gnupatch patchelf
322 attr acl paxctl zlib pcre;
323 } // lib.optionalAttrs (super.targetPlatform == localSystem) {
324 # Need to get rid of these when cross-compiling.
325 inherit (prevStage) binutils;
326 gcc = cc;
327 };
328 };
329 })
330
331]