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