;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Ludovic Courtès ;;; Copyright © 2014, 2015, 2018, 2019 Mark H Weaver ;;; Copyright © 2017 Efraim Flashner ;;; Copyright © 2018 Jan (janneke) Nieuwenhuizen ;;; Copyright © 2019 Carl Dong ;;; ;;; This file is part of GNU Guix. ;;; ;;; GNU 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. ;;; ;;; GNU 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
aboutsummaryrefslogtreecommitdiff
# GNU Guix --- Functional package management for GNU
# Copyright © 2018, 2019, 2020, 2023 Ludovic Courtès <ludo@gnu.org>
# Copyright © 2020 Eric Bavier <bavier@posteo.net>
#
# This file is part of GNU Guix.
#
# GNU 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.
#
# GNU 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 GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

#
# Test the 'guix pack --relocatable' using the external store, if any.
#

guix pack --version

# 'guix pack --relocatable' requires a C compiler and libc.a, which our
# bootstrap binaries don't provide.  To make the test relatively inexpensive,
# run it on the user's global store if possible, on the grounds that binaries
# may already be there or can be built or downloaded inexpensively.

storedir="`guile -c '(use-modules (guix config))(display %storedir)'`"
localstatedir="`guile -c '(use-modules (guix config))(display %localstatedir)'`"
NIX_STORE_DIR="$storedir"
GUIX_DAEMON_SOCKET="$localstatedir/guix/daemon-socket/socket"
export NIX_STORE_DIR GUIX_DAEMON_SOCKET

if ! guile -c '(use-modules (guix)) (exit (false-if-exception (open-connection)))'
then
    exit 77
fi

# Attempt to run the given command in a namespace where the store is
# invisible.  This makes sure the presence of the store does not hide
# problems.
run_without_store ()
{
    if unshare -r true		# Are user namespaces supported?
    then
	# Run that relocatable executable in a user namespace where we "erase"
	# the store by mounting an empty file system on top of it.  That way,
	# we exercise the wrapper code that creates the user namespace and
	# bind-mounts the store.
	unshare -mrf sh -c 'mount -t tmpfs -o ro none "$NIX_STORE_DIR"; '"$*"
    else
	# Run the relocatable program in the current namespaces.  This is a
	# weak test because we're going to access store items from the host
	# store.
	sh -c "$*"
    fi
}

# Wait for the given file to show up.  Error out if it doesn't show up in a
# timely fashion.
wait_for_file ()
{
    i=0
    while ! test -f "$1" && test $i -lt 20
    do
	sleep 0.3
	i=`expr $i + 1`
    done
    test -f "$1"
}

test_directory="`mktemp -d`"
export test_directory
trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_directory"' EXIT

if unshare -r true
then
    # Test the 'userns' execution engine.
    tarball="`guix pack -R -S /Bin=bin sed`"
    (cd "$test_directory"; tar xvf "$tarball")

    chmod +w "$test_directory"
    run_without_store "$test_directory/Bin/sed" --version > "$test_directory/output"
    grep 'GNU sed' "$test_directory/output"

    # Same with an explicit engine.
    run_without_store GUIX_EXECUTION_ENGINE="userns" \
		      "$test_directory/Bin/sed" --version > "$test_directory/output"
    grep 'GNU sed' "$test_directory/output"

    # Check whether the exit code is preserved.
    run_without_store "$test_directory/Bin/sed" --does-not-exist && false

    chmod -Rf +w "$test_directory"; rm -rf "$test_directory"/*
else
    echo "'userns' execution tests skipped" >&2
fi

case "`uname -m`" in
    x86_64|i?86)
	# Try '-RR' and PRoot.
	tarball="`guix pack -RR -S /Bin=bin sed`"
	tar tvf "$tarball" | grep /bin/proot
	(cd "$test_directory"; tar xf "$tarball")
	chmod +w "$test_directory"
	run_without_store GUIX_EXECUTION_ENGINE="proot" \
	"$test_directory/Bin/sed" --version > "$test_directory/output"
	grep 'GNU sed' "$test_directory/output"

	# Now with fakechroot.
	run_without_store GUIX_EXECUTION_ENGINE="fakechroot" \
	"$test_directory/Bin/sed" --version > "$test_directory/output"
	grep 'GNU sed' "$test_directory/output"
	unset GUIX_EXECUTION_ENGINE

	chmod -Rf +w "$test_directory"; rm -rf "$test_directory"/*

	if unshare -r true
	then
	    # Check whether the store contains everything it should.  Check
	    # once when erasing $STORE_PARENT ("/gnu") and once when erasing
	    # $NIX_STORE_DIR ("/gnu/store").
	    tarball="`guix pack -RR -S /bin=bin bash-minimal`"
	    (cd "$test_directory"; tar xf "$tarball")

	    STORE_PARENT="`dirname $NIX_STORE_DIR`"
	    export STORE_PARENT

	    for engine in userns proot fakechroot
	    do
		for i in $(guix gc -R $(guix build bash-minimal | grep -v -e '-doc$'))
		do
		    unshare -mrf sh -c "mount -t tmpfs none \"$NIX_STORE_DIR\"; GUIX_EXECUTION_ENGINE=$engine $test_directory/bin/sh -c 'echo $NIX_STORE_DIR/*'" | grep $(basename $i)
		    unshare -mrf sh -c "mount -t tmpfs none \"$STORE_PARENT\";  GUIX_EXECUTION_ENGINE=$engine $test_directory/bin/sh -c 'echo $NIX_STORE_DIR/*'" | grep $(basename $i)
		done
	    done

	    chmod -Rf +w "$test_directory"; rm -rf "$test_directory"/*
	fi
	;;
    *)
	echo "skipping PRoot and Fakechroot tests" >&2
	;;
esac

if unshare -r true
then
    # Check what happens if the wrapped binary forks and leaves child
    # processes behind, like a daemon.  The root file system should remain
    # available to those child processes.  See <https://bugs.gnu.org/44261>.
    cat > "$test_directory/manifest.scm" <<EOF
(use-modules (guix))

(define daemon
  (program-file "daemon"
                #~(begin
                    (use-modules (ice-9 match)
                                 (ice-9 ftw))

                    (call-with-output-file "parent-store"
                      (lambda (port)
                        (write (scandir (ungexp (%store-prefix)))
                               port)))

                    (match (primitive-fork)
                      (0 (sigaction SIGHUP (const #t))
                         (call-with-output-file "pid"
                           (lambda (port)
                             (display (getpid) port)))
                         (pause)
                         (call-with-output-file "child-store"
                           (lambda (port)
                             (write (scandir (ungexp (%store-prefix)))
                                    port))))
                      (_ #t)))))

(define package
  (computed-file "package"
                 #~(let ((out (ungexp output)))
                     (mkdir out)
                     (mkdir (string-append out "/bin"))
                     (symlink (ungexp daemon)
                              (string-append out "/bin/daemon")))))

(manifest (list (manifest-entry
                  (name "daemon")
                  (version "0")
                  (item package))))
EOF

    tarball="$(guix pack -S /bin=bin -R -m "$test_directory/manifest.scm")"
    (cd "$test_directory"; tar xf "$tarball")

    # Run '/bin/daemon', which forks, then wait for the child, send it SIGHUP
    # so that it dumps its view of the store, and make sure the child and
    # parent both see the same store contents.
    chmod +w "$test_directory"
    (cd "$test_directory"; run_without_store ./bin/daemon)
    wait_for_file "$test_directory/pid"
    kill -HUP $(cat "$test_directory/pid")
    wait_for_file "$test_directory/child-store"
    diff -u "$test_directory/parent-store" "$test_directory/child-store"

    chmod -Rf +w "$test_directory"; rm -rf "$test_directory"/*
fi

# Ensure '-R' works with outputs other than "out".
tarball="`guix pack -R -S /share=share groff:doc`"
(cd "$test_directory"; tar xf "$tarball")
test -d "$test_directory/share/doc/groff/html"
chmod -Rf +w "$test_directory"; rm -rf "$test_directory"/*

# Ensure '-R' applies to propagated inputs.  Failing to do that, it would fail
# with a profile collision error in this case because 'python-scipy'
# propagates 'python-numpy'.  See <https://bugs.gnu.org/42510>.
guix pack -RR python-numpy python-scipy --no-grafts -n

# Check that packages that mix executable and support files (e.g. git) in the
# "binary" directories still work after wrapped.
cat >"$test_directory/manifest.scm" <<'EOF'
(use-modules (guix) (guix profiles) (guix search-paths)
             (gnu packages bootstrap))
(manifest
 (list (manifest-entry
        (name "test") (version "0")
        (item (file-union "test"
                          `(("bin/hello"
                             ,(program-file
                               "hello"
                               #~(begin
                                   (add-to-load-path (getenv "HELLO_EXEC_PATH"))
                                   (display (load-from-path "msg"))(newline))
                               #:guile %bootstrap-guile))
                            ("libexec/hello/msg"
                             ,(plain-file "msg" "42")))))
        (search-paths
         (list (search-path-specification
                (variable "HELLO_EXEC_PATH")
                (files '("libexec/hello"))
                (separator #f)))))))
EOF
tarball="`guix pack -RR -S /opt= -m $test_directory/manifest.scm`"
(cd "$test_directory"; tar xvf "$tarball")
chmod +w "$test_directory"
( export GUIX_PROFILE=$test_directory/opt
  . $GUIX_PROFILE/etc/profile
  run_without_store "$test_directory/opt/bin/hello" > "$test_directory/output" )
cat "$test_directory/output"
test "`cat $test_directory/output`" = "42"
eturn a derivation that downloads the bootstrap Guile tarball for SYSTEM." (let* ((path (bootstrap-guile-url-path system)) (base (basename path)) (urls (map (cut string-append <> path) %bootstrap-base-urls))) (run-with-store store (url-fetch urls 'sha256 (bootstrap-guile-hash system) #:system system)))) (define* (raw-build store name inputs #:key outputs system search-paths #:allow-other-keys) (define (->store file) (run-with-store store (lower-object (bootstrap-executable file system) system))) (let* ((tar (->store "tar")) (xz (->store "xz")) (mkdir (->store "mkdir")) (bash (->store "bash")) (guile (download-bootstrap-guile store system)) ;; The following code, run by the bootstrap guile after it is ;; unpacked, creates a wrapper for itself to set its load path. ;; This replaces the previous non-portable method based on ;; reading the /proc/self/exe symlink. (make-guile-wrapper '(begin (use-modules (ice-9 match)) (match (command-line) ((_ out bash) (let ((bin-dir (string-append out "/bin")) (guile (string-append out "/bin/guile")) (guile-real (string-append out "/bin/.guile-real")) ;; We must avoid using a bare dollar sign in this code, ;; because it would be interpreted by the shell. (dollar (string (integer->char 36)))) (chmod bin-dir #o755) (rename-file guile guile-real) (call-with-output-file guile (lambda (p) (format p "\ #!~a export GUILE_SYSTEM_PATH=~a/share/guile/2.0 export GUILE_SYSTEM_COMPILED_PATH=~a/lib/guile/2.0/ccache exec -a \"~a0\" ~a \"~a@\"\n" bash out out dollar guile-real dollar))) (chmod guile #o555) (chmod bin-dir #o555)))))) (builder (add-text-to-store store "build-bootstrap-guile.sh" (format #f " echo \"unpacking bootstrap Guile to '$out'...\" ~a $out cd $out ~a -dc < $GUILE_TARBALL | ~a xv # Use the bootstrap guile to create its own wrapper to set the load path. GUILE_SYSTEM_PATH=$out/share/guile/2.0 \ GUILE_SYSTEM_COMPILED_PATH=$out/lib/guile/2.0/ccache \ $out/bin/guile -c ~s $out ~a # Sanity check. $out/bin/guile --version~%" (derivation->output-path mkdir) (derivation->output-path xz) (derivation->output-path tar) (format #f "~s" make-guile-wrapper) (derivation->output-path bash))))) (derivation store name (derivation->output-path bash) `(,builder) #:system system #:inputs (map derivation-input (list bash mkdir tar xz guile)) #:sources (list builder) #:env-vars `(("GUILE_TARBALL" . ,(derivation->output-path guile)))))) (define* (make-raw-bag name #:key source inputs native-inputs outputs system target) (bag (name name) (system system) (build-inputs inputs) (build raw-build))) (define %bootstrap-guile ;; The Guile used to run the build scripts of the initial derivations. ;; 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") (lower make-raw-bag)))) (package (name "guile-bootstrap") (version "2.0") (source #f) (build-system raw) (synopsis "Bootstrap Guile") (description "Pre-built Guile for bootstrapping purposes.") (home-page #f) (license lgpl3+)))) (define %bootstrap-coreutils&co (package-from-tarball "bootstrap-binaries" (lambda (system) (origin (method url-fetch) (uri (map (cut string-append <> "/" system (match system ("armhf-linux" "/20150101/static-binaries.tar.xz") ("aarch64-linux" "/20170217/static-binaries.tar.xz") (_ "/20131110/static-binaries.tar.xz"))) %bootstrap-base-urls)) (sha256 (match system ("x86_64-linux" (base32 "0c533p9dhczzcsa1117gmfq3pc8w362g4mx84ik36srpr7cx2bg4")) ("i686-linux" (base32 "0s5b3jb315n13m1k8095l0a5hfrsz8g0fv1b6riyc5hnxqyphlak")) ("armhf-linux" (base32 "0gf0fn2kbpxkjixkmx5f4z6hv6qpmgixl69zgg74dbsfdfj8jdv5")) ("aarch64-linux" (base32 "18dfiq6c6xhsdpbidigw6480wh0vdgsxqq3xindq4lpdgqlccpfh")) ("mips64el-linux" (base32 "072y4wyfsj1bs80r6vbybbafy8ya4vfy7qj25dklwk97m6g71753")))))) "fgrep" ; the program to test "Bootstrap binaries of Coreutils, Awk, etc." #:snippet '(let ((path (list (string-append (getcwd) "/bin")))) (chmod "bin" #o755) (patch-shebang "bin/egrep" path) (patch-shebang "bin/fgrep" path) ;; Starting with grep@2.25 'egrep' and 'fgrep' are shell files ;; that call 'grep'. If the bootstrap 'egrep' and 'fgrep' ;; are not binaries then patch them to execute 'grep' via its ;; absolute file name instead of searching for it in $PATH. (if (not (elf-file? "bin/egrep")) (substitute* '("bin/egrep" "bin/fgrep") (("^exec grep") (string-append (getcwd) "/bin/grep")))) (chmod "bin" #o555)))) (define-public %bootstrap-linux-libre-headers (package-from-tarball "linux-libre-headers-bootstrap" (lambda (system) (origin (method url-fetch) (uri (map (cute string-append <> "/i686-linux/20190815/" "linux-libre-headers-stripped-4.14.67-i686-linux.tar.xz") %bootstrap-base-urls)) (sha256 (base32 "0sm2z9x4wk45bh6qfs94p0w1d6hsy6dqx9sw38qsqbvxwa1qzk8s")))) #f ; no program to test "Bootstrap linux-libre-headers")) (define %bootstrap-binutils (package-from-tarball "binutils-bootstrap" (lambda (system) (origin (method url-fetch) (uri (map (cut string-append <> "/" system (match system ("armhf-linux" "/20150101/binutils-2.25.tar.xz") ("aarch64-linux" "/20170217/binutils-2.27.tar.xz") (_ "/20131110/binutils-2.23.2.tar.xz"))) %bootstrap-base-urls)) (sha256 (match system ("x86_64-linux" (base32 "1j5yivz7zkjqfsfmxzrrrffwyayjqyfxgpi89df0w4qziqs2dg20")) ("i686-linux" (base32 "14jgwf9gscd7l2pnz610b1zia06dvcm2qyzvni31b8zpgmcai2v9")) ("armhf-linux" (base32 "1v7dj6bzn6m36f20gw31l99xaabq4xrhrx3gwqkhhig0mdlmr69q")) ("aarch64-linux" (base32 "111s7ilfiby033rczc71797xrmaa3qlv179wdvsaq132pd51xv3n")) ("mips64el-linux" (base32 "1x8kkhcxmfyzg1ddpz2pxs6fbdl6412r7x0nzbmi5n7mj8zw2gy7")))))) "ld" ; the program to test "Bootstrap binaries of the GNU Binutils")) (define %bootstrap-glibc ;; The initial libc. (package (name "glibc-bootstrap") (version "0") (source #f) (build-system trivial-build-system) (arguments `(#:guile ,%bootstrap-guile #:modules ((guix build utils)) #:builder (begin (use-modules (guix build utils)) (let ((out (assoc-ref %outputs "out")) (tar (assoc-ref %build-inputs "tar")) (xz (assoc-ref %build-inputs "xz")) (tarball (assoc-ref %build-inputs "tarball"))) (mkdir out) (copy-file tarball "binaries.tar.xz") (invoke xz "-d" "binaries.tar.xz") (let ((builddir (getcwd))) (with-directory-excursion out (invoke tar "xvf" (string-append builddir "/binaries.tar")) (chmod "lib" #o755) ;; Patch libc.so so it refers to the right path. (substitute* "lib/libc.so" (("/[^ ]+/lib/(libc|ld)" _ prefix) (string-append out "/lib/" prefix))) #t)))))) (inputs `(("tar" ,(bootstrap-executable "tar" (%current-system))) ("xz" ,(bootstrap-executable "xz" (%current-system))) ("tarball" ,(bootstrap-origin (origin (method url-fetch) (uri (map (cut string-append <> "/" (%current-system) (match (%current-system) ("armhf-linux" "/20150101/glibc-2.20.tar.xz") ("aarch64-linux" "/20170217/glibc-2.25.tar.xz") (_ "/20131110/glibc-2.18.tar.xz"))) %bootstrap-base-urls)) (sha256 (match (%current-system) ("x86_64-linux" (base32 "0jlqrgavvnplj1b083s20jj9iddr4lzfvwybw5xrcis9spbfzk7v")) ("i686-linux" (base32 "1hgrccw1zqdc7lvgivwa54d9l3zsim5pqm0dykxg0z522h6gr05w")) ("armhf-linux" (base32 "18cmgvpllqfpn6khsmivqib7ys8ymnq0hdzi3qp24prik0ykz8gn")) ("aarch64-linux" (base32 "07nx3x8598i2924rjnlrncg6rm61c9bmcczbbcpbx0fb742nvv5c")) ("mips64el-linux" (base32 "0k97a3whzx3apsi9n2cbsrr79ad6lh00klxph9hw4fqyp1abkdsg"))))))))) (synopsis "Bootstrap binaries and headers of the GNU C Library") (description synopsis) (home-page #f) (license lgpl2.1+))) (define %bootstrap-gcc ;; The initial GCC. Uses binaries from a tarball typically built by ;; %GCC-BOOTSTRAP-TARBALL. (package (name "gcc-bootstrap") (version "0") (source #f) (build-system trivial-build-system) (arguments `(#:guile ,%bootstrap-guile #:modules ((guix build utils)) #:builder (begin (use-modules (guix build utils) (ice-9 popen)) (let ((out (assoc-ref %outputs "out")) (tar (assoc-ref %build-inputs "tar")) (xz (assoc-ref %build-inputs "xz")) (bash (assoc-ref %build-inputs "bash")) (libc (assoc-ref %build-inputs "libc")) (tarball (assoc-ref %build-inputs "tarball"))) (mkdir out) (copy-file tarball "binaries.tar.xz") (invoke xz "-d" "binaries.tar.xz") (let ((builddir (getcwd)) (bindir (string-append out "/bin"))) (with-directory-excursion out (invoke tar "xvf" (string-append builddir "/binaries.tar"))) (with-directory-excursion bindir (chmod "." #o755) (rename-file "gcc" ".gcc-wrapped") (call-with-output-file "gcc" (lambda (p) (format p "#!~a exec ~a/bin/.gcc-wrapped -B~a/lib \ -Wl,-rpath -Wl,~a/lib \ -Wl,-dynamic-linker -Wl,~a/~a \"$@\"~%" bash out libc libc libc ,(glibc-dynamic-linker)))) (chmod "gcc" #o555) #t)))))) (inputs `(("tar" ,(bootstrap-executable "tar" (%current-system))) ("xz" ,(bootstrap-executable "xz" (%current-system))) ("bash" ,(bootstrap-executable "bash" (%current-system))) ("libc" ,%bootstrap-glibc) ("tarball" ,(bootstrap-origin (origin (method url-fetch) (uri (map (cut string-append <> "/" (%current-system) (match (%current-system) ("armhf-linux" "/20150101/gcc-4.8.4.tar.xz") ("aarch64-linux" "/20170217/gcc-5.4.0.tar.xz") (_ "/20131110/gcc-4.8.2.tar.xz"))) %bootstrap-base-urls)) (sha256 (match (%current-system) ("x86_64-linux" (base32 "17ga4m6195n4fnbzdkmik834znkhs53nkypp6557pl1ps7dgqbls")) ("i686-linux" (base32 "150c1arrf2k8vfy6dpxh59vcgs4p1bgiz2av5m19dynpks7rjnyw")) ("armhf-linux" (base32 "0ghz825yzp43fxw53kd6afm8nkz16f7dxi9xi40bfwc8x3nbbr8v")) ("aarch64-linux" (base32 "1ar3vdzyqbfm0z36kmvazvfswxhcihlacl2dzdjgiq25cqnq9ih1")) ("mips64el-linux" (base32 "1m5miqkyng45l745n0sfafdpjkqv9225xf44jqkygwsipj2cv9ks"))))))))) (native-search-paths (list (search-path-specification (variable "CPATH") (files '("include"))) (search-path-specification (variable "LIBRARY_PATH") (files '("lib" "lib64"))))) (synopsis "Bootstrap binaries of the GNU Compiler Collection") (description synopsis) (home-page #f) (license gpl3+))) (define %bootstrap-mescc-tools ;; The initial MesCC tools. Uses binaries from a tarball typically built by ;; %MESCC-TOOLS-BOOTSTRAP-TARBALL. (package (name "bootstrap-mescc-tools") (version "0.5.2") (source #f) (build-system trivial-build-system) (arguments `(#:guile ,%bootstrap-guile #:modules ((guix build utils)) #:builder (begin (use-modules (guix build utils) (ice-9 popen)) (let ((out (assoc-ref %outputs "out")) (tar (assoc-ref %build-inputs "tar")) (xz (assoc-ref %build-inputs "xz")) (tarball (assoc-ref %build-inputs "tarball"))) (mkdir out) (copy-file tarball "binaries.tar.xz") (invoke xz "-d" "binaries.tar.xz") (let ((builddir (getcwd)) (bindir (string-append out "/bin"))) (with-directory-excursion out (invoke tar "xvf" (string-append builddir "/binaries.tar")))))))) (inputs `(("tar" ,(bootstrap-executable "tar" (%current-system))) ("xz" ,(bootstrap-executable "xz" (%current-system))) ("tarball" ,(bootstrap-origin (origin (method url-fetch) (uri (map (cute string-append <> "/i686-linux/20190815/" "mescc-tools-static-stripped-0.5.2-i686-linux.tar.xz") %bootstrap-base-urls)) (sha256 (base32 "0c3kklgghzh4q2dbpl6asb74cimp7hp6jscdwqwmzxbapgcl6582"))))))) (synopsis "Bootstrap binaries of MesCC Tools") (description synopsis) (home-page #f) (supported-systems '("i686-linux" "x86_64-linux")) (license gpl3+))) (define %bootstrap-mes ;; The initial Mes. Uses binaries from a tarball typically built by ;; %MES-BOOTSTRAP-TARBALL. (package (name "bootstrap-mes") (version "0") (source #f) (build-system trivial-build-system) (arguments `(#:guile ,%bootstrap-guile #:modules ((guix build utils)) #:builder (begin (use-modules (guix build utils) (ice-9 popen)) (let ((out (assoc-ref %outputs "out")) (tar (assoc-ref %build-inputs "tar")) (xz (assoc-ref %build-inputs "xz")) (tarball (assoc-ref %build-inputs "tarball"))) (mkdir out) (copy-file tarball "binaries.tar.xz") (invoke xz "-d" "binaries.tar.xz") (let ((builddir (getcwd)) (bindir (string-append out "/bin"))) (with-directory-excursion out (invoke tar "xvf" (string-append builddir "/binaries.tar")))))))) (inputs `(("tar" ,(bootstrap-executable "tar" (%current-system))) ("xz" ,(bootstrap-executable "xz" (%current-system))) ("tarball" ,(bootstrap-origin (origin (method url-fetch) (uri (map (cute string-append <> "/i686-linux/20190815/" "mes-minimal-stripped-0.19-i686-linux.tar.xz") %bootstrap-base-urls)) (sha256 (base32 "1q4xjpx6nbn44kxnilpgl12bhpmwy2bblzwszc2ci7xkf400jcpv"))))))) (supported-systems '("i686-linux" "x86_64-linux")) (synopsis "Bootstrap binaries of Mes") (description synopsis) (home-page #f) (license gpl3+))) (define (%bootstrap-inputs) ;; The initial, pre-built inputs. From now on, we can start building our ;; own packages. `(,@(match (%current-system) ((or "i686-linux" "x86_64-linux") `(("linux-libre-headers" ,%bootstrap-linux-libre-headers) ("bootstrap-mescc-tools" ,%bootstrap-mescc-tools) ("mes" ,%bootstrap-mes))) (_ `(("libc" ,%bootstrap-glibc) ("gcc" ,%bootstrap-gcc) ("binutils" ,%bootstrap-binutils)))) ("coreutils&co" ,%bootstrap-coreutils&co) ;; In gnu-build-system.scm, we rely on the availability of Bash. ("bash" ,%bootstrap-coreutils&co))) (define %bootstrap-inputs-for-tests ;; These are bootstrap inputs that are cheap to produce (no compilation ;; needed) and that are meant to be used for testing. (These are those we ;; used before the Mes-based reduced bootstrap.) `(("libc" ,%bootstrap-glibc) ("gcc" ,%bootstrap-gcc) ("binutils" ,%bootstrap-binutils) ("coreutils&co" ,%bootstrap-coreutils&co) ("bash" ,%bootstrap-coreutils&co))) ;;; bootstrap.scm ends here