projects/guix·blob java-team · refs

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