diff --git a/.gitignore b/.gitignore index be0a75ecfc..d4c24c209e 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ config.cache /doc/guix.pdf /doc/stamp-vti /doc/version.texi +/distro/packages/bootstrap/x86_64-linux/guile-bootstrap-2.0.6.tar.xz diff --git a/Makefile.am b/Makefile.am index dd2cfee8e6..277ac4277e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -62,6 +62,31 @@ dist_patch_DATA = \ distro/patches/readline-link-ncurses.patch \ distro/patches/tar-gets-undeclared.patch +bootstrapdir = $(pkgdatadir)/bootstrap +bootstrap_x86_64_linuxdir = $(bootstrapdir)/x86_64-linux + +dist_bootstrap_x86_64_linux_DATA = \ + distro/packages/bootstrap/x86_64-linux/bash \ + distro/packages/bootstrap/x86_64-linux/mkdir \ + distro/packages/bootstrap/x86_64-linux/tar \ + distro/packages/bootstrap/x86_64-linux/xz + +# Big bootstrap binaries are not included in the tarball. Instead, they +# are downloaded. +nodist_bootstrap_x86_64_linux_DATA = \ + distro/packages/bootstrap/x86_64-linux/guile-bootstrap-2.0.6.tar.xz + +DISTCLEANFILES = $(nodist_bootstrap_x86_64_linux_DATA) + +# Method to download a file from an external source. +DOWNLOAD_FILE = \ + GUILE_LOAD_COMPILED_PATH="$(top_builddir):$$GUILE_LOAD_COMPILED_PATH" \ + $(GUILE) --no-auto-compile -L "$(top_srcdir)" \ + "$(top_srcdir)/build-aux/download.scm" + +distro/packages/bootstrap/x86_64-linux/guile-bootstrap-2.0.6.tar.xz: guix/utils.go + $(DOWNLOAD_FILE) "$@" "0467a82cbe4136f60a79eb4176011bf88cf28ea19c9ad9defa365811ff8e11cf" + nobase_nodist_guilemodule_DATA = $(GOBJECTS) TESTS = \ @@ -77,6 +102,7 @@ LOG_COMPILER = \ EXTRA_DIST = \ .dir-locals.el \ + build-aux/download.scm \ srfi/srfi-64.scm \ srfi/srfi-64.upstream.scm \ tests/test.drv \ @@ -93,6 +119,8 @@ CLEANFILES = $(GOBJECTS) *.log LIBGCRYPT="$(LIBGCRYPT)" \ DISTRO_PATCH_DIRECTORY="$(top_srcdir)/distro/patches" \ DISTRO_INSTALLED_PATCH_DIRECTORY="$(patchdir)" \ + DISTRO_BOOTSTRAP_DIRECTORY="$(top_srcdir)/distro/packages/bootstrap" \ + DISTRO_INSTALLED_BOOTSTRAP_DIRECTORY="$(bootstrapdir)" \ GUILE_AUTO_COMPILE=0 \ GUILE_LOAD_COMPILED_PATH="$(top_builddir):$$GUILE_LOAD_COMPILED_PATH" \ $(GUILD) compile -L "$(top_srcdir)" \ diff --git a/build-aux/download.scm b/build-aux/download.scm new file mode 100644 index 0000000000..9da39155ea --- /dev/null +++ b/build-aux/download.scm @@ -0,0 +1,57 @@ +;;; Guix --- Nix package management from Guile. -*- coding: utf-8 -*- +;;; Copyright (C) 2012 Ludovic Courtès +;;; +;;; This file is part of Guix. +;;; +;;; Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Guix. If not, see . + +;;; +;;; Download a binary file from an external source. +;;; + +(use-modules (ice-9 match) + (web uri) + (web client) + (rnrs io ports) + (srfi srfi-11) + (guix utils)) + +(define %url-base + "http://www.fdn.fr/~lcourtes/software/guix/packages") + +(define (file-name->uri file) + "Return the URI for FILE." + (match (string-tokenize file (char-set-complement (char-set #\/))) + ((_ ... system basename) + (string->uri (string-append %url-base "/" system "/" basename))))) + +(match (command-line) + ((_ file expected-hash) + (let ((uri (file-name->uri file))) + (format #t "downloading file `~a' from `~a'...~%" + file (uri->string uri)) + (let*-values (((resp data) (http-get uri #:decode-body? #f)) + ((hash) (bytevector->base16-string (sha256 data))) + ((part) (string-append file ".part"))) + (if (string=? expected-hash hash) + (begin + (call-with-output-file part + (lambda (port) + (put-bytevector port data))) + (rename-file part file)) + (begin + (format (current-error-port) + "file at `~a' has SHA256 ~a; expected ~a~%" + (uri->string uri) hash expected-hash) + (exit 1))))))) diff --git a/distro.scm b/distro.scm index f697ad3601..760c7245e7 100644 --- a/distro.scm +++ b/distro.scm @@ -24,6 +24,7 @@ #:use-module (srfi srfi-26) #:use-module (srfi srfi-39) #:export (search-patch + search-bootstrap-binary %patch-directory find-packages-by-name)) @@ -41,10 +42,20 @@ (or (getenv "DISTRO_PATCH_DIRECTORY") (compile-time-value (getenv "DISTRO_INSTALLED_PATCH_DIRECTORY"))))) +(define %bootstrap-binaries-directory + (make-parameter + (or (getenv "DISTRO_BOOTSTRAP_DIRECTORY") + (compile-time-value (getenv "DISTRO_INSTALLED_BOOTSTRAP_DIRECTORY"))))) + (define (search-patch file-name) "Search the patch FILE-NAME." (search-path (list (%patch-directory)) file-name)) +(define (search-bootstrap-binary file-name system) + "Search the bootstrap binary FILE-NAME for SYSTEM." + (search-path (list (%bootstrap-binaries-directory)) + (string-append system "/" file-name))) + (define %distro-module-directory ;; Absolute path of the (distro ...) module root. (string-append (dirname (search-path %load-path "distro.scm")) diff --git a/distro/packages/base.scm b/distro/packages/base.scm index 8ffdbf635d..35db11e7de 100644 --- a/distro/packages/base.scm +++ b/distro/packages/base.scm @@ -21,8 +21,11 @@ #:use-module (guix packages) #:use-module (guix ftp) #:use-module (guix http) + #:use-module (guix build-system) #:use-module (guix build-system gnu) #:use-module (guix build-system trivial) + #:use-module ((guix store) #:select (add-to-store add-text-to-store)) + #:use-module ((guix derivations) #:select (derivation)) #:use-module (guix utils) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) @@ -1386,7 +1389,49 @@ with the Linux kernel.") (define %bootstrap-guile ;; The Guile used to run the build scripts of the initial derivations. - (nixpkgs-derivation* "guile")) + ;; It is just unpacked from a tarball containing a pre-built binary. + ;; This is typically built using %GUILE-BOOTSTRAP-TARBALL below. + ;; + ;; XXX: Would need libc's `libnss_files2.so' for proper `getaddrinfo' + ;; support (for /etc/services). + (let ((raw (build-system + (name "raw") + (description "Raw build system with direct store access") + (build (lambda* (store name source inputs #:key outputs system) + (define (->store file) + (add-to-store store file #t #t "sha256" + (search-bootstrap-binary file system))) + + (let* ((tar (->store "tar")) + (xz (->store "xz")) + (mkdir (->store "mkdir")) + (bash (->store "bash")) + (guile (->store "guile-bootstrap-2.0.6.tar.xz")) + (builder + (add-text-to-store store + "build-bootstrap-guile.sh" + (format #f " +echo \"unpacking bootstrap Guile to '$out'...\" +~a $out +cd $out +~a -dc < ~a | ~a xv + +# Sanity check. +$out/bin/guile --version~%" + mkdir xz guile tar) + (list mkdir xz guile tar)))) + (derivation store name system + bash `(,builder) '() + `((,bash) (,builder))))))))) + (package + (name "guile-bootstrap") + (version "2.0") + (source #f) + (build-system raw) + (description "Bootstrap Guile") + (long-description "Pre-built Guile for bootstrapping purposes.") + (home-page #f) + (license "LGPLv3+")))) (define (default-keyword-arguments args defaults) "Return ARGS augmented with any keyword/value from DEFAULTS for diff --git a/distro/packages/bootstrap/x86_64-linux/bash b/distro/packages/bootstrap/x86_64-linux/bash new file mode 100755 index 0000000000..81114f79c3 Binary files /dev/null and b/distro/packages/bootstrap/x86_64-linux/bash differ diff --git a/distro/packages/bootstrap/x86_64-linux/mkdir b/distro/packages/bootstrap/x86_64-linux/mkdir new file mode 100755 index 0000000000..226865dfe6 Binary files /dev/null and b/distro/packages/bootstrap/x86_64-linux/mkdir differ diff --git a/distro/packages/bootstrap/x86_64-linux/tar b/distro/packages/bootstrap/x86_64-linux/tar new file mode 100755 index 0000000000..c9a2c27d13 Binary files /dev/null and b/distro/packages/bootstrap/x86_64-linux/tar differ diff --git a/distro/packages/bootstrap/x86_64-linux/xz b/distro/packages/bootstrap/x86_64-linux/xz new file mode 100755 index 0000000000..02f9014740 Binary files /dev/null and b/distro/packages/bootstrap/x86_64-linux/xz differ diff --git a/pre-inst-env.in b/pre-inst-env.in index 3022ee5cff..7dcad5b967 100644 --- a/pre-inst-env.in +++ b/pre-inst-env.in @@ -24,10 +24,12 @@ # "./pre-inst-env guix-build hello". DISTRO_PATCH_DIRECTORY="@abs_top_srcdir@/distro/patches" +DISTRO_BOOTSTRAP_DIRECTORY="@abs_top_srcdir@/distro/packages/bootstrap" GUILE_LOAD_COMPILED_PATH="@abs_top_builddir@${GUILE_LOAD_COMPILED_PATH:+:}$GUILE_LOAD_COMPILED_PATH" GUILE_LOAD_PATH="@abs_top_srcdir@${GUILE_LOAD_PATH:+:}:$GUILE_LOAD_PATH" -export DISTRO_PATCH_DIRECTORY GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH +export DISTRO_PATCH_DIRECTORY DISTRO_BOOTSTRAP_DIRECTORY +export GUILE_LOAD_COMPILED_PATH GUILE_LOAD_PATH # Define $PATH so that `guix-build' and friends are easily found.