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