diff options
Diffstat (limited to 'guix/build')
-rw-r--r-- | guix/build/cargo-build-system.scm | 6 | ||||
-rw-r--r-- | guix/build/chicken-build-system.scm | 133 | ||||
-rw-r--r-- | guix/build/store-copy.scm | 133 |
3 files changed, 234 insertions, 38 deletions
diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-system.scm index c7beffc6e4..1d21b33895 100644 --- a/guix/build/cargo-build-system.scm +++ b/guix/build/cargo-build-system.scm @@ -183,13 +183,9 @@ directory = '" port) ;; otherwise cargo will raise an error. (or skip-build? (not (has-executable-target?)) - (invoke "cargo" "install" "--path" "." "--root" out + (invoke "cargo" "install" "--no-track" "--path" "." "--root" out "--features" (string-join features))) - ;; This is a file which we definitely don't need installed. - (when (file-exists? (string-append out "/.crates.toml")) - (delete-file (string-append out "/.crates.toml"))) - #t)) (define %standard-phases diff --git a/guix/build/chicken-build-system.scm b/guix/build/chicken-build-system.scm new file mode 100644 index 0000000000..5db9906acf --- /dev/null +++ b/guix/build/chicken-build-system.scm @@ -0,0 +1,133 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2020 raingloom <raingloom@riseup.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/>. + +(define-module (guix build chicken-build-system) + #:use-module ((guix build gnu-build-system) #:prefix gnu:) + #:use-module (guix build union) + #:use-module (guix build utils) + #:use-module (ice-9 match) + #:use-module (ice-9 ftw) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-26) + #:use-module (rnrs io ports) + #:use-module (rnrs bytevectors) + #:export (%standard-phases + chicken-build)) + +;; CHICKEN_EGG_CACHE is where sources are fetched and binaries are built +;; CHICKEN_INSTALL_REPOSITORY is where dependencies are looked up +;; its first component is also where new eggs are installed. + +;; TODO: deduplicate with go-build-system.scm ? +;; TODO: the binary version should be defined in one of the relevant modules +;; instead of being hardcoded everywhere. Tried to do that but got undefined +;; variable errors. + +(define (chicken-package? name) + (string-prefix? "chicken-" name)) + +(define* (setup-chicken-environment #:key inputs outputs #:allow-other-keys) + (setenv "CHICKEN_INSTALL_REPOSITORY" + (string-concatenate + ;; see TODO item about binary version above + (append (list (assoc-ref outputs "out") "/var/lib/chicken/11/") + (let ((oldenv (getenv "CHICKEN_INSTALL_REPOSITORY"))) + (if oldenv + (list ":" oldenv) + '()))))) + (setenv "CHICKEN_EGG_CACHE" (getcwd)) + #t) + +;; This is copied from go-build-system.scm so it could probably be simplified. +;; I used it because the source of the egg needs to be unpacked into a directory +;; that is named after the egg and I knew that the go build system does that. +(define* (unpack #:key source egg-name unpack-path #:allow-other-keys) + "Relative to $CHICKEN_EGG_CACHE, unpack SOURCE in UNPACK-PATH, or EGG-NAME +when UNPACK-PATH is unset. If the SOURCE archive has a single top level +directory, it is stripped so that the sources appear directly under UNPACK-PATH. +When SOURCE is a directory, copy its content into UNPACK-PATH instead of +unpacking." + (define (unpack-maybe-strip source dest) + (let* ((scratch-dir (string-append (or (getenv "TMPDIR") "/tmp") + "/scratch-dir")) + (out (mkdir-p scratch-dir))) + (with-directory-excursion scratch-dir + (if (string-suffix? ".zip" source) + (invoke "unzip" source) + (invoke "tar" "-xvf" source)) + (let ((top-level-files (remove (lambda (x) + (member x '("." ".."))) + (scandir ".")))) + (match top-level-files + ((top-level-file) + (when (file-is-directory? top-level-file) + (copy-recursively top-level-file dest #:keep-mtime? #t))) + (_ + (copy-recursively "." dest #:keep-mtime? #t))))) + (delete-file-recursively scratch-dir))) + + (when (string-null? egg-name) + (display "WARNING: The egg name is unset.\n")) + (when (string-null? unpack-path) + (set! unpack-path egg-name)) + (let ((dest (string-append (getenv "CHICKEN_EGG_CACHE") "/" unpack-path))) + (mkdir-p dest) + (if (file-is-directory? source) + (copy-recursively source dest #:keep-mtime? #t) + (unpack-maybe-strip source dest))) + #t) + +(define* (build #:key egg-name #:allow-other-keys) + "Build the Chicken egg named by EGG-NAME" + (invoke "chicken-install" "-cached" "-no-install" egg-name)) + +(define* (install #:key egg-name #:allow-other-keys) + "Install the already built egg named by EGG-NAME" + (invoke "chicken-install" "-cached" egg-name)) + +(define* (check #:key egg-name tests? #:allow-other-keys) + "Build and run tests for the Chicken egg EGG-NAME" + ;; there is no "-test-only" option, but we've already run install + ;; so this just runs tests. + ;; i think it's a fair assumption that phases won't be reordered. + (setenv "CHICKEN_REPOSITORY_PATH" + (string-append (getenv "CHICKEN_INSTALL_REPOSITORY") + ":" + (getenv "CHICKEN_REPOSITORY_PATH"))) + (when tests? + (invoke "chicken-install" "-cached" "-test" "-no-install" egg-name))) + +;; It doesn't look like Chicken generates any unnecessary references. +;; So we don't have to remove them either. Nice. + +(define %standard-phases + (modify-phases gnu:%standard-phases + (replace 'unpack unpack) + (delete 'bootstrap) + (delete 'configure) + (delete 'patch-generated-file-shebangs) + (add-before 'unpack 'setup-chicken-environment setup-chicken-environment) + (replace 'build build) + (delete 'check) + (replace 'install install) + (add-after 'install 'check check))) + +(define* (chicken-build #:key inputs (phases %standard-phases) + #:allow-other-keys #:rest args) + "Build the given Chicken package, applying all of PHASES in order." + (apply gnu:gnu-build #:inputs inputs #:phases phases args)) diff --git a/guix/build/store-copy.scm b/guix/build/store-copy.scm index ad551bca98..01e1f41870 100644 --- a/guix/build/store-copy.scm +++ b/guix/build/store-copy.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2017, 2018 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2013, 2014, 2017, 2018, 2020 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -17,9 +17,10 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (guix build store-copy) - #:use-module (guix build utils) + #:use-module ((guix build utils) #:hide (copy-recursively)) #:use-module (guix sets) #:use-module (guix progress) + #:autoload (guix store deduplication) (copy-file/deduplicate) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) #:use-module (srfi srfi-26) @@ -37,6 +38,7 @@ file-size closure-size + copy-store-item populate-store)) ;;; Commentary: @@ -169,32 +171,104 @@ REFERENCE-GRAPHS, a list of reference-graph files." (reduce + 0 (map file-size items))) -(define (reset-permissions file) - "Reset the permissions on FILE and its sub-directories so that they are all -read-only." - ;; XXX: This procedure exists just to work around the inability of - ;; 'copy-recursively' to preserve permissions. - (file-system-fold (const #t) ;enter? - (lambda (file stat _) ;leaf - (unless (eq? 'symlink (stat:type stat)) - (chmod file - (if (zero? (logand (stat:mode stat) - #o100)) - #o444 - #o555)))) - (const #t) ;down - (lambda (directory stat _) ;up - (chmod directory #o555)) - (const #f) ;skip - (const #f) ;error +;; TODO: Remove when the one in (guix build utils) has #:keep-permissions?, +;; the fix for <https://bugs.gnu.org/44741>, and when #:keep-mtime? works for +;; symlinks. +(define* (copy-recursively source destination + #:key + (log (current-output-port)) + (follow-symlinks? #f) + (copy-file copy-file) + keep-mtime? keep-permissions?) + "Copy SOURCE directory to DESTINATION. Follow symlinks if FOLLOW-SYMLINKS? +is true; otherwise, just preserve them. Call COPY-FILE to copy regular files. +When KEEP-MTIME? is true, keep the modification time of the files in SOURCE on +those of DESTINATION. When KEEP-PERMISSIONS? is true, preserve file +permissions. Write verbose output to the LOG port." + (define AT_SYMLINK_NOFOLLOW + ;; Guile 2.0 did not define this constant, hence this hack. + (let ((variable (module-variable the-root-module 'AT_SYMLINK_NOFOLLOW))) + (if variable + (variable-ref variable) + 256))) ;for GNU/Linux + + (define (set-file-time file stat) + (utime file + (stat:atime stat) + (stat:mtime stat) + (stat:atimensec stat) + (stat:mtimensec stat) + AT_SYMLINK_NOFOLLOW)) + + (define strip-source + (let ((len (string-length source))) + (lambda (file) + (substring file len)))) + + (file-system-fold (const #t) ; enter? + (lambda (file stat result) ; leaf + (let ((dest (string-append destination + (strip-source file)))) + (format log "`~a' -> `~a'~%" file dest) + (case (stat:type stat) + ((symlink) + (let ((target (readlink file))) + (symlink target dest))) + (else + (copy-file file dest) + (when keep-permissions? + (chmod dest (stat:perms stat))))) + (when keep-mtime? + (set-file-time dest stat)))) + (lambda (dir stat result) ; down + (let ((target (string-append destination + (strip-source dir)))) + (mkdir-p target))) + (lambda (dir stat result) ; up + (let ((target (string-append destination + (strip-source dir)))) + (when keep-mtime? + (set-file-time target stat)) + (when keep-permissions? + (chmod target (stat:perms stat))))) + (const #t) ; skip + (lambda (file stat errno result) + (format (current-error-port) "i/o error: ~a: ~a~%" + file (strerror errno)) + #f) #t - file - lstat)) + source + + (if follow-symlinks? + stat + lstat))) + +(define* (copy-store-item item target + #:key + (deduplicate? #t) + (log-port (%make-void-port "w"))) + "Copy ITEM, a store item, to the store under TARGET, the target root +directory. When DEDUPLICATE? is true, deduplicate it within TARGET." + (define store + (string-append target (%store-directory))) + + (copy-recursively item (string-append target item) + #:keep-mtime? #t + #:keep-permissions? #t + #:copy-file + (if deduplicate? + (cut copy-file/deduplicate <> <> #:store store) + copy-file) + #:log log-port)) (define* (populate-store reference-graphs target - #:key (log-port (current-error-port))) + #:key + (deduplicate? #t) + (log-port (current-error-port))) "Populate the store under directory TARGET with the items specified in -REFERENCE-GRAPHS, a list of reference-graph files." +REFERENCE-GRAPHS, a list of reference-graph files. Items copied to TARGET +maintain timestamps and permissions. When DEDUPLICATE? is true, deduplicate +regular files as they are copied to TARGET." (define store (string-append target (%store-directory))) @@ -218,15 +292,8 @@ REFERENCE-GRAPHS, a list of reference-graph files." (call-with-progress-reporter progress (lambda (report) (for-each (lambda (thing) - (copy-recursively thing - (string-append target thing) - #:keep-mtime? #t - #:log (%make-void-port "w")) - - ;; XXX: Since 'copy-recursively' doesn't allow us to - ;; preserve permissions, we have to traverse TARGET to - ;; make sure everything is read-only. - (reset-permissions (string-append target thing)) + (copy-store-item thing target + #:deduplicate? deduplicate?) (report)) things))))) |