projects/guix·blob kernel-updates · refs

1017 lines · 43.9 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012-2020, 2024 Ludovic Courtès <[email protected]>
3;;; Copyright © 2014, 2015, 2018, 2019 Mark H Weaver <[email protected]>
4;;; Copyright © 2017, 2020, 2024 Efraim Flashner <[email protected]>
5;;; Copyright © 2018, 2020, 2022, 2024, 2026 Janneke Nieuwenhuizen <[email protected]>
6;;; Copyright © 2019 Carl Dong <[email protected]>
7;;; Copyright © 2019 Léo Le Bouter <[email protected]>
8;;; Copyright © 2020 Jakub Kądziołka <[email protected]>
9;;; Copyright © 2021 Chris Marusich <[email protected]>
10;;;
11;;; This file is part of GNU Guix.
12;;;
13;;; GNU Guix is free software; you can redistribute it and/or modify it
14;;; under the terms of the GNU General Public License as published by
15;;; the Free Software Foundation; either version 3 of the License, or (at
16;;; your option) any later version.
17;;;
18;;; GNU Guix is distributed in the hope that it will be useful, but
19;;; WITHOUT ANY WARRANTY; without even the implied warranty of
20;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;;; GNU General Public License for more details.
22;;;
23;;; You should have received a copy of the GNU General Public License
24;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
25
26;;; Commentary:
27;;;
28;;; Pre-built packages that are used to bootstrap the
29;;; distribution--i.e., to build all the core packages from scratch.
30;;;
31;;; Code:
32
33(define-module (gnu packages bootstrap)
34 #:use-module (guix licenses)
35 #:use-module (gnu packages)
36 #:use-module (guix platform)
37 #:use-module (guix packages)
38 #:use-module (guix download)
39 #:use-module (guix build-system)
40 #:use-module (guix build-system trivial)
41 #:use-module ((guix store)
42 #:select (%store-monad interned-file text-file store-lift))
43 #:use-module ((guix derivations)
44 #:select (raw-derivation derivation-input derivation->output-path))
45 #:use-module (guix utils)
46 #:use-module ((guix build utils) #:select (elf-file?))
47 #:use-module ((guix gexp) #:select (lower-object local-file))
48 #:use-module (guix monads)
49 #:use-module (guix memoization)
50 #:use-module (guix i18n)
51 #:use-module (srfi srfi-1)
52 #:use-module (srfi srfi-26)
53 #:use-module (srfi srfi-34)
54 #:use-module (srfi srfi-35)
55 #:use-module (ice-9 match)
56 #:export (bootstrap-guile-url-path
57 bootstrap-origin
58 package-with-bootstrap-guile
59 glibc-dynamic-linker
60
61 bootstrap-executable
62 bootstrap-guile-origin
63
64 %bootstrap-guile
65 %bootstrap-coreutils&co
66 %bootstrap-linux-libre-headers
67 %bootstrap-binutils
68 %bootstrap-gcc
69 %bootstrap-glibc
70 %bootstrap-inputs
71
72 %bootstrap-inputs-for-tests))
73
74
75;;;
76;;; The bootstrap executables: 'bash', 'mkdir', 'tar', 'xz'. They allow us to
77;;; extract the very first tarball.
78;;;
79
80(define %bootstrap-executables
81 ;; List of bootstrap executables and their recursive hashes (as per 'guix
82 ;; hash -r'), taking their executable bit into account.
83 `(("aarch64-linux"
84 ("bash"
85 ,(base32 "13aqhqb8nydlwq1ah9974q0iadx1pb95v13wzzyf7vgv6nasrwzr"))
86 ("mkdir"
87 ,(base32 "1pxhdp7ldwavmm71xbh9wc197cb2nr66acjn26yjx3732cixh9ws"))
88 ("tar"
89 ,(base32 "1j51gv08sfg277yxj73xd564wjq3f8xwd6s9rbcg8v9gms47m4cx"))
90 ("xz"
91 ,(base32 "1d779rwsrasphg5g3r37qppcqy3p7ay1jb1y83w7x4i3qsc7zjy2")))
92 ("powerpc-linux"
93 ("bash"
94 ,(base32 "0hwlw5lcyjzadprf5fm0cv4zb6jw667g9amnmhq0lbixasy7j72j"))
95 ("mkdir"
96 ,(base32 "12lfwh5p8pp06250wgi9mdvjv1jdfpd5xpmvfc0616aj0xqh09hp"))
97 ("tar"
98 ,(base32 "00sbmwl8qh6alxv9mw4hvj1j4yipwmw5mrw6qad8bi2pr7ya5386"))
99 ("xz"
100 ,(base32 "0hi47y6zh5zz137i59l5ibw92x6g54zn7ris1b1ym9rvavsasg7b")))
101 ("armhf-linux"
102 ("bash"
103 ,(base32 "0s6f1s26g4dsrrkl39zblvwpxmbzi6n9mgqf6vxsqz42gik6bgyn"))
104 ("mkdir"
105 ,(base32 "1r5rcp35niyxfkrdf00y2ba8ifrq9bi76cr63lwjf2l655j1i5p7"))
106 ("tar"
107 ,(base32 "0dksx5im3fv8ximz7368bsax9f26nn47ds74298flm5lnvpv9xly"))
108 ("xz"
109 ,(base32 "1cqqavghjfr0iwxqf61lrssv27wfigysgq2rs4rm1gkmn04yn1k3")))
110 ("i686-linux"
111 ("bash"
112 ,(base32 "0rjaxyzjdllfkf1abczvgaf3cdcc7mmahyvdbkjmjzhgz92pv23g"))
113 ("mkdir"
114 ,(base32 "133ybmfpkmsnysrzbngwvbysqnsmfi8is8zifs7i7n6n600h4s1w"))
115 ("tar"
116 ,(base32 "07830bx29ad5i0l1ykj0g0b1jayjdblf01sr3ww9wbnwdbzinqms"))
117 ("xz"
118 ,(base32 "0i9kxdi17bm5gxfi2xzm0y73p3ii0cqxli1sbljm6rh2fjgyn90k")))
119 ("i586-gnu"
120 ("bash"
121 ,(base32 "1as8649aqaibahhhrvkj10ci8shpi4hq5n7gnik8rhhy0dc1jarg"))
122 ("mkdir"
123 ,(base32 "1snqgpfrl00hfn82lm29jqylzjsfb9jd6ha74dp12phwb8fpbmb9"))
124 ("tar"
125 ,(base32 "0nq2c1zb3wv5bf7kd83sziaashydazrn7xgq6kijlk0zj2syzc2m"))
126 ("xz"
127 ,(base32 "033rhpk6zrpxpd6ffjyg5y2zwq9x9cnq0zljb7k8jlncbalsayq5")))
128 ("x86_64-gnu"
129 ("bash"
130 ,(base32 "1gr7hxpk55iahz5gc30iprssnkg0b8ylf7fh130dgiz8202z0c65"))
131 ("mkdir"
132 ,(base32 "1wv4hsxg3d995bb5wfrvi8rhqrvn18qb2y889x89c8mhf9jl9xcp"))
133 ("tar"
134 ,(base32 "00s7f78yhd8s865fy8gizpzdx5dn294nxvy10bpga6dfj8q2990r"))
135 ("xz"
136 ,(base32 "1193r88af30z124nc10a6aryvlk8pn320v6260kb56a6ax5dgqf9")))
137 ("mips64el-linux"
138 ("bash"
139 ,(base32 "1aw046dhda240k9pb9iaj5aqkm23gkvxa9j82n4k7fk87nbrixw6"))
140 ("mkdir"
141 ,(base32 "0c9j6qgyw84zxbry3ypifzll13gy8ax71w40kdk1h11jbgla3f5k"))
142 ("tar"
143 ,(base32 "06gmqdjq3rl8lr47b9fyx4ifnm5x56ymc8lyryp1ax1j2s4y5jb4"))
144 ("xz"
145 ,(base32 "09j1d69qr0hhhx4k4ih8wp00dfc9y4rp01hfg3vc15yxd0jxabh5")))
146 ("powerpc64le-linux"
147 ("bash"
148 ,(base32 "1kiw7n6mkdy2x9in97646nb7aiayxr090ws1hbrlazah3fjqi6nj"))
149 ("mkdir"
150 ,(base32 "04dpvi231zcl40ig048vqqnyvmnkw1byrm1q1qqvs1f0g16yhrrk"))
151 ("tar"
152 ,(base32 "150c8948cz8r208g6qgn2dn4f4zs5kpgbpbg6bwag6yw42rapw2l"))
153 ("xz"
154 ,(base32 "0v5738idy9pqzcbrjdpxi5c6qs5m78zrpsydmrpx5cfcfzbkxzjh")))
155 ("riscv64-linux"
156 ("bash"
157 ,(base32 "0almlf73k6hbm495kzf4bw1rzsg5qddn7z2rf5l3d1xcapac2hj3"))
158 ("mkdir"
159 ,(base32 "0rg1amdcqfkplcy1608jignl8jq0wqzfkp430mwik3f62959gya6"))
160 ("tar"
161 ,(base32 "17d3x27qhiwk7h6ns0xrvbrq0frxz89mjjh2cdwx2rraq5x6wffm"))
162 ("xz"
163 ,(base32 "0nxn75xf386vdq3igmgm8gnyk4h4x0cm8jv71vlb2jvwxh0cyw1q")))))
164
165(define %bootstrap-executable-base-urls
166 ;; This is where the bootstrap executables come from.
167 '("https://ftpmirror.gnu.org/guix/bootstrap/"
168 "https://git.savannah.gnu.org/cgit/guix.git/plain/gnu/packages/bootstrap/"
169 "https://alpha.gnu.org/gnu/guix/bootstrap/"
170 "http://flashner.co.il/guix/bootstrap/"
171 "http://lilypond.org/janneke/guix/"))
172
173(define (bootstrap-executable-file-name system program)
174 "Return the FILE-NAME part of url where PROGRAM can be found for SYSTEM."
175 (match system
176 ("powerpc64le-linux" (string-append system "/20210106/" program))
177 ("i586-gnu" (string-append system "/20200326/" program))
178 ("x86_64-gnu" (string-append system "/20260302/" program))
179 ("powerpc-linux" (string-append system "/20200923/bin/" program))
180 ("riscv64-linux" (string-append system "/20210725/bin/" program))
181 (_ (string-append system "/" program
182 "?id=44f07d1dc6806e97c4e9ee3e6be883cc59dc666e"))))
183
184(define bootstrap-executable*
185 (mlambda (program system file-name)
186 "Return an origin for PROGRAM, a statically-linked bootstrap executable
187built for SYSTEM."
188 (let ((system (if (string=? system "x86_64-linux")
189 "i686-linux"
190 system)))
191 (match (assoc-ref (assoc-ref %bootstrap-executables system)
192 program)
193 (#f
194 (raise (condition
195 (&message
196 (message
197 (format #f (G_ "could not find bootstrap binary '~a' \
198for system '~a'")
199 program system))))))
200 ((bv)
201 (origin
202 (method url-fetch/executable)
203 (uri (map (cute string-append <>
204 (bootstrap-executable-file-name system program))
205 %bootstrap-executable-base-urls))
206 ;; XXX: In the long term, migrate all boostrap executables to
207 ;; (string-append "bootstrap-" program), and drop the additional
208 ;; file-name argument.
209 (file-name file-name)
210 (hash (content-hash bv sha256))))))))
211
212(define* (bootstrap-executable program system #:optional file-name)
213 (bootstrap-executable* program system (or file-name program)))
214
215
216;;;
217;;; Helper procedures.
218;;;
219
220(define bootstrap-origin
221 (mlambdaq (source)
222 "Return a variant of SOURCE, an <origin> instance, whose method uses
223%BOOTSTRAP-GUILE to do its job."
224 (define (boot fetch)
225 (lambda* (url hash-algo hash
226 #:optional name #:key system)
227 (fetch url hash-algo hash name
228 #:guile %bootstrap-guile
229 #:system system)))
230
231 (define %bootstrap-patch-inputs
232 ;; Packages used when an <origin> has a non-empty 'patches' field.
233 `(("tar" ,%bootstrap-coreutils&co)
234 ("xz" ,%bootstrap-coreutils&co)
235 ("bzip2" ,%bootstrap-coreutils&co)
236 ("gzip" ,%bootstrap-coreutils&co)
237 ("patch" ,%bootstrap-coreutils&co)))
238
239 (let ((orig-method (origin-method source)))
240 (if (or (not (null? (origin-patches source)))
241 (origin-snippet source))
242 (origin (inherit source)
243 (method (if (eq? orig-method url-fetch)
244 (boot url-fetch)
245 orig-method))
246 (patch-guile %bootstrap-guile)
247 (patch-inputs %bootstrap-patch-inputs)
248
249 ;; Patches can be origins as well, so process them.
250 (patches (map (match-lambda
251 ((? origin? patch)
252 (bootstrap-origin patch))
253 (patch patch))
254 (origin-patches source))))
255 source))))
256
257(define* (package-from-tarball name source program-to-test description
258 #:key snippet)
259 "Return a package that correspond to the extraction of SOURCE.
260PROGRAM-TO-TEST is #f or a string: the program to run after extraction of
261SOURCE to check whether everything is alright. If SNIPPET is provided, it is
262evaluated after extracting SOURCE. SNIPPET should return true if successful,
263or false to signal an error."
264 (package
265 (name name)
266 (version "0")
267 (build-system trivial-build-system)
268 (arguments
269 `(#:guile ,%bootstrap-guile
270 #:modules ((guix build utils))
271 #:builder
272 (begin
273 (use-modules (guix build utils))
274
275 (let ((out (assoc-ref %outputs "out"))
276 (tar (assoc-ref %build-inputs "tar"))
277 (xz (assoc-ref %build-inputs "xz"))
278 (tarball (assoc-ref %build-inputs "tarball")))
279
280 (mkdir out)
281 (copy-file tarball "binaries.tar.xz")
282 (invoke xz "-d" "binaries.tar.xz")
283 (let ((builddir (getcwd)))
284 (with-directory-excursion out
285 (invoke tar "xvf"
286 (string-append builddir "/binaries.tar"))
287 ,@(if snippet (list snippet) '())
288 (or (not ,program-to-test)
289 (invoke (string-append "bin/" ,program-to-test)
290 "--version"))))))))
291 (inputs
292 `(("tar" ,(bootstrap-executable "tar" (%current-system)))
293 ("xz" ,(bootstrap-executable "xz" (%current-system)))
294 ("tarball" ,(bootstrap-origin (source (%current-system))))))
295 (source #f)
296 (synopsis description)
297 (description description)
298 (home-page #f)
299 (license gpl3+)))
300
301(define package-with-bootstrap-guile
302 (mlambdaq (p)
303 "Return a variant of P such that all its origins are fetched with
304%BOOTSTRAP-GUILE."
305 (define rewritten-input
306 (match-lambda
307 ((name (? origin? o))
308 `(,name ,(bootstrap-origin o)))
309 ((name (? package? p) sub-drvs ...)
310 `(,name ,(package-with-bootstrap-guile p) ,@sub-drvs))
311 (x x)))
312
313 (package (inherit p)
314 (source (match (package-source p)
315 ((? origin? o) (bootstrap-origin o))
316 (s s)))
317 (inputs (map rewritten-input
318 (package-inputs p)))
319 (native-inputs (map rewritten-input
320 (package-native-inputs p)))
321 (propagated-inputs (map rewritten-input
322 (package-propagated-inputs p)))
323 (replacement (and=> (package-replacement p)
324 package-with-bootstrap-guile)))))
325
326(define* (glibc-dynamic-linker
327 #:optional (system (or (and=> (%current-target-system)
328 gnu-triplet->nix-system)
329 (%current-system))))
330 "Return the name of Glibc's dynamic linker for SYSTEM."
331 ;; See the appropriate 'shlib-versions' file in libc.
332 (let ((platform (false-if-platform-not-found
333 (lookup-platform-by-system system))))
334 (cond
335 ((platform? platform)
336 (platform-glibc-dynamic-linker platform))
337
338 ;; TODO: Define those as platforms.
339 ((string=? system "i686-gnu") "/lib/ld.so.1")
340 ((string=? system "powerpc64-linux") "/lib/ld64.so.1")
341 ((string=? system "alpha-linux") "/lib/ld-linux.so.2")
342
343 ;; TODO: Remove it when we support native loongarch64 build.
344 ((string=? system "loongarch64-linux")
345 "/lib/ld-linux-loongarch-lp64d.so.1")
346
347 ;; TODO: Differentiate between x86_64-linux-gnu and x86_64-linux-gnux32.
348 ((string=? system "x86_64-linux-gnux32") "/lib/ld-linux-x32.so.2")
349
350 ;; XXX: This one is used bare-bones, without a libc, so add a case
351 ;; here just so we can keep going.
352 ((string=? system "arm-eabi") "no-ld.so")
353 ((string=? system "avr") "no-ld.so")
354 ((string=? system "bpf-none") "no-ld.so")
355 ((string=? system "or1k-elf") "no-ld.so")
356 ((string-suffix? "-elf" system) "no-ld.so")
357 ((string-suffix? "-mingw" system) "no-ld.so")
358
359 (else (error "dynamic linker name not known for this system"
360 system)))))
361
362
363;;;
364;;; Bootstrap packages.
365;;;
366
367(define %bootstrap-base-urls
368 ;; This is where the initial binaries come from.
369 '("https://ftpmirror.gnu.org/guix/bootstrap/"
370 "https://ftp.gnu.org/gnu/guix/bootstrap"
371 "https://alpha.gnu.org/gnu/guix/bootstrap"
372 "http://ftp.gnu.org/gnu/guix/bootstrap"
373 "http://alpha.gnu.org/gnu/guix/bootstrap"
374 "ftp://alpha.gnu.org/gnu/guix/bootstrap"
375 "http://www.fdn.fr/~lcourtes/software/guix/packages"
376 "http://flashner.co.il/guix/bootstrap"
377 "http://lilypond.org/janneke/guix/"))
378
379(define (bootstrap-guile-url-path system)
380 "Return the URI for FILE."
381 (string-append "/" system
382 (match system
383 ("aarch64-linux"
384 "/20170217/guile-2.0.14.tar.xz")
385 ("powerpc-linux"
386 "/20200923/guile-2.0.14.tar.xz")
387 ("armhf-linux"
388 "/20150101/guile-2.0.11.tar.xz")
389 ("i586-gnu"
390 "/20200326/guile-static-stripped-2.0.14-i586-pc-gnu.tar.xz")
391 ("x86_64-gnu"
392 "/20260302/guile-static-stripped-3.0.9-x86_64-pc-gnu.tar.xz")
393 ("powerpc64le-linux"
394 "/20210106/guile-static-stripped-2.0.14-powerpc64le-linux-gnu.tar.xz")
395 ("riscv64-linux"
396 "/20210725/guile-3.0.2.tar.xz")
397 (_
398 "/20131110/guile-2.0.9.tar.xz"))))
399
400(define (bootstrap-guile-hash system)
401 "Return the SHA256 hash of the Guile bootstrap tarball for SYSTEM."
402 (match system
403 ("x86_64-linux"
404 (base32 "1w2p5zyrglzzniqgvyn1b55vprfzhgk8vzbzkkbdgl5248si0yq3"))
405 ("i686-linux"
406 (base32 "0im800m30abgh7msh331pcbjvb4n02smz5cfzf1srv0kpx3csmxp"))
407 ("mips64el-linux"
408 (base32 "0fzp93lvi0hn54acc0fpvhc7bvl0yc853k62l958cihk03q80ilr"))
409 ("armhf-linux"
410 (base32 "1mi3brl7l58aww34rawhvja84xc7l1b4hmwdmc36fp9q9mfx0lg5"))
411 ("powerpc64le-linux"
412 (base32 "1rnyfz5q38jyvxddj617443bnnzql4vw0mxzqpj8wz48wx4bhbq0"))
413 ("aarch64-linux"
414 (base32 "1giy2aprjmn5fp9c4s9r125fljw4wv6ixy5739i5bffw4jgr0f9r"))
415 ("i586-gnu"
416 (base32 "0wgqpsmvg25rnqn49ap7kwd2qxccd8dr4lllzp7i3rjvgav27vac"))
417 ("x86_64-gnu"
418 (base32 "049c6dxc5lgaa9kbp81gn9gj32bc7xqnly4ivwajzsh4lknrhq6n"))
419 ("powerpc-linux"
420 (base32 "1by2p7s27fbyjzfkcw8h65h4kkqh7d23kv4sgg5jppjn2qx7swq4"))
421 ("riscv64-linux"
422 (base32 "12pqmhsbbp7hh9r1bjdl14l3a4q06plpz6dcks9dysb4czay8p9f"))))
423
424(define (bootstrap-guile-origin system)
425 "Return an <origin> object for the Guile tarball of SYSTEM."
426 (origin
427 (method url-fetch)
428 (uri (map (cute string-append <> (bootstrap-guile-url-path system))
429 %bootstrap-base-urls))
430 (sha256 (bootstrap-guile-hash system))))
431
432(define (download-bootstrap-guile system)
433 "Return a derivation that downloads the bootstrap Guile tarball for SYSTEM."
434 (let* ((path (bootstrap-guile-url-path system))
435 (base (basename path))
436 (urls (map (cut string-append <> path) %bootstrap-base-urls)))
437 (url-fetch urls 'sha256 (bootstrap-guile-hash system)
438 #:system system)))
439
440(define* (raw-build name inputs
441 #:key outputs system search-paths
442 #:allow-other-keys)
443 (define (->store file)
444 (lower-object (bootstrap-executable file system)
445 system))
446
447 (define (make-guile-wrapper bash guile-real)
448 ;; The following code, run by the bootstrap guile after it is unpacked,
449 ;; creates a wrapper for itself to set its load path. This replaces the
450 ;; previous non-portable method based on reading the /proc/self/exe
451 ;; symlink.
452 '(begin
453 (use-modules (ice-9 match))
454 (match (command-line)
455 ((_ out bash)
456 (let ((bin-dir (string-append out "/bin"))
457 (guile (string-append out "/bin/guile"))
458 (guile-real (string-append out "/bin/.guile-real"))
459 ;; We must avoid using a bare dollar sign in this code,
460 ;; because it would be interpreted by the shell.
461 (dollar (string (integer->char 36))))
462 (chmod bin-dir #o755)
463 (rename-file guile guile-real)
464 (call-with-output-file guile
465 (lambda (p)
466 (format p "\
467#!~a
468export GUILE_SYSTEM_PATH=~a/share/guile/2.0
469export GUILE_SYSTEM_COMPILED_PATH=~a/lib/guile/2.0/ccache
470exec -a \"~a0\" ~a \"~a@\"\n"
471 bash out out dollar guile-real dollar)))
472 (chmod guile #o555)
473 (chmod bin-dir #o555))))))
474
475 (mlet* %store-monad ((tar (->store "tar"))
476 (xz (->store "xz"))
477 (mkdir (->store "mkdir"))
478 (bash (->store "bash"))
479 (guile (download-bootstrap-guile system))
480 (wrapper -> (make-guile-wrapper bash guile))
481 (builder
482 (text-file "build-bootstrap-guile.sh"
483 (format #f "
484echo \"unpacking bootstrap Guile to '$out'...\"
485~a $out
486cd $out
487~a -dc < $GUILE_TARBALL | ~a xv
488
489# Use the bootstrap guile to create its own wrapper to set the load path.
490GUILE_SYSTEM_PATH=$out/share/guile/2.0 \
491GUILE_SYSTEM_COMPILED_PATH=$out/lib/guile/2.0/ccache \
492$out/bin/guile -c ~s $out ~a
493
494# Sanity check.
495$out/bin/guile --version~%"
496 (derivation->output-path mkdir)
497 (derivation->output-path xz)
498 (derivation->output-path tar)
499 (object->string wrapper)
500 (derivation->output-path bash)))))
501 (raw-derivation name
502 (derivation->output-path bash) `(,builder)
503 #:system system
504 #:inputs (map derivation-input
505 (list bash mkdir tar xz guile))
506 #:sources (list builder)
507 #:env-vars `(("GUILE_TARBALL"
508 . ,(derivation->output-path guile))))))
509
510(define* (raw-build-guile3 name inputs
511 #:key outputs system search-paths
512 #:allow-other-keys)
513 (define (->store file)
514 (lower-object (bootstrap-executable file system)
515 system))
516
517 (define (make-guile-wrapper bash guile-real)
518 ;; The following code, run by the bootstrap guile after it is unpacked,
519 ;; creates a wrapper for itself to set its load path. This replaces the
520 ;; previous non-portable method based on reading the /proc/self/exe
521 ;; symlink.
522 '(begin
523 (use-modules (ice-9 match))
524 (match (command-line)
525 ((_ out bash)
526 (let ((bin-dir (string-append out "/bin"))
527 (guile (string-append out "/bin/guile"))
528 (guile-real (string-append out "/bin/.guile-real"))
529 ;; We must avoid using a bare dollar sign in this code,
530 ;; because it would be interpreted by the shell.
531 (dollar (string (integer->char 36))))
532 (chmod bin-dir #o755)
533 (rename-file guile guile-real)
534 (call-with-output-file guile
535 (lambda (p)
536 (format p "\
537#!~a
538export GUILE_SYSTEM_PATH=~a/share/guile/3.0
539export GUILE_SYSTEM_COMPILED_PATH=~a/lib/guile/3.0/ccache
540exec -a \"~a0\" ~a \"~a@\"\n"
541 bash out out dollar guile-real dollar)))
542 (chmod guile #o555)
543 (chmod bin-dir #o555))))))
544
545 (mlet* %store-monad ((tar (->store "tar"))
546 (xz (->store "xz"))
547 (mkdir (->store "mkdir"))
548 (bash (->store "bash"))
549 (guile (download-bootstrap-guile system))
550 (wrapper -> (make-guile-wrapper bash guile))
551 (builder
552 (text-file "build-bootstrap-guile.sh"
553 (format #f "
554echo \"unpacking bootstrap Guile to '$out'...\"
555~a $out
556cd $out
557~a -dc < $GUILE_TARBALL | ~a xv
558
559# Use the bootstrap guile to create its own wrapper to set the load path.
560GUILE_SYSTEM_PATH=$out/share/guile/3.0 \
561GUILE_SYSTEM_COMPILED_PATH=$out/lib/guile/3.0/ccache \
562$out/bin/guile -c ~s $out ~a
563
564# Sanity check.
565$out/bin/guile --version~%"
566 (derivation->output-path mkdir)
567 (derivation->output-path xz)
568 (derivation->output-path tar)
569 (object->string wrapper)
570 (derivation->output-path bash)))))
571 (raw-derivation name
572 (derivation->output-path bash) `(,builder)
573 #:system system
574 #:inputs (map derivation-input
575 (list bash mkdir tar xz guile))
576 #:sources (list builder)
577 #:env-vars `(("GUILE_TARBALL"
578 . ,(derivation->output-path guile))))))
579
580(define* (make-raw-bag name
581 #:key source inputs native-inputs outputs
582 system target)
583 (bag
584 (name name)
585 (system system)
586 (build-inputs inputs)
587 (build (cond ((or (target-riscv64?)
588 (target-hurd64?))
589 raw-build-guile3)
590 (else raw-build)))))
591
592(define %bootstrap-guile
593 ;; The Guile used to run the build scripts of the initial derivations.
594 ;; It is just unpacked from a tarball containing a pre-built binary.
595 ;; This is typically built using %GUILE-BOOTSTRAP-TARBALL below.
596 ;;
597 ;; XXX: Would need libc's `libnss_files2.so' for proper `getaddrinfo'
598 ;; support (for /etc/services).
599 (let ((raw (build-system
600 (name 'raw)
601 (description "Raw build system with direct store access")
602 (lower make-raw-bag))))
603 (package
604 (name "guile-bootstrap")
605 (version "2.0")
606 (source #f)
607 (build-system raw)
608 (synopsis "Bootstrap Guile")
609 (description "Pre-built Guile for bootstrapping purposes.")
610 (home-page #f)
611 (license lgpl3+))))
612
613(define %bootstrap-coreutils&co
614 (package-from-tarball "bootstrap-binaries"
615 (lambda (system)
616 (origin
617 (method url-fetch)
618 (uri (map (cut string-append <> "/" system
619 (match system
620 ("armhf-linux"
621 "/20150101/static-binaries.tar.xz")
622 ("aarch64-linux"
623 "/20170217/static-binaries.tar.xz")
624 ("powerpc64le-linux"
625 "/20210106/static-binaries-0-powerpc64le-linux-gnu.tar.xz")
626 ("i586-gnu"
627 "/20200326/static-binaries-0-i586-pc-gnu.tar.xz")
628 ("x86_64-gnu"
629 "/20260302/static-binaries-0-x86_64-pc-gnu.tar.xz")
630 ("powerpc-linux"
631 "/20200923/static-binaries.tar.xz")
632 ("riscv64-linux"
633 "/20210725/static-binaries.tar.xz")
634 (_
635 "/20131110/static-binaries.tar.xz")))
636 %bootstrap-base-urls))
637 (sha256
638 (match system
639 ("x86_64-linux"
640 (base32
641 "0c533p9dhczzcsa1117gmfq3pc8w362g4mx84ik36srpr7cx2bg4"))
642 ("i686-linux"
643 (base32
644 "0s5b3jb315n13m1k8095l0a5hfrsz8g0fv1b6riyc5hnxqyphlak"))
645 ("armhf-linux"
646 (base32
647 "0gf0fn2kbpxkjixkmx5f4z6hv6qpmgixl69zgg74dbsfdfj8jdv5"))
648 ("aarch64-linux"
649 (base32
650 "18dfiq6c6xhsdpbidigw6480wh0vdgsxqq3xindq4lpdgqlccpfh"))
651 ("powerpc64le-linux"
652 (base32
653 "0afs2j9z2d1hjq42myz4iwjh0aqgzf59inifw87x6b6p1z9wv92v"))
654 ("i586-gnu"
655 (base32
656 "17kllqnf3fg79gzy9ansgi801c46yh9c23h4d923plvb0nfm1cfn"))
657 ("x86_64-gnu"
658 (base32
659 "0xnw5p6279m8xazbhal5ld5qxsya0249z2l6jcc7w9ndh2gnx07v"))
660 ("powerpc-linux"
661 (base32
662 "0kspxy0yczan2vlih6aa9hailr2inz000fqa0gn5x9d1fxxa5y8m"))
663 ("riscv64-linux"
664 (base32
665 "0x0xjlpmyh6rkr51p00gp6pscgl6zjida1rsg8vk3rinyi6rrbkg"))
666 ("mips64el-linux"
667 (base32
668 "072y4wyfsj1bs80r6vbybbafy8ya4vfy7qj25dklwk97m6g71753"))))))
669 "fgrep" ; the program to test
670 "Bootstrap binaries of Coreutils, Awk, etc."
671 #:snippet
672 '(let ((path (list (string-append (getcwd) "/bin"))))
673 (chmod "bin" #o755)
674 (patch-shebang "bin/egrep" path)
675 (patch-shebang "bin/fgrep" path)
676 ;; Starting with [email protected] 'egrep' and 'fgrep' are shell files
677 ;; that call 'grep'. If the bootstrap 'egrep' and 'fgrep'
678 ;; are not binaries then patch them to execute 'grep' via its
679 ;; absolute file name instead of searching for it in $PATH.
680 (if (not (elf-file? "bin/egrep"))
681 (substitute* '("bin/egrep" "bin/fgrep")
682 (("^exec grep") (string-append (getcwd) "/bin/grep"))))
683 (chmod "bin" #o555))))
684
685(define-public %bootstrap-linux-libre-headers
686 (package-from-tarball
687 "linux-libre-headers-bootstrap"
688 (lambda (system)
689 (origin
690 (method url-fetch)
691 (uri (map (cute string-append <>
692 "/i686-linux/20190815/"
693 "linux-libre-headers-stripped-4.14.67-i686-linux.tar.xz")
694 %bootstrap-base-urls))
695 (sha256
696 (base32
697 "0sm2z9x4wk45bh6qfs94p0w1d6hsy6dqx9sw38qsqbvxwa1qzk8s"))))
698 #f ; no program to test
699 "Bootstrap linux-libre-headers"))
700
701(define %bootstrap-binutils
702 (package-from-tarball "binutils-bootstrap"
703 (lambda (system)
704 (origin
705 (method url-fetch)
706 (uri (map (cut string-append <> "/" system
707 (match system
708 ("armhf-linux"
709 "/20150101/binutils-2.25.tar.xz")
710 ("aarch64-linux"
711 "/20170217/binutils-2.27.tar.xz")
712 ("powerpc64le-linux"
713 "/20210106/binutils-static-stripped-2.34-powerpc64le-linux-gnu.tar.xz")
714 ("i586-gnu"
715 "/20200326/binutils-static-stripped-2.34-i586-pc-gnu.tar.xz")
716 ("x86_64-gnu"
717 "/20260302/binutils-static-stripped-2.44-x86_64-pc-gnu.tar.xz")
718 ("powerpc-linux"
719 "/20200923/binutils-2.35.1.tar.xz")
720 ("riscv64-linux"
721 "/20210725/binutils-2.34.tar.xz")
722 (_
723 "/20131110/binutils-2.23.2.tar.xz")))
724 %bootstrap-base-urls))
725 (sha256
726 (match system
727 ("x86_64-linux"
728 (base32
729 "1j5yivz7zkjqfsfmxzrrrffwyayjqyfxgpi89df0w4qziqs2dg20"))
730 ("i686-linux"
731 (base32
732 "14jgwf9gscd7l2pnz610b1zia06dvcm2qyzvni31b8zpgmcai2v9"))
733 ("armhf-linux"
734 (base32
735 "1v7dj6bzn6m36f20gw31l99xaabq4xrhrx3gwqkhhig0mdlmr69q"))
736 ("aarch64-linux"
737 (base32
738 "111s7ilfiby033rczc71797xrmaa3qlv179wdvsaq132pd51xv3n"))
739 ("powerpc64le-linux"
740 (base32
741 "1klxy945c61134mzhqzz2gbk8w0n8jq7arwkrvz78d22ff2q0cwz"))
742 ("riscv64-linux"
743 (base32
744 "0n9qf4vbilfmh1lknhw000waakj4q6s50pnjazr5137skm976z5m"))
745 ("i586-gnu"
746 (base32
747 "11kykv1kmqc5wln57rs4klaqa13hm952smkc57qcsyss21kfjprs"))
748 ("x86_64-gnu"
749 (base32
750 "033bgmaa012b2lw8g76b02mjgzdnzv2yd3jvaqbhqrr5q9r3xn04"))
751 ("powerpc-linux"
752 (base32
753 "0asbg1c4avkrvh057mx0942xwddd136jni382zqsxzn79ls42yq8"))
754 ("mips64el-linux"
755 (base32
756 "1x8kkhcxmfyzg1ddpz2pxs6fbdl6412r7x0nzbmi5n7mj8zw2gy7"))))))
757 "ld" ; the program to test
758 "Bootstrap binaries of the GNU Binutils"))
759
760(define %bootstrap-glibc
761 ;; The initial libc.
762 (package
763 (name "glibc-bootstrap")
764 (version "0")
765 (source #f)
766 (build-system trivial-build-system)
767 (arguments
768 `(#:guile ,%bootstrap-guile
769 #:modules ((guix build utils))
770 #:builder
771 (begin
772 (use-modules (guix build utils))
773
774 (let ((out (assoc-ref %outputs "out"))
775 (tar (assoc-ref %build-inputs "tar"))
776 (xz (assoc-ref %build-inputs "xz"))
777 (tarball (assoc-ref %build-inputs "tarball")))
778
779 (mkdir out)
780 (copy-file tarball "binaries.tar.xz")
781 (invoke xz "-d" "binaries.tar.xz")
782 (let ((builddir (getcwd)))
783 (with-directory-excursion out
784 (invoke tar "xvf"
785 (string-append builddir
786 "/binaries.tar"))
787 (chmod "lib" #o755)
788
789 ;; Patch linker scripts so they refer to the right file-names.
790 (substitute* ,(cond ((target-hurd64?)
791 ''("lib/libc.so" "lib/libm.so"))
792 ((and (not (target-hurd?))
793 (or (target-x86?)
794 (target-arm?)))
795 ''("lib/libc.so" "lib/libpthread.so"))
796 (else
797 ''("lib/libc.so")))
798 (("/[^ ]+/lib/(libc|libh|libm|libpthread|ld)" _ prefix)
799 (string-append out "/lib/" prefix)))
800 ,@(if (target-arm32?)
801 `((substitute* "lib/libpthread.so"
802 (("/[^ ]+/lib/libpthread_nonshared\\.a") "")))
803 `())))))))
804 (inputs
805 `(("tar" ,(bootstrap-executable "tar" (%current-system)))
806 ("xz" ,(bootstrap-executable "xz" (%current-system)))
807 ("tarball" ,(bootstrap-origin
808 (origin
809 (method url-fetch)
810 (uri (map (cut string-append <> "/" (%current-system)
811 (match (%current-system)
812 ("armhf-linux"
813 "/20150101/glibc-2.20.tar.xz")
814 ("aarch64-linux"
815 "/20170217/glibc-2.25.tar.xz")
816 ("powerpc64le-linux"
817 "/20210106/glibc-stripped-2.31-powerpc64le-linux-gnu.tar.xz")
818 ("i586-gnu"
819 "/20240816/glibc-stripped-2.39-i586-pc-gnu.tar.xz")
820 ("x86_64-gnu"
821 "/20260302/glibc-stripped-2.41-x86_64-pc-gnu.tar.xz")
822 ("powerpc-linux"
823 "/20200923/glibc-2.32.tar.xz")
824 ("riscv64-linux"
825 "/20210725/glibc-2.31.tar.xz")
826 (_
827 "/20131110/glibc-2.18.tar.xz")))
828 %bootstrap-base-urls))
829 (sha256
830 (match (%current-system)
831 ("x86_64-linux"
832 (base32
833 "0jlqrgavvnplj1b083s20jj9iddr4lzfvwybw5xrcis9spbfzk7v"))
834 ("i686-linux"
835 (base32
836 "1hgrccw1zqdc7lvgivwa54d9l3zsim5pqm0dykxg0z522h6gr05w"))
837 ("armhf-linux"
838 (base32
839 "18cmgvpllqfpn6khsmivqib7ys8ymnq0hdzi3qp24prik0ykz8gn"))
840 ("aarch64-linux"
841 (base32
842 "07nx3x8598i2924rjnlrncg6rm61c9bmcczbbcpbx0fb742nvv5c"))
843 ("powerpc64le-linux"
844 (base32
845 "1a1df6z8gkaq09md3jy94lixnh20599p58p0s856p10xwjaqr1iz"))
846 ("riscv64-linux"
847 (base32
848 "0d9x80vm7ca1pd2whcmpm1h14zxpb58kqajlxlwffzm04xfsjnxm"))
849 ("i586-gnu"
850 (base32
851 "0x2x6w611k6v9qdabacawamw2475p04hm3s0q95xcg063wjq4ig2"))
852 ("x86_64-gnu"
853 (base32
854 "1lpvk0l7qqvz46cnxm64a1a40zg0gj90j3glyk67i1sh5r4znlmy"))
855 ("powerpc-linux"
856 (base32
857 "0smmssyjrlk5cvx49586smmk81gkwff0i6r91n4rir4jm6ba25sb"))
858 ("mips64el-linux"
859 (base32
860 "0k97a3whzx3apsi9n2cbsrr79ad6lh00klxph9hw4fqyp1abkdsg")))))))))
861 (synopsis "Bootstrap binaries and headers of the GNU C Library")
862 (description synopsis)
863 (home-page #f)
864 (license lgpl2.1+)))
865
866(define %bootstrap-gcc
867 ;; The initial GCC. Uses binaries from a tarball typically built by
868 ;; %GCC-BOOTSTRAP-TARBALL.
869 (package
870 (name "gcc-bootstrap")
871 (version "0")
872 (source #f)
873 (build-system trivial-build-system)
874 (arguments
875 `(#:guile ,%bootstrap-guile
876 #:modules ((guix build utils))
877 #:builder
878 (begin
879 (use-modules (guix build utils)
880 (ice-9 popen))
881
882 (let ((out (assoc-ref %outputs "out"))
883 (tar (assoc-ref %build-inputs "tar"))
884 (xz (assoc-ref %build-inputs "xz"))
885 (bash (assoc-ref %build-inputs "bash"))
886 (libc (assoc-ref %build-inputs "libc"))
887 (tarball (assoc-ref %build-inputs "tarball")))
888
889 (mkdir out)
890 (copy-file tarball "binaries.tar.xz") ;avoid: more than one hard link
891 (invoke xz "-d" "binaries.tar.xz")
892 (let ((builddir (getcwd))
893 (bindir (string-append out "/bin")))
894
895 (define (wrap-program program)
896 (let ((wrapped (format #f ".~a-wrapped" program)))
897 (rename-file program wrapped)
898 (call-with-output-file program
899 (lambda (p)
900 (format p "#!~a
901exec ~a/bin/~a -B~a/lib \
902 -Wl,-rpath -Wl,~a/lib \
903 -Wl,-dynamic-linker -Wl,~a/~a \"$@\"~%"
904 bash
905 out wrapped
906 libc libc libc
907 ,(glibc-dynamic-linker)))))
908 (chmod program #o555))
909
910 (with-directory-excursion out
911 (invoke tar "xvf"
912 (string-append builddir "/binaries.tar")))
913
914 (with-directory-excursion bindir
915 (chmod "." #o755)
916 (for-each wrap-program
917 ,(if (target-hurd64?)
918 ''("gcc" "g++")
919 ''("gcc")))))))))
920 (inputs
921 `(("tar" ,(bootstrap-executable "tar" (%current-system)))
922 ("xz" ,(bootstrap-executable "xz" (%current-system)))
923 ("bash" ,(bootstrap-executable "bash" (%current-system)))
924 ("libc" ,%bootstrap-glibc)
925 ("tarball" ,(bootstrap-origin
926 (origin
927 (method url-fetch)
928 (uri (map (cut string-append <> "/" (%current-system)
929 (match (%current-system)
930 ("armhf-linux"
931 "/20150101/gcc-4.8.4.tar.xz")
932 ("aarch64-linux"
933 "/20170217/gcc-5.4.0.tar.xz")
934 ("powerpc64le-linux"
935 "/20210106/gcc-stripped-5.5.0-powerpc64le-linux-gnu.tar.xz")
936 ("i586-gnu"
937 "/20200326/gcc-stripped-5.5.0-i586-pc-gnu.tar.xz")
938 ("x86_64-gnu"
939 "/20260302/gcc-stripped-14.3.0-x86_64-pc-gnu.tar.xz")
940 ("powerpc-linux"
941 "/20200923/gcc-5.5.0.tar.xz")
942 ("riscv64-linux"
943 "/20210725/gcc-7.5.0.tar.xz")
944 (_
945 "/20131110/gcc-4.8.2.tar.xz")))
946 %bootstrap-base-urls))
947 (sha256
948 (match (%current-system)
949 ("x86_64-linux"
950 (base32
951 "17ga4m6195n4fnbzdkmik834znkhs53nkypp6557pl1ps7dgqbls"))
952 ("i686-linux"
953 (base32
954 "150c1arrf2k8vfy6dpxh59vcgs4p1bgiz2av5m19dynpks7rjnyw"))
955 ("armhf-linux"
956 (base32
957 "0ghz825yzp43fxw53kd6afm8nkz16f7dxi9xi40bfwc8x3nbbr8v"))
958 ("aarch64-linux"
959 (base32
960 "1ar3vdzyqbfm0z36kmvazvfswxhcihlacl2dzdjgiq25cqnq9ih1"))
961 ("powerpc64le-linux"
962 (base32
963 "151kjsai25vz2s667bgzpisx8f281fpl3n9pxz2yrp9jlnadz3m1"))
964 ("riscv64-linux"
965 (base32
966 "1k4mbnb54wj2q37fgshf5dfixixqnhn002vhzvi9pnb57xb9v14d"))
967 ("i586-gnu"
968 (base32
969 "1j2zc58wzil71a34h7c70sd68dmqvcscrw3rmn2whq79vd70zvv5"))
970 ("x86_64-gnu"
971 (base32
972 "1fhi7f5zld08b6qsyv1d48ha7z0vr8pxr4kf8x7aq1a3kbcv5rkz"))
973 ("powerpc-linux"
974 (base32
975 "1p7df3yixhm87dw5sccc6yn1i9db1r9hnmsg87wq5xi4rfmirq7w"))
976 ("mips64el-linux"
977 (base32
978 "1m5miqkyng45l745n0sfafdpjkqv9225xf44jqkygwsipj2cv9ks")))))))))
979 (native-search-paths
980 (list (search-path-specification
981 (variable "C_INCLUDE_PATH")
982 (files '("include")))
983 (search-path-specification
984 (variable "CPLUS_INCLUDE_PATH")
985 (files '("include/c++" "include")))
986 (search-path-specification
987 (variable "LIBRARY_PATH")
988 (files '("lib" "lib64")))))
989 (synopsis "Bootstrap binaries of the GNU Compiler Collection")
990 (description synopsis)
991 (home-page #f)
992 (license gpl3+)))
993
994(define (%bootstrap-inputs)
995 ;; The initial, pre-built inputs. From now on, we can start building our
996 ;; own packages.
997 (match (%current-system)
998 ((or "i686-linux" "x86_64-linux")
999 `(("linux-libre-headers" ,%bootstrap-linux-libre-headers)))
1000 (_
1001 `(("libc" ,%bootstrap-glibc)
1002 ("gcc" ,%bootstrap-gcc)
1003 ("binutils" ,%bootstrap-binutils)
1004 ("coreutils&co" ,%bootstrap-coreutils&co)
1005 ;; In gnu-build-system.scm, we rely on the availability of Bash.
1006 ("bash" ,%bootstrap-coreutils&co)))))
1007
1008(define %bootstrap-inputs-for-tests
1009 ;; These are bootstrap inputs that are cheap to produce (no compilation
1010 ;; needed) and that are meant to be used for testing. (These are those we
1011 ;; used before the Mes-based full-source bootstrap.)
1012 (list %bootstrap-glibc
1013 %bootstrap-gcc
1014 %bootstrap-binutils
1015 %bootstrap-coreutils&co))
1016
1017;;; bootstrap.scm ends here