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