lint: Report synopses/descriptions that are not strings.
[jackhill/guix/guix.git] / gnu / packages / bootstrap.scm
... / ...
CommitLineData
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
3;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
4;;;
5;;; This file is part of GNU Guix.
6;;;
7;;; GNU Guix is free software; you can redistribute it and/or modify it
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;;;
12;;; GNU Guix is distributed in the hope that it will be useful, but
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
18;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
19
20(define-module (gnu packages bootstrap)
21 #:use-module (guix licenses)
22 #:use-module (gnu packages)
23 #:use-module (guix packages)
24 #:use-module (guix download)
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)
62 (lambda* (url hash-algo hash
63 #:optional name #:key system)
64 (fetch url hash-algo hash
65 #:guile %bootstrap-guile
66 #:system system)))
67
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
76 (let ((orig-method (origin-method source)))
77 (origin (inherit source)
78 (method (cond ((eq? orig-method url-fetch)
79 (boot url-fetch))
80 (else orig-method)))
81 (patch-guile %bootstrap-guile)
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))))))
90
91(define* (package-from-tarball name source program-to-test description
92 #:key snippet)
93 "Return a package that correspond to the extraction of SOURCE.
94PROGRAM-TO-TEST is a program to run after extraction of SOURCE, to
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."
98 (package
99 (name name)
100 (version "0")
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")))
119 ,@(if snippet (list snippet) '())
120 (zero? (system* (string-append "bin/" ,program-to-test)
121 "--version"))))))))
122 (inputs
123 `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
124 ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
125 ("tarball" ,(bootstrap-origin (source (%current-system))))))
126 (source #f)
127 (synopsis description)
128 (description #f)
129 (home-page #f)
130 (license gpl3+)))
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
154 (package-propagated-inputs p)))
155 (replacement (and=> (package-replacement p)
156 package-with-bootstrap-guile))))))
157
158(define* (glibc-dynamic-linker
159 #:optional (system (or (and=> (%current-target-system)
160 gnu-triplet->nix-system)
161 (%current-system))))
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")
165 ((string=? system "armhf-linux") "/lib/ld-linux-armhf.so.3")
166 ((string=? system "mips64el-linux") "/lib/ld.so.1")
167 ((string=? system "i586-gnu") "/lib/ld.so.1")
168 ((string=? system "i686-gnu") "/lib/ld.so.1")
169 ((string=? system "aarch64-linux") "/lib/ld-linux-aarch64.so.1")
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")
174 ((string=? system "avr") "no-ld.so")
175
176 (else (error "dynamic linker name not known for this system"
177 system))))
178
179\f
180;;;
181;;; Bootstrap packages.
182;;;
183
184(define* (raw-build store name inputs
185 #:key outputs system search-paths
186 #:allow-other-keys)
187 (define (->store file)
188 (add-to-store store file #t "sha256"
189 (or (search-bootstrap-binary file
190 system)
191 (error "bootstrap binary not found"
192 file system))))
193
194 (let* ((tar (->store "tar"))
195 (xz (->store "xz"))
196 (mkdir (->store "mkdir"))
197 (bash (->store "bash"))
198 (guile (->store (match system
199 ("armhf-linux"
200 "guile-2.0.11.tar.xz")
201 (_
202 "guile-2.0.9.tar.xz"))))
203 ;; The following code, run by the bootstrap guile after it is
204 ;; unpacked, creates a wrapper for itself to set its load path.
205 ;; This replaces the previous non-portable method based on
206 ;; reading the /proc/self/exe symlink.
207 (make-guile-wrapper
208 '(begin
209 (use-modules (ice-9 match))
210 (match (command-line)
211 ((_ out bash)
212 (let ((bin-dir (string-append out "/bin"))
213 (guile (string-append out "/bin/guile"))
214 (guile-real (string-append out "/bin/.guile-real"))
215 ;; We must avoid using a bare dollar sign in this code,
216 ;; because it would be interpreted by the shell.
217 (dollar (string (integer->char 36))))
218 (chmod bin-dir #o755)
219 (rename-file guile guile-real)
220 (call-with-output-file guile
221 (lambda (p)
222 (format p "\
223#!~a
224export GUILE_SYSTEM_PATH=~a/share/guile/2.0
225export GUILE_SYSTEM_COMPILED_PATH=~a/lib/guile/2.0/ccache
226exec -a \"~a0\" ~a \"~a@\"\n"
227 bash out out dollar guile-real dollar)))
228 (chmod guile #o555)
229 (chmod bin-dir #o555))))))
230 (builder
231 (add-text-to-store store
232 "build-bootstrap-guile.sh"
233 (format #f "
234echo \"unpacking bootstrap Guile to '$out'...\"
235~a $out
236cd $out
237~a -dc < ~a | ~a xv
238
239# Use the bootstrap guile to create its own wrapper to set the load path.
240GUILE_SYSTEM_PATH=$out/share/guile/2.0 \
241GUILE_SYSTEM_COMPILED_PATH=$out/lib/guile/2.0/ccache \
242$out/bin/guile -c ~s $out ~a
243
244# Sanity check.
245$out/bin/guile --version~%"
246 mkdir xz guile tar
247 (format #f "~s" make-guile-wrapper)
248 bash)
249 (list mkdir xz guile tar bash))))
250 (derivation store name
251 bash `(,builder)
252 #:system system
253 #:inputs `((,bash) (,builder)))))
254
255(define* (make-raw-bag name
256 #:key source inputs native-inputs outputs
257 system target)
258 (bag
259 (name name)
260 (system system)
261 (build-inputs inputs)
262 (build raw-build)))
263
264(define %bootstrap-guile
265 ;; The Guile used to run the build scripts of the initial derivations.
266 ;; It is just unpacked from a tarball containing a pre-built binary.
267 ;; This is typically built using %GUILE-BOOTSTRAP-TARBALL below.
268 ;;
269 ;; XXX: Would need libc's `libnss_files2.so' for proper `getaddrinfo'
270 ;; support (for /etc/services).
271 (let ((raw (build-system
272 (name 'raw)
273 (description "Raw build system with direct store access")
274 (lower make-raw-bag))))
275 (package
276 (name "guile-bootstrap")
277 (version "2.0")
278 (source #f)
279 (build-system raw)
280 (synopsis "Bootstrap Guile")
281 (description "Pre-built Guile for bootstrapping purposes.")
282 (home-page #f)
283 (license lgpl3+))))
284
285(define %bootstrap-base-urls
286 ;; This is where the initial binaries come from.
287 '("http://alpha.gnu.org/gnu/guix/bootstrap"
288 "http://www.fdn.fr/~lcourtes/software/guix/packages"))
289
290(define %bootstrap-coreutils&co
291 (package-from-tarball "bootstrap-binaries"
292 (lambda (system)
293 (origin
294 (method url-fetch)
295 (uri (map (cut string-append <> "/" system
296 (match system
297 ("armhf-linux"
298 "/20150101/static-binaries.tar.xz")
299 (_
300 "/20131110/static-binaries.tar.xz")))
301 %bootstrap-base-urls))
302 (sha256
303 (match system
304 ("x86_64-linux"
305 (base32
306 "0c533p9dhczzcsa1117gmfq3pc8w362g4mx84ik36srpr7cx2bg4"))
307 ("i686-linux"
308 (base32
309 "0s5b3jb315n13m1k8095l0a5hfrsz8g0fv1b6riyc5hnxqyphlak"))
310 ("armhf-linux"
311 (base32
312 "0gf0fn2kbpxkjixkmx5f4z6hv6qpmgixl69zgg74dbsfdfj8jdv5"))
313 ("mips64el-linux"
314 (base32
315 "072y4wyfsj1bs80r6vbybbafy8ya4vfy7qj25dklwk97m6g71753"))))))
316 "fgrep" ; the program to test
317 "Bootstrap binaries of Coreutils, Awk, etc."
318 #:snippet
319 '(let ((path (list (string-append (getcwd) "/bin"))))
320 (chmod "bin" #o755)
321 (patch-shebang "bin/egrep" path)
322 (patch-shebang "bin/fgrep" path)
323 (chmod "bin" #o555)
324 #t)))
325
326(define %bootstrap-binutils
327 (package-from-tarball "binutils-bootstrap"
328 (lambda (system)
329 (origin
330 (method url-fetch)
331 (uri (map (cut string-append <> "/" system
332 (match system
333 ("armhf-linux"
334 "/20150101/binutils-2.25.tar.xz")
335 (_
336 "/20131110/binutils-2.23.2.tar.xz")))
337 %bootstrap-base-urls))
338 (sha256
339 (match system
340 ("x86_64-linux"
341 (base32
342 "1j5yivz7zkjqfsfmxzrrrffwyayjqyfxgpi89df0w4qziqs2dg20"))
343 ("i686-linux"
344 (base32
345 "14jgwf9gscd7l2pnz610b1zia06dvcm2qyzvni31b8zpgmcai2v9"))
346 ("armhf-linux"
347 (base32
348 "1v7dj6bzn6m36f20gw31l99xaabq4xrhrx3gwqkhhig0mdlmr69q"))
349 ("mips64el-linux"
350 (base32
351 "1x8kkhcxmfyzg1ddpz2pxs6fbdl6412r7x0nzbmi5n7mj8zw2gy7"))))))
352 "ld" ; the program to test
353 "Bootstrap binaries of the GNU Binutils"))
354
355(define %bootstrap-glibc
356 ;; The initial libc.
357 (package
358 (name "glibc-bootstrap")
359 (version "0")
360 (source #f)
361 (build-system trivial-build-system)
362 (arguments
363 `(#:guile ,%bootstrap-guile
364 #:modules ((guix build utils))
365 #:builder
366 (let ((out (assoc-ref %outputs "out"))
367 (tar (assoc-ref %build-inputs "tar"))
368 (xz (assoc-ref %build-inputs "xz"))
369 (tarball (assoc-ref %build-inputs "tarball")))
370 (use-modules (guix build utils))
371
372 (mkdir out)
373 (copy-file tarball "binaries.tar.xz")
374 (system* xz "-d" "binaries.tar.xz")
375 (let ((builddir (getcwd)))
376 (with-directory-excursion out
377 (system* tar "xvf"
378 (string-append builddir
379 "/binaries.tar"))
380 (chmod "lib" #o755)
381
382 ;; Patch libc.so so it refers to the right path.
383 (substitute* "lib/libc.so"
384 (("/[^ ]+/lib/(libc|ld)" _ prefix)
385 (string-append out "/lib/" prefix))))))))
386 (inputs
387 `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
388 ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
389 ("tarball" ,(bootstrap-origin
390 (origin
391 (method url-fetch)
392 (uri (map (cut string-append <> "/" (%current-system)
393 (match (%current-system)
394 ("armhf-linux"
395 "/20150101/glibc-2.20.tar.xz")
396 (_
397 "/20131110/glibc-2.18.tar.xz")))
398 %bootstrap-base-urls))
399 (sha256
400 (match (%current-system)
401 ("x86_64-linux"
402 (base32
403 "0jlqrgavvnplj1b083s20jj9iddr4lzfvwybw5xrcis9spbfzk7v"))
404 ("i686-linux"
405 (base32
406 "1hgrccw1zqdc7lvgivwa54d9l3zsim5pqm0dykxg0z522h6gr05w"))
407 ("armhf-linux"
408 (base32
409 "18cmgvpllqfpn6khsmivqib7ys8ymnq0hdzi3qp24prik0ykz8gn"))
410 ("mips64el-linux"
411 (base32
412 "0k97a3whzx3apsi9n2cbsrr79ad6lh00klxph9hw4fqyp1abkdsg")))))))))
413 (synopsis "Bootstrap binaries and headers of the GNU C Library")
414 (description #f)
415 (home-page #f)
416 (license lgpl2.1+)))
417
418(define %bootstrap-gcc
419 ;; The initial GCC. Uses binaries from a tarball typically built by
420 ;; %GCC-BOOTSTRAP-TARBALL.
421 (package
422 (name "gcc-bootstrap")
423 (version "0")
424 (source #f)
425 (build-system trivial-build-system)
426 (arguments
427 `(#:guile ,%bootstrap-guile
428 #:modules ((guix build utils))
429 #:builder
430 (let ((out (assoc-ref %outputs "out"))
431 (tar (assoc-ref %build-inputs "tar"))
432 (xz (assoc-ref %build-inputs "xz"))
433 (bash (assoc-ref %build-inputs "bash"))
434 (libc (assoc-ref %build-inputs "libc"))
435 (tarball (assoc-ref %build-inputs "tarball")))
436 (use-modules (guix build utils)
437 (ice-9 popen))
438
439 (mkdir out)
440 (copy-file tarball "binaries.tar.xz")
441 (system* xz "-d" "binaries.tar.xz")
442 (let ((builddir (getcwd))
443 (bindir (string-append out "/bin")))
444 (with-directory-excursion out
445 (system* tar "xvf"
446 (string-append builddir "/binaries.tar")))
447
448 (with-directory-excursion bindir
449 (chmod "." #o755)
450 (rename-file "gcc" ".gcc-wrapped")
451 (call-with-output-file "gcc"
452 (lambda (p)
453 (format p "#!~a
454exec ~a/bin/.gcc-wrapped -B~a/lib \
455 -Wl,-rpath -Wl,~a/lib \
456 -Wl,-dynamic-linker -Wl,~a/~a \"$@\"~%"
457 bash
458 out libc libc libc
459 ,(glibc-dynamic-linker))))
460
461 (chmod "gcc" #o555))))))
462 (inputs
463 `(("tar" ,(search-bootstrap-binary "tar" (%current-system)))
464 ("xz" ,(search-bootstrap-binary "xz" (%current-system)))
465 ("bash" ,(search-bootstrap-binary "bash" (%current-system)))
466 ("libc" ,%bootstrap-glibc)
467 ("tarball" ,(bootstrap-origin
468 (origin
469 (method url-fetch)
470 (uri (map (cut string-append <> "/" (%current-system)
471 (match (%current-system)
472 ("armhf-linux"
473 "/20150101/gcc-4.8.4.tar.xz")
474 (_
475 "/20131110/gcc-4.8.2.tar.xz")))
476 %bootstrap-base-urls))
477 (sha256
478 (match (%current-system)
479 ("x86_64-linux"
480 (base32
481 "17ga4m6195n4fnbzdkmik834znkhs53nkypp6557pl1ps7dgqbls"))
482 ("i686-linux"
483 (base32
484 "150c1arrf2k8vfy6dpxh59vcgs4p1bgiz2av5m19dynpks7rjnyw"))
485 ("armhf-linux"
486 (base32
487 "0ghz825yzp43fxw53kd6afm8nkz16f7dxi9xi40bfwc8x3nbbr8v"))
488 ("mips64el-linux"
489 (base32
490 "1m5miqkyng45l745n0sfafdpjkqv9225xf44jqkygwsipj2cv9ks")))))))))
491 (native-search-paths
492 (list (search-path-specification
493 (variable "CPATH")
494 (files '("include")))
495 (search-path-specification
496 (variable "LIBRARY_PATH")
497 (files '("lib" "lib64")))))
498 (synopsis "Bootstrap binaries of the GNU Compiler Collection")
499 (description #f)
500 (home-page #f)
501 (license gpl3+)))
502
503(define %bootstrap-inputs
504 ;; The initial, pre-built inputs. From now on, we can start building our
505 ;; own packages.
506 `(("libc" ,%bootstrap-glibc)
507 ("gcc" ,%bootstrap-gcc)
508 ("binutils" ,%bootstrap-binutils)
509 ("coreutils&co" ,%bootstrap-coreutils&co)
510
511 ;; In gnu-build-system.scm, we rely on the availability of Bash.
512 ("bash" ,%bootstrap-coreutils&co)))
513
514;;; bootstrap.scm ends here