gnu: dealii: Update to 8.5.0.
[jackhill/guix/guix.git] / gnu / packages / bootstrap.scm
1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
4 ;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
5 ;;;
6 ;;; This file is part of GNU Guix.
7 ;;;
8 ;;; GNU Guix is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
12 ;;;
13 ;;; GNU Guix is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;;; GNU General Public License for more details.
17 ;;;
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21 (define-module (gnu packages bootstrap)
22 #:use-module (guix licenses)
23 #:use-module (gnu packages)
24 #:use-module (guix packages)
25 #:use-module (guix download)
26 #:use-module (guix build-system)
27 #:use-module (guix build-system gnu)
28 #:use-module (guix build-system trivial)
29 #:use-module ((guix store) #:select (add-to-store add-text-to-store))
30 #:use-module ((guix derivations) #:select (derivation))
31 #:use-module ((guix utils) #:select (gnu-triplet->nix-system))
32 #:use-module ((guix build utils) #:select (elf-file?))
33 #:use-module (guix memoization)
34 #:use-module (srfi srfi-1)
35 #:use-module (srfi srfi-26)
36 #:use-module (ice-9 match)
37 #:export (bootstrap-origin
38 package-with-bootstrap-guile
39 glibc-dynamic-linker
40
41 %bootstrap-guile
42 %bootstrap-coreutils&co
43 %bootstrap-binutils
44 %bootstrap-gcc
45 %bootstrap-glibc
46 %bootstrap-inputs))
47
48 ;;; Commentary:
49 ;;;
50 ;;; Pre-built packages that are used to bootstrap the
51 ;;; distribution--i.e., to build all the core packages from scratch.
52 ;;;
53 ;;; Code:
54
55
56 \f
57 ;;;
58 ;;; Helper procedures.
59 ;;;
60
61 (define (bootstrap-origin source)
62 "Return a variant of SOURCE, an <origin> instance, whose method uses
63 %BOOTSTRAP-GUILE to do its job."
64 (define (boot fetch)
65 (lambda* (url hash-algo hash
66 #:optional name #:key system)
67 (fetch url hash-algo hash name
68 #:guile %bootstrap-guile
69 #:system system)))
70
71 (define %bootstrap-patch-inputs
72 ;; Packages used when an <origin> has a non-empty 'patches' field.
73 `(("tar" ,%bootstrap-coreutils&co)
74 ("xz" ,%bootstrap-coreutils&co)
75 ("bzip2" ,%bootstrap-coreutils&co)
76 ("gzip" ,%bootstrap-coreutils&co)
77 ("patch" ,%bootstrap-coreutils&co)))
78
79 (let ((orig-method (origin-method source)))
80 (origin (inherit source)
81 (method (cond ((eq? orig-method url-fetch)
82 (boot url-fetch))
83 (else orig-method)))
84 (patch-guile %bootstrap-guile)
85 (patch-inputs %bootstrap-patch-inputs)
86
87 ;; Patches can be origins as well, so process them.
88 (patches (map (match-lambda
89 ((? origin? patch)
90 (bootstrap-origin patch))
91 (patch patch))
92 (origin-patches source))))))
93
94 (define* (package-from-tarball name source program-to-test description
95 #:key snippet)
96 "Return a package that correspond to the extraction of SOURCE.
97 PROGRAM-TO-TEST is a program to run after extraction of SOURCE, to
98 check whether everything is alright. If SNIPPET is provided, it is
99 evaluated after extracting SOURCE. SNIPPET should return true if
100 successful, or false to signal an error."
101 (package
102 (name name)
103 (version "0")
104 (build-system trivial-build-system)
105 (arguments
106 `(#:guile ,%bootstrap-guile
107 #:modules ((guix build utils))
108 #:builder
109 (let ((out (assoc-ref %outputs "out"))
110 (tar (assoc-ref %build-inputs "tar"))
111 (xz (assoc-ref %build-inputs "xz"))
112 (tarball (assoc-ref %build-inputs "tarball")))
113 (use-modules (guix build utils))
114
115 (mkdir out)
116 (copy-file tarball "binaries.tar.xz")
117 (system* xz "-d" "binaries.tar.xz")
118 (let ((builddir (getcwd)))
119 (with-directory-excursion out
120 (and (zero? (system* tar "xvf"
121 (string-append builddir "/binaries.tar")))
122 ,@(if snippet (list snippet) '())
123 (zero? (system* (string-append "bin/" ,program-to-test)
124 "--version"))))))))
125 (inputs
126 `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
127 ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
128 ("tarball" ,(bootstrap-origin (source (%current-system))))))
129 (source #f)
130 (synopsis description)
131 (description description)
132 (home-page #f)
133 (license gpl3+)))
134
135 (define package-with-bootstrap-guile
136 (mlambda (p)
137 "Return a variant of P such that all its origins are fetched with
138 %BOOTSTRAP-GUILE."
139 (define rewritten-input
140 (match-lambda
141 ((name (? origin? o))
142 `(,name ,(bootstrap-origin o)))
143 ((name (? package? p) sub-drvs ...)
144 `(,name ,(package-with-bootstrap-guile p) ,@sub-drvs))
145 (x x)))
146
147 (package (inherit p)
148 (source (match (package-source p)
149 ((? origin? o) (bootstrap-origin o))
150 (s s)))
151 (inputs (map rewritten-input
152 (package-inputs p)))
153 (native-inputs (map rewritten-input
154 (package-native-inputs p)))
155 (propagated-inputs (map rewritten-input
156 (package-propagated-inputs p)))
157 (replacement (and=> (package-replacement p)
158 package-with-bootstrap-guile)))))
159
160 (define* (glibc-dynamic-linker
161 #:optional (system (or (and=> (%current-target-system)
162 gnu-triplet->nix-system)
163 (%current-system))))
164 "Return the name of Glibc's dynamic linker for SYSTEM."
165 (cond ((string=? system "x86_64-linux") "/lib/ld-linux-x86-64.so.2")
166 ((string=? system "i686-linux") "/lib/ld-linux.so.2")
167 ((string=? system "armhf-linux") "/lib/ld-linux-armhf.so.3")
168 ((string=? system "mips64el-linux") "/lib/ld.so.1")
169 ((string=? system "i586-gnu") "/lib/ld.so.1")
170 ((string=? system "i686-gnu") "/lib/ld.so.1")
171 ((string=? system "aarch64-linux") "/lib/ld-linux-aarch64.so.1")
172 ((string=? system "powerpc-linux") "/lib/ld.so.1")
173 ((string=? system "alpha-linux") "/lib/ld-linux.so.2")
174
175 ;; XXX: This one is used bare-bones, without a libc, so add a case
176 ;; here just so we can keep going.
177 ((string=? system "arm-eabi") "no-ld.so")
178 ((string=? system "xtensa-elf") "no-ld.so")
179 ((string=? system "avr") "no-ld.so")
180 ((string=? system "propeller-elf") "no-ld.so")
181 ((string=? system "i686-mingw") "no-ld.so")
182 ((string=? system "vc4-elf") "no-ld.so")
183
184 (else (error "dynamic linker name not known for this system"
185 system))))
186
187 \f
188 ;;;
189 ;;; Bootstrap packages.
190 ;;;
191
192 (define* (raw-build store name inputs
193 #:key outputs system search-paths
194 #:allow-other-keys)
195 (define (->store file)
196 (add-to-store store file #t "sha256"
197 (or (search-bootstrap-binary file
198 system)
199 (error "bootstrap binary not found"
200 file system))))
201
202 (let* ((tar (->store "tar"))
203 (xz (->store "xz"))
204 (mkdir (->store "mkdir"))
205 (bash (->store "bash"))
206 (guile (->store (match system
207 ("armhf-linux"
208 "guile-2.0.11.tar.xz")
209 ("aarch64-linux"
210 "guile-2.0.14.tar.xz")
211 (_
212 "guile-2.0.9.tar.xz"))))
213 ;; The following code, run by the bootstrap guile after it is
214 ;; unpacked, creates a wrapper for itself to set its load path.
215 ;; This replaces the previous non-portable method based on
216 ;; reading the /proc/self/exe symlink.
217 (make-guile-wrapper
218 '(begin
219 (use-modules (ice-9 match))
220 (match (command-line)
221 ((_ out bash)
222 (let ((bin-dir (string-append out "/bin"))
223 (guile (string-append out "/bin/guile"))
224 (guile-real (string-append out "/bin/.guile-real"))
225 ;; We must avoid using a bare dollar sign in this code,
226 ;; because it would be interpreted by the shell.
227 (dollar (string (integer->char 36))))
228 (chmod bin-dir #o755)
229 (rename-file guile guile-real)
230 (call-with-output-file guile
231 (lambda (p)
232 (format p "\
233 #!~a
234 export GUILE_SYSTEM_PATH=~a/share/guile/2.0
235 export GUILE_SYSTEM_COMPILED_PATH=~a/lib/guile/2.0/ccache
236 exec -a \"~a0\" ~a \"~a@\"\n"
237 bash out out dollar guile-real dollar)))
238 (chmod guile #o555)
239 (chmod bin-dir #o555))))))
240 (builder
241 (add-text-to-store store
242 "build-bootstrap-guile.sh"
243 (format #f "
244 echo \"unpacking bootstrap Guile to '$out'...\"
245 ~a $out
246 cd $out
247 ~a -dc < ~a | ~a xv
248
249 # Use the bootstrap guile to create its own wrapper to set the load path.
250 GUILE_SYSTEM_PATH=$out/share/guile/2.0 \
251 GUILE_SYSTEM_COMPILED_PATH=$out/lib/guile/2.0/ccache \
252 $out/bin/guile -c ~s $out ~a
253
254 # Sanity check.
255 $out/bin/guile --version~%"
256 mkdir xz guile tar
257 (format #f "~s" make-guile-wrapper)
258 bash)
259 (list mkdir xz guile tar bash))))
260 (derivation store name
261 bash `(,builder)
262 #:system system
263 #:inputs `((,bash) (,builder)))))
264
265 (define* (make-raw-bag name
266 #:key source inputs native-inputs outputs
267 system target)
268 (bag
269 (name name)
270 (system system)
271 (build-inputs inputs)
272 (build raw-build)))
273
274 (define %bootstrap-guile
275 ;; The Guile used to run the build scripts of the initial derivations.
276 ;; It is just unpacked from a tarball containing a pre-built binary.
277 ;; This is typically built using %GUILE-BOOTSTRAP-TARBALL below.
278 ;;
279 ;; XXX: Would need libc's `libnss_files2.so' for proper `getaddrinfo'
280 ;; support (for /etc/services).
281 (let ((raw (build-system
282 (name 'raw)
283 (description "Raw build system with direct store access")
284 (lower make-raw-bag))))
285 (package
286 (name "guile-bootstrap")
287 (version "2.0")
288 (source #f)
289 (build-system raw)
290 (synopsis "Bootstrap Guile")
291 (description "Pre-built Guile for bootstrapping purposes.")
292 (home-page #f)
293 (license lgpl3+))))
294
295 (define %bootstrap-base-urls
296 ;; This is where the initial binaries come from.
297 '("ftp://alpha.gnu.org/gnu/guix/bootstrap"
298 "http://alpha.gnu.org/gnu/guix/bootstrap"
299 "http://www.fdn.fr/~lcourtes/software/guix/packages"
300 "http://flashner.co.il/guix/bootstrap"))
301
302 (define %bootstrap-coreutils&co
303 (package-from-tarball "bootstrap-binaries"
304 (lambda (system)
305 (origin
306 (method url-fetch)
307 (uri (map (cut string-append <> "/" system
308 (match system
309 ("armhf-linux"
310 "/20150101/static-binaries.tar.xz")
311 ("aarch64-linux"
312 "/20170217/static-binaries.tar.xz")
313 (_
314 "/20131110/static-binaries.tar.xz")))
315 %bootstrap-base-urls))
316 (sha256
317 (match system
318 ("x86_64-linux"
319 (base32
320 "0c533p9dhczzcsa1117gmfq3pc8w362g4mx84ik36srpr7cx2bg4"))
321 ("i686-linux"
322 (base32
323 "0s5b3jb315n13m1k8095l0a5hfrsz8g0fv1b6riyc5hnxqyphlak"))
324 ("armhf-linux"
325 (base32
326 "0gf0fn2kbpxkjixkmx5f4z6hv6qpmgixl69zgg74dbsfdfj8jdv5"))
327 ("aarch64-linux"
328 (base32
329 "18dfiq6c6xhsdpbidigw6480wh0vdgsxqq3xindq4lpdgqlccpfh"))
330 ("mips64el-linux"
331 (base32
332 "072y4wyfsj1bs80r6vbybbafy8ya4vfy7qj25dklwk97m6g71753"))))))
333 "fgrep" ; the program to test
334 "Bootstrap binaries of Coreutils, Awk, etc."
335 #:snippet
336 '(let ((path (list (string-append (getcwd) "/bin"))))
337 (chmod "bin" #o755)
338 (patch-shebang "bin/egrep" path)
339 (patch-shebang "bin/fgrep" path)
340 ;; Starting with grep@2.25 'egrep' and 'fgrep' are shell files
341 ;; that call 'grep'. If the bootstrap 'egrep' and 'fgrep'
342 ;; are not binaries then patch them to execute 'grep' via its
343 ;; absolute file name instead of searching for it in $PATH.
344 (if (not (elf-file? "bin/egrep"))
345 (substitute* '("bin/egrep" "bin/fgrep")
346 (("^exec grep") (string-append (getcwd) "/bin/grep"))))
347 (chmod "bin" #o555)
348 #t)))
349
350 (define %bootstrap-binutils
351 (package-from-tarball "binutils-bootstrap"
352 (lambda (system)
353 (origin
354 (method url-fetch)
355 (uri (map (cut string-append <> "/" system
356 (match system
357 ("armhf-linux"
358 "/20150101/binutils-2.25.tar.xz")
359 ("aarch64-linux"
360 "/20170217/binutils-2.27.tar.xz")
361 (_
362 "/20131110/binutils-2.23.2.tar.xz")))
363 %bootstrap-base-urls))
364 (sha256
365 (match system
366 ("x86_64-linux"
367 (base32
368 "1j5yivz7zkjqfsfmxzrrrffwyayjqyfxgpi89df0w4qziqs2dg20"))
369 ("i686-linux"
370 (base32
371 "14jgwf9gscd7l2pnz610b1zia06dvcm2qyzvni31b8zpgmcai2v9"))
372 ("armhf-linux"
373 (base32
374 "1v7dj6bzn6m36f20gw31l99xaabq4xrhrx3gwqkhhig0mdlmr69q"))
375 ("aarch64-linux"
376 (base32
377 "111s7ilfiby033rczc71797xrmaa3qlv179wdvsaq132pd51xv3n"))
378 ("mips64el-linux"
379 (base32
380 "1x8kkhcxmfyzg1ddpz2pxs6fbdl6412r7x0nzbmi5n7mj8zw2gy7"))))))
381 "ld" ; the program to test
382 "Bootstrap binaries of the GNU Binutils"))
383
384 (define %bootstrap-glibc
385 ;; The initial libc.
386 (package
387 (name "glibc-bootstrap")
388 (version "0")
389 (source #f)
390 (build-system trivial-build-system)
391 (arguments
392 `(#:guile ,%bootstrap-guile
393 #:modules ((guix build utils))
394 #:builder
395 (let ((out (assoc-ref %outputs "out"))
396 (tar (assoc-ref %build-inputs "tar"))
397 (xz (assoc-ref %build-inputs "xz"))
398 (tarball (assoc-ref %build-inputs "tarball")))
399 (use-modules (guix build utils))
400
401 (mkdir out)
402 (copy-file tarball "binaries.tar.xz")
403 (system* xz "-d" "binaries.tar.xz")
404 (let ((builddir (getcwd)))
405 (with-directory-excursion out
406 (system* tar "xvf"
407 (string-append builddir
408 "/binaries.tar"))
409 (chmod "lib" #o755)
410
411 ;; Patch libc.so so it refers to the right path.
412 (substitute* "lib/libc.so"
413 (("/[^ ]+/lib/(libc|ld)" _ prefix)
414 (string-append out "/lib/" prefix))))))))
415 (inputs
416 `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
417 ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
418 ("tarball" ,(bootstrap-origin
419 (origin
420 (method url-fetch)
421 (uri (map (cut string-append <> "/" (%current-system)
422 (match (%current-system)
423 ("armhf-linux"
424 "/20150101/glibc-2.20.tar.xz")
425 ("aarch64-linux"
426 "/20170217/glibc-2.25.tar.xz")
427 (_
428 "/20131110/glibc-2.18.tar.xz")))
429 %bootstrap-base-urls))
430 (sha256
431 (match (%current-system)
432 ("x86_64-linux"
433 (base32
434 "0jlqrgavvnplj1b083s20jj9iddr4lzfvwybw5xrcis9spbfzk7v"))
435 ("i686-linux"
436 (base32
437 "1hgrccw1zqdc7lvgivwa54d9l3zsim5pqm0dykxg0z522h6gr05w"))
438 ("armhf-linux"
439 (base32
440 "18cmgvpllqfpn6khsmivqib7ys8ymnq0hdzi3qp24prik0ykz8gn"))
441 ("aarch64-linux"
442 (base32
443 "07nx3x8598i2924rjnlrncg6rm61c9bmcczbbcpbx0fb742nvv5c"))
444 ("mips64el-linux"
445 (base32
446 "0k97a3whzx3apsi9n2cbsrr79ad6lh00klxph9hw4fqyp1abkdsg")))))))))
447 (synopsis "Bootstrap binaries and headers of the GNU C Library")
448 (description synopsis)
449 (home-page #f)
450 (license lgpl2.1+)))
451
452 (define %bootstrap-gcc
453 ;; The initial GCC. Uses binaries from a tarball typically built by
454 ;; %GCC-BOOTSTRAP-TARBALL.
455 (package
456 (name "gcc-bootstrap")
457 (version "0")
458 (source #f)
459 (build-system trivial-build-system)
460 (arguments
461 `(#:guile ,%bootstrap-guile
462 #:modules ((guix build utils))
463 #:builder
464 (let ((out (assoc-ref %outputs "out"))
465 (tar (assoc-ref %build-inputs "tar"))
466 (xz (assoc-ref %build-inputs "xz"))
467 (bash (assoc-ref %build-inputs "bash"))
468 (libc (assoc-ref %build-inputs "libc"))
469 (tarball (assoc-ref %build-inputs "tarball")))
470 (use-modules (guix build utils)
471 (ice-9 popen))
472
473 (mkdir out)
474 (copy-file tarball "binaries.tar.xz")
475 (system* xz "-d" "binaries.tar.xz")
476 (let ((builddir (getcwd))
477 (bindir (string-append out "/bin")))
478 (with-directory-excursion out
479 (system* tar "xvf"
480 (string-append builddir "/binaries.tar")))
481
482 (with-directory-excursion bindir
483 (chmod "." #o755)
484 (rename-file "gcc" ".gcc-wrapped")
485 (call-with-output-file "gcc"
486 (lambda (p)
487 (format p "#!~a
488 exec ~a/bin/.gcc-wrapped -B~a/lib \
489 -Wl,-rpath -Wl,~a/lib \
490 -Wl,-dynamic-linker -Wl,~a/~a \"$@\"~%"
491 bash
492 out libc libc libc
493 ,(glibc-dynamic-linker))))
494
495 (chmod "gcc" #o555))))))
496 (inputs
497 `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
498 ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
499 ("bash" ,(search-bootstrap-binary "bash" (%current-system)))
500 ("libc" ,%bootstrap-glibc)
501 ("tarball" ,(bootstrap-origin
502 (origin
503 (method url-fetch)
504 (uri (map (cut string-append <> "/" (%current-system)
505 (match (%current-system)
506 ("armhf-linux"
507 "/20150101/gcc-4.8.4.tar.xz")
508 ("aarch64-linux"
509 "/20170217/gcc-5.4.0.tar.xz")
510 (_
511 "/20131110/gcc-4.8.2.tar.xz")))
512 %bootstrap-base-urls))
513 (sha256
514 (match (%current-system)
515 ("x86_64-linux"
516 (base32
517 "17ga4m6195n4fnbzdkmik834znkhs53nkypp6557pl1ps7dgqbls"))
518 ("i686-linux"
519 (base32
520 "150c1arrf2k8vfy6dpxh59vcgs4p1bgiz2av5m19dynpks7rjnyw"))
521 ("armhf-linux"
522 (base32
523 "0ghz825yzp43fxw53kd6afm8nkz16f7dxi9xi40bfwc8x3nbbr8v"))
524 ("aarch64-linux"
525 (base32
526 "1ar3vdzyqbfm0z36kmvazvfswxhcihlacl2dzdjgiq25cqnq9ih1"))
527 ("mips64el-linux"
528 (base32
529 "1m5miqkyng45l745n0sfafdpjkqv9225xf44jqkygwsipj2cv9ks")))))))))
530 (native-search-paths
531 (list (search-path-specification
532 (variable "CPATH")
533 (files '("include")))
534 (search-path-specification
535 (variable "LIBRARY_PATH")
536 (files '("lib" "lib64")))))
537 (synopsis "Bootstrap binaries of the GNU Compiler Collection")
538 (description synopsis)
539 (home-page #f)
540 (license gpl3+)))
541
542 (define %bootstrap-inputs
543 ;; The initial, pre-built inputs. From now on, we can start building our
544 ;; own packages.
545 `(("libc" ,%bootstrap-glibc)
546 ("gcc" ,%bootstrap-gcc)
547 ("binutils" ,%bootstrap-binutils)
548 ("coreutils&co" ,%bootstrap-coreutils&co)
549
550 ;; In gnu-build-system.scm, we rely on the availability of Bash.
551 ("bash" ,%bootstrap-coreutils&co)))
552
553 ;;; bootstrap.scm ends here