distro: Use our own pre-built Guile to bootstrap.
authorLudovic Courtès <ludo@gnu.org>
Wed, 17 Oct 2012 19:44:25 +0000 (21:44 +0200)
committerLudovic Courtès <ludo@gnu.org>
Wed, 17 Oct 2012 21:25:25 +0000 (23:25 +0200)
* distro/packages/base.scm (%bootstrap-guile): Build from a tarball
  containing a pre-built Guile.

* distro.scm (%bootstrap-binaries-directory): New variable.
  (search-bootstrap-binary): New procedure.

* Makefile.am (bootstrapdir, bootstrap_x86_64_linuxdir,
  dist_bootstrap_x86_64_linux_DATA, DISTCLEANFILES, DOWNLOAD_FILE): New
  variables.
  (distro/packages/bootstrap/x86_64-linux/guile-bootstrap-2.0.6.tar.xz):
  New rule.
  (EXTRA_DIST): Add `build-aux/download.scm'.
  (.scm.go): Define the `DISTRO_BOOTSTRAP_DIRECTORY' and
  `DISTRO_INSTALLED_BOOTSTRAP_DIRECTORY' environment variables.

* pre-inst-env.in: Define `DISTRO_BOOTSTRAP_DIRECTORY'.

* build-aux/download.scm: New file.
* distro/packages/bootstrap/x86_64-linux/{bash, mkdir, tar, xz}: New
  files.

.gitignore
Makefile.am
build-aux/download.scm [new file with mode: 0644]
distro.scm
distro/packages/base.scm
distro/packages/bootstrap/x86_64-linux/bash [new file with mode: 0755]
distro/packages/bootstrap/x86_64-linux/mkdir [new file with mode: 0755]
distro/packages/bootstrap/x86_64-linux/tar [new file with mode: 0755]
distro/packages/bootstrap/x86_64-linux/xz [new file with mode: 0755]
pre-inst-env.in

index be0a75e..d4c24c2 100644 (file)
@@ -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
index dd2cfee..277ac42 100644 (file)
@@ -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 (file)
index 0000000..9da3915
--- /dev/null
@@ -0,0 +1,57 @@
+;;; Guix --- Nix package management from Guile.         -*- coding: utf-8 -*-
+;;; Copyright (C) 2012 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; 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 <http://www.gnu.org/licenses/>.
+
+;;;
+;;; 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)))))))
index f697ad3..760c724 100644 (file)
@@ -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))
 
    (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"))
index 8ffdbf6..35db11e 100644 (file)
   #: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 (executable)
index 0000000..81114f7
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 (executable)
index 0000000..226865d
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 (executable)
index 0000000..c9a2c27
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 (executable)
index 0000000..02f9014
Binary files /dev/null and b/distro/packages/bootstrap/x86_64-linux/xz differ
index 3022ee5..7dcad5b 100644 (file)
 # "./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.