diff options
author | Mark H Weaver <mhw@netris.org> | 2015-04-17 22:06:05 -0400 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2015-04-17 22:06:05 -0400 |
commit | 334345d9db53326fa062298e2372d6c33123949a (patch) | |
tree | 50774c171f1a348bd7de8e9a447bad2a14a9dffb /guix | |
parent | 8d7dc5d9dbf009009d33e21598f92c4685965cd5 (diff) | |
parent | 09dd019490e4a269b0a2d9512a07688f8ee657d3 (diff) | |
download | gnu-guix-334345d9db53326fa062298e2372d6c33123949a.tar gnu-guix-334345d9db53326fa062298e2372d6c33123949a.tar.gz |
Merge branch 'core-updates'
Diffstat (limited to 'guix')
28 files changed, 529 insertions, 312 deletions
diff --git a/guix/build-system/cmake.scm b/guix/build-system/cmake.scm index 0425e9fb39..2e6784251e 100644 --- a/guix/build-system/cmake.scm +++ b/guix/build-system/cmake.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2013 Cyril Roelandt <tipecaml@gmail.com> ;;; ;;; This file is part of GNU Guix. @@ -25,7 +25,8 @@ #:use-module (guix build-system gnu) #:use-module (guix packages) #:use-module (ice-9 match) - #:export (cmake-build + #:export (%cmake-build-system-modules + cmake-build cmake-build-system)) ;; Commentary: @@ -35,6 +36,11 @@ ;; ;; Code: +(define %cmake-build-system-modules + ;; Build-side modules imported by default. + `((guix build cmake-build-system) + ,@%gnu-build-system-modules)) + (define (default-cmake) "Return the default CMake package." @@ -86,9 +92,7 @@ (phases '(@ (guix build cmake-build-system) %standard-phases)) (system (%current-system)) - (imported-modules '((guix build cmake-build-system) - (guix build gnu-build-system) - (guix build utils))) + (imported-modules %cmake-build-system-modules) (modules '((guix build cmake-build-system) (guix build utils)))) "Build SOURCE using CMAKE, and with INPUTS. This assumes that SOURCE diff --git a/guix/build-system/glib-or-gtk.scm b/guix/build-system/glib-or-gtk.scm index 7a90587136..85d01961a5 100644 --- a/guix/build-system/glib-or-gtk.scm +++ b/guix/build-system/glib-or-gtk.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2013 Cyril Roelandt <tipecaml@gmail.com> ;;; Copyright © 2014 Federico Beffa <beffa@fbengineering.ch> ;;; @@ -26,7 +26,8 @@ #:use-module (guix build-system gnu) #:use-module (guix packages) #:use-module (ice-9 match) - #:export (glib-or-gtk-build + #:export (%glib-or-gtk-build-system-modules + glib-or-gtk-build glib-or-gtk-build-system)) ;; Commentary: @@ -67,11 +68,10 @@ '((guix build glib-or-gtk-build-system) (guix build utils))) -(define %default-imported-modules +(define %glib-or-gtk-build-system-modules ;; Build-side modules imported and used by default. - '((guix build gnu-build-system) - (guix build glib-or-gtk-build-system) - (guix build utils))) + `((guix build glib-or-gtk-build-system) + ,@%gnu-build-system-modules)) (define (default-glib) "Return the default glib package from which we use @@ -136,7 +136,7 @@ %standard-phases)) (glib-or-gtk-wrap-excluded-outputs ''()) (system (%current-system)) - (imported-modules %default-imported-modules) + (imported-modules %glib-or-gtk-build-system-modules) (modules %default-modules) allowed-references) "Build SOURCE with INPUTS. See GNU-BUILD for more details." diff --git a/guix/build-system/gnu.scm b/guix/build-system/gnu.scm index c91ad2ee0c..3ccdef1328 100644 --- a/guix/build-system/gnu.scm +++ b/guix/build-system/gnu.scm @@ -24,7 +24,8 @@ #:use-module (guix packages) #:use-module (srfi srfi-1) #:use-module (ice-9 match) - #:export (gnu-build + #:export (%gnu-build-system-modules + gnu-build gnu-build-system standard-packages package-with-explicit-inputs @@ -41,9 +42,16 @@ ;; ;; Code: -(define %default-modules +(define %gnu-build-system-modules ;; Build-side modules imported and used by default. '((guix build gnu-build-system) + (guix build utils) + (guix build gremlin) + (guix elf))) + +(define %default-modules + ;; Modules in scope in the build-side environment. + '((guix build gnu-build-system) (guix build utils))) (define* (package-with-explicit-inputs p inputs @@ -182,7 +190,7 @@ runs `make distcheck' and whose result is one or more source tarballs." (let* ((args (default-keyword-arguments (package-arguments p) `(#:phases #f #:modules ,%default-modules - #:imported-modules ,%default-modules)))) + #:imported-modules ,%gnu-build-system-modules)))) (substitute-keyword-arguments args ((#:modules modules) `((guix build gnu-dist) @@ -277,10 +285,11 @@ standard packages used as implicit inputs of the GNU build system." (strip-flags ''("--strip-debug")) (strip-directories ''("lib" "lib64" "libexec" "bin" "sbin")) + (validate-runpath? #t) (phases '%standard-phases) (locale "en_US.UTF-8") (system (%current-system)) - (imported-modules %default-modules) + (imported-modules %gnu-build-system-modules) (modules %default-modules) (substitutable? #t) allowed-references) @@ -339,6 +348,7 @@ are allowed to refer to." #:parallel-tests? ,parallel-tests? #:patch-shebangs? ,patch-shebangs? #:strip-binaries? ,strip-binaries? + #:validate-runpath? ,validate-runpath? #:strip-flags ,strip-flags #:strip-directories ,strip-directories))) @@ -411,13 +421,12 @@ is one of `host' or `target'." (strip-flags ''("--strip-debug")) (strip-directories ''("lib" "lib64" "libexec" "bin" "sbin")) + (validate-runpath? #t) (phases '%standard-phases) (locale "en_US.UTF-8") (system (%current-system)) - (imported-modules '((guix build gnu-build-system) - (guix build utils))) - (modules '((guix build gnu-build-system) - (guix build utils))) + (imported-modules %gnu-build-system-modules) + (modules %default-modules) (substitutable? #t) allowed-references) "Cross-build NAME for TARGET, where TARGET is a GNU triplet. INPUTS are @@ -486,6 +495,7 @@ platform." #:parallel-tests? ,parallel-tests? #:patch-shebangs? ,patch-shebangs? #:strip-binaries? ,strip-binaries? + #:validate-runpath? ,validate-runpath? #:strip-flags ,strip-flags #:strip-directories ,strip-directories)))) diff --git a/guix/build-system/haskell.scm b/guix/build-system/haskell.scm index 79faa5a09e..0fbf0b8e75 100644 --- a/guix/build-system/haskell.scm +++ b/guix/build-system/haskell.scm @@ -25,7 +25,8 @@ #:use-module (guix build-system gnu) #:use-module (ice-9 match) #:use-module (srfi srfi-26) - #:export (haskell-build + #:export (%haskell-build-system-modules + haskell-build haskell-build-system)) ;; Commentary: @@ -35,6 +36,11 @@ ;; ;; Code: +(define %haskell-build-system-modules + ;; Build-side modules imported by default. + `((guix build haskell-build-system) + ,@%gnu-build-system-modules)) + (define (default-haskell) "Return the default Haskell package." ;; Lazily resolve the binding to avoid a circular dependency. @@ -80,9 +86,7 @@ (search-paths '()) (system (%current-system)) (guile #f) - (imported-modules '((guix build haskell-build-system) - (guix build gnu-build-system) - (guix build utils))) + (imported-modules %haskell-build-system-modules) (modules '((guix build haskell-build-system) (guix build utils)))) "Build SOURCE using HASKELL, and with INPUTS. This assumes that SOURCE diff --git a/guix/build-system/perl.scm b/guix/build-system/perl.scm index e0f86438a8..7833153676 100644 --- a/guix/build-system/perl.scm +++ b/guix/build-system/perl.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -24,7 +24,8 @@ #:use-module (guix build-system gnu) #:use-module (guix packages) #:use-module (ice-9 match) - #:export (perl-build + #:export (%perl-build-system-modules + perl-build perl-build-system)) ;; Commentary: @@ -35,6 +36,11 @@ ;; ;; Code: +(define %perl-build-system-modules + ;; Build-side modules imported by default. + `((guix build perl-build-system) + ,@%gnu-build-system-modules)) + (define (default-perl) "Return the default Perl package." @@ -83,9 +89,7 @@ (outputs '("out")) (system (%current-system)) (guile #f) - (imported-modules '((guix build perl-build-system) - (guix build gnu-build-system) - (guix build utils))) + (imported-modules %perl-build-system-modules) (modules '((guix build perl-build-system) (guix build utils)))) "Build SOURCE using PERL, and with INPUTS. This assumes that SOURCE diff --git a/guix/build-system/python.scm b/guix/build-system/python.scm index 37108650d0..d498cf618b 100644 --- a/guix/build-system/python.scm +++ b/guix/build-system/python.scm @@ -27,7 +27,8 @@ #:use-module (guix build-system gnu) #:use-module (ice-9 match) #:use-module (srfi srfi-26) - #:export (package-with-python2 + #:export (%python-build-system-modules + package-with-python2 python-build python-build-system)) @@ -38,6 +39,11 @@ ;; ;; Code: +(define %python-build-system-modules + ;; Build-side modules imported by default. + `((guix build python-build-system) + ,@%gnu-build-system-modules)) + (define (default-python) "Return the default Python package." ;; Lazily resolve the binding to avoid a circular dependency. @@ -132,9 +138,7 @@ prepended to the name." (search-paths '()) (system (%current-system)) (guile #f) - (imported-modules '((guix build python-build-system) - (guix build gnu-build-system) - (guix build utils))) + (imported-modules %python-build-system-modules) (modules '((guix build python-build-system) (guix build utils)))) "Build SOURCE using PYTHON, and with INPUTS. This assumes that SOURCE diff --git a/guix/build-system/ruby.scm b/guix/build-system/ruby.scm index 08301ec609..83bc93d901 100644 --- a/guix/build-system/ruby.scm +++ b/guix/build-system/ruby.scm @@ -1,6 +1,6 @@ ;;; GNU Guix --- Functional package management for GNU ;;; Copyright © 2014 David Thompson <davet@gnu.org> -;;; Copyright © 2014 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org> ;;; ;;; This file is part of GNU Guix. ;;; @@ -25,9 +25,15 @@ #:use-module (guix build-system) #:use-module (guix build-system gnu) #:use-module (ice-9 match) - #:export (ruby-build + #:export (%ruby-build-system-modules + ruby-build ruby-build-system)) +(define %ruby-build-system-modules + ;; Build-side modules imported by default. + `((guix build ruby-build-system) + ,@%gnu-build-system-modules)) + (define (default-ruby) "Return the default Ruby package." ;; Lazily resolve the binding to avoid a circular dependency. @@ -72,9 +78,7 @@ (search-paths '()) (system (%current-system)) (guile #f) - (imported-modules '((guix build ruby-build-system) - (guix build gnu-build-system) - (guix build utils))) + (imported-modules %ruby-build-system-modules) (modules '((guix build ruby-build-system) (guix build utils)))) "Build SOURCE using RUBY and INPUTS." diff --git a/guix/build-system/waf.scm b/guix/build-system/waf.scm index 494cb957ac..c67f649fa7 100644 --- a/guix/build-system/waf.scm +++ b/guix/build-system/waf.scm @@ -27,7 +27,8 @@ #:select (default-python default-python2)) #:use-module (ice-9 match) #:use-module (srfi srfi-26) - #:export (waf-build + #:export (%waf-build-system-modules + waf-build waf-build-system)) ;; Commentary: @@ -38,6 +39,11 @@ ;; ;; Code: +(define %waf-build-system-modules + ;; Build-side modules imported by default. + `((guix build waf-build-system) + ,@%gnu-build-system-modules)) + (define* (lower name #:key source inputs native-inputs outputs system target (python (default-python)) @@ -75,9 +81,7 @@ (search-paths '()) (system (%current-system)) (guile #f) - (imported-modules '((guix build waf-build-system) - (guix build gnu-build-system) - (guix build utils))) + (imported-modules %waf-build-system-modules) (modules '((guix build waf-build-system) (guix build utils)))) "Build SOURCE with INPUTS. This assumes that SOURCE provides a 'waf' file diff --git a/guix/build/cmake-build-system.scm b/guix/build/cmake-build-system.scm index d8d437c653..f57622e0f4 100644 --- a/guix/build/cmake-build-system.scm +++ b/guix/build/cmake-build-system.scm @@ -73,8 +73,8 @@ ;; Everything is as with the GNU Build System except for the `configure' ;; and 'check' phases. (modify-phases gnu:%standard-phases - (replace check check) - (replace configure configure))) + (replace 'check check) + (replace 'configure configure))) (define* (cmake-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args) diff --git a/guix/build/glib-or-gtk-build-system.scm b/guix/build/glib-or-gtk-build-system.scm index 40f1bb85fa..15d7de2236 100644 --- a/guix/build/glib-or-gtk-build-system.scm +++ b/guix/build/glib-or-gtk-build-system.scm @@ -242,9 +242,9 @@ needed." (define %standard-phases (modify-phases gnu:%standard-phases - (add-after install glib-or-gtk-compile-schemas compile-glib-schemas) - (add-after install glib-or-gtk-icon-cache generate-icon-cache) - (add-after install glib-or-gtk-wrap wrap-all-programs))) + (add-after 'install 'glib-or-gtk-compile-schemas compile-glib-schemas) + (add-after 'install 'glib-or-gtk-icon-cache generate-icon-cache) + (add-after 'install 'glib-or-gtk-wrap wrap-all-programs))) (define* (glib-or-gtk-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args) diff --git a/guix/build/gnu-build-system.scm b/guix/build/gnu-build-system.scm index 5ae537150f..c60f8ba162 100644 --- a/guix/build/gnu-build-system.scm +++ b/guix/build/gnu-build-system.scm @@ -18,12 +18,15 @@ (define-module (guix build gnu-build-system) #:use-module (guix build utils) + #:use-module (guix build gremlin) + #:use-module (guix elf) #:use-module (ice-9 ftw) #:use-module (ice-9 match) #:use-module (ice-9 regex) #:use-module (ice-9 format) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) + #:use-module (rnrs io ports) #:export (%standard-phases gnu-build)) @@ -398,6 +401,64 @@ makefiles." strip-directories))) outputs)))) +(define (every* pred lst) + "This is like 'every', but process all the elements of LST instead of +stopping as soon as PRED returns false. This is useful when PRED has side +effects, such as displaying warnings or error messages." + (let loop ((lst lst) + (result #t)) + (match lst + (() + result) + ((head . tail) + (loop tail (and (pred head) result)))))) + +(define* (validate-runpath #:key + validate-runpath? + (elf-directories '("lib" "lib64" "libexec" + "bin" "sbin")) + outputs #:allow-other-keys) + "When VALIDATE-RUNPATH? is true, validate that all the ELF files in +ELF-DIRECTORIES have their dependencies found in their 'RUNPATH'. + +Since the ELF parser needs to have a copy of files in memory, better run this +phase after stripping." + (define (sub-directory parent) + (lambda (directory) + (let ((directory (string-append parent "/" directory))) + (and (directory-exists? directory) directory)))) + + (define (validate directory) + (define (file=? file1 file2) + (let ((st1 (stat file1)) + (st2 (stat file2))) + (= (stat:ino st1) (stat:ino st2)))) + + ;; There are always symlinks from '.so' to '.so.1' and so on, so delete + ;; duplicates. + (let ((files (delete-duplicates (find-files directory (lambda (file stat) + (elf-file? file))) + file=?))) + (format (current-error-port) + "validating RUNPATH of ~a binaries in ~s...~%" + (length files) directory) + (every* validate-needed-in-runpath files))) + + (if validate-runpath? + (let ((dirs (append-map (match-lambda + (("debug" . _) + ;; The "debug" output is full of ELF files + ;; that are not worth checking. + '()) + ((name . output) + (filter-map (sub-directory output) + elf-directories))) + outputs))) + (every* validate dirs)) + (begin + (format (current-error-port) "skipping RUNPATH validation~%") + #t))) + (define* (validate-documentation-location #:key outputs #:allow-other-keys) "Documentation should go to 'share/info' and 'share/man', not just 'info/' @@ -477,6 +538,16 @@ DOCUMENTATION-COMPRESSOR-FLAGS." (format #t "not compressing documentation~%") #t))) +(define* (delete-info-dir-file #:key outputs #:allow-other-keys) + "Delete any 'share/info/dir' file from OUTPUTS." + (for-each (match-lambda + ((output . directory) + (let ((info-dir-file (string-append directory "/share/info/dir"))) + (when (file-exists? info-dir-file) + (delete-file info-dir-file))))) + outputs) + #t) + (define %standard-phases ;; Standard build phases, as a list of symbol/procedure pairs. (let-syntax ((phases (syntax-rules () @@ -486,7 +557,9 @@ DOCUMENTATION-COMPRESSOR-FLAGS." patch-source-shebangs configure patch-generated-file-shebangs build check install patch-shebangs strip + validate-runpath validate-documentation-location + delete-info-dir-file compress-documentation))) diff --git a/guix/build/gnu-dist.scm b/guix/build/gnu-dist.scm index 887b5e94e9..ad69c6cf16 100644 --- a/guix/build/gnu-dist.scm +++ b/guix/build/gnu-dist.scm @@ -83,10 +83,10 @@ (define %dist-phases ;; Phases for building a source tarball. (modify-phases %standard-phases - (delete strip) - (replace install install-dist) - (replace build build) - (add-before configure autoreconf autoreconf) - (replace unpack copy-source))) + (delete 'strip) + (replace 'install install-dist) + (replace 'build build) + (add-before 'configure 'autoreconf autoreconf) + (replace 'unpack copy-source))) ;;; gnu-dist.scm ends here diff --git a/guix/build/gremlin.scm b/guix/build/gremlin.scm index e8429129e1..30b06034dd 100644 --- a/guix/build/gremlin.scm +++ b/guix/build/gremlin.scm @@ -18,14 +18,22 @@ (define-module (guix build gremlin) #:use-module (guix elf) + #:use-module ((guix build utils) #:select (store-file-name?)) #:use-module (ice-9 match) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) #:use-module (system foreign) #:use-module (rnrs bytevectors) #:use-module (rnrs io ports) - #:export (elf-dynamic-info + #:export (elf-error? + elf-error-elf + invalid-segment-size? + invalid-segment-size-segment + + elf-dynamic-info elf-dynamic-info? elf-dynamic-info-sopath elf-dynamic-info-needed @@ -41,12 +49,31 @@ ;;; ;;; Code: +(define-condition-type &elf-error &error + elf-error? + (elf elf-error-elf)) + +(define-condition-type &invalid-segment-size &elf-error + invalid-segment-size? + (segment invalid-segment-size-segment)) + + (define (dynamic-link-segment elf) "Return the 'PT_DYNAMIC' segment of ELF--i.e., the segment that contains dynamic linking information." - (find (lambda (segment) - (= (elf-segment-type segment) PT_DYNAMIC)) - (elf-segments elf))) + (let ((size (bytevector-length (elf-bytes elf)))) + (find (lambda (segment) + (unless (<= (+ (elf-segment-offset segment) + (elf-segment-filesz segment)) + size) + ;; This happens on separate debug output files created by + ;; 'strip --only-keep-debug' (Binutils 2.25.) + (raise (condition (&invalid-segment-size + (elf elf) + (segment segment))))) + + (= (elf-segment-type segment) PT_DYNAMIC)) + (elf-segments elf)))) (define (word-reader size byte-order) "Return a procedure to read a word of SIZE bytes according to BYTE-ORDER." @@ -197,6 +224,7 @@ value of DT_NEEDED entries is a string.)" "libc.so" "libdl.so" "libm.so" + "libnsl.so" ;NEEDED by nscd "libpthread.so" "libresolv.so" "librt.so" @@ -214,23 +242,42 @@ value of DT_NEEDED entries is a string.)" present in its RUNPATH, or if FILE lacks dynamic-link information. Return #f otherwise. Libraries whose name matches ALWAYS-FOUND? are considered to be always available." - (let* ((elf (call-with-input-file file - (compose parse-elf get-bytevector-all))) - (dyninfo (elf-dynamic-info elf))) - (when dyninfo - (let* ((runpath (elf-dynamic-info-runpath dyninfo)) - (needed (remove always-found? - (elf-dynamic-info-needed dyninfo))) - (not-found (remove (cut search-path runpath <>) - needed))) - (for-each (lambda (lib) - (format (current-error-port) - "error: '~a' depends on '~a', which cannot \ + (guard (c ((invalid-segment-size? c) + (let ((segment (invalid-segment-size-segment c))) + (format (current-error-port) + "~a: error: offset + size of segment ~a (type ~a) \ +exceeds total size~%" + file + (elf-segment-index segment) + (elf-segment-type segment)) + #f))) + + (let* ((elf (call-with-input-file file + (compose parse-elf get-bytevector-all))) + (dyninfo (elf-dynamic-info elf))) + (when dyninfo + (let* ((runpath (filter store-file-name? + (elf-dynamic-info-runpath dyninfo))) + (bogus (remove store-file-name? + (elf-dynamic-info-runpath dyninfo))) + (needed (remove always-found? + (elf-dynamic-info-needed dyninfo))) + (not-found (remove (cut search-path runpath <>) + needed))) + ;; XXX: $ORIGIN is not supported. + (unless (null? bogus) + (format (current-error-port) + "~a: warning: RUNPATH contains bogus entries: ~s~%" + file bogus)) + + (for-each (lambda (lib) + (format (current-error-port) + "~a: error: depends on '~a', which cannot \ be found in RUNPATH ~s~%" - file lib runpath)) - not-found) - ;; (when (null? not-found) - ;; (format (current-error-port) "~a is OK~%" file)) - (null? not-found))))) + file lib runpath)) + not-found) + ;; (when (null? not-found) + ;; (format (current-error-port) "~a is OK~%" file)) + (null? not-found)))))) ;;; gremlin.scm ends here diff --git a/guix/build/haskell-build-system.scm b/guix/build/haskell-build-system.scm index e17967fb72..d382ee403d 100644 --- a/guix/build/haskell-build-system.scm +++ b/guix/build/haskell-build-system.scm @@ -196,13 +196,13 @@ generate the cache as it would clash in user profiles." (define %standard-phases (modify-phases gnu:%standard-phases - (add-before configure setup-compiler setup-compiler) - (add-before install haddock haddock) - (add-after install register register) - (replace install install) - (replace check check) - (replace build build) - (replace configure configure))) + (add-before 'configure 'setup-compiler setup-compiler) + (add-before 'install 'haddock haddock) + (add-after 'install 'register register) + (replace 'install install) + (replace 'check check) + (replace 'build build) + (replace 'configure configure))) (define* (haskell-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args) diff --git a/guix/build/perl-build-system.scm b/guix/build/perl-build-system.scm index 9ca5353bb9..8f480eae16 100644 --- a/guix/build/perl-build-system.scm +++ b/guix/build/perl-build-system.scm @@ -72,10 +72,10 @@ ;; Everything is as with the GNU Build System except for the `configure', ;; `build', `check', and `install' phases. (modify-phases gnu:%standard-phases - (replace install install) - (replace check check) - (replace build build) - (replace configure configure))) + (replace 'install install) + (replace 'check check) + (replace 'build build) + (replace 'configure configure))) (define* (perl-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args) diff --git a/guix/build/python-build-system.scm b/guix/build/python-build-system.scm index 9f853134bd..26a7254db9 100644 --- a/guix/build/python-build-system.scm +++ b/guix/build/python-build-system.scm @@ -123,12 +123,12 @@ installed with setuptools." ;; 'configure' and 'build' phases are not needed. Everything is done during ;; 'install'. (modify-phases gnu:%standard-phases - (delete configure) - (replace install install) - (replace check check) - (replace build build) - (add-after install wrap wrap) - (add-before strip rename-pth-file rename-pth-file))) + (delete 'configure) + (replace 'install install) + (replace 'check check) + (replace 'build build) + (add-after 'install 'wrap wrap) + (add-before 'strip 'rename-pth-file rename-pth-file))) (define* (python-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args) diff --git a/guix/build/ruby-build-system.scm b/guix/build/ruby-build-system.scm index a143df467f..531cf382ae 100644 --- a/guix/build/ruby-build-system.scm +++ b/guix/build/ruby-build-system.scm @@ -72,11 +72,11 @@ directory." (define %standard-phases (modify-phases gnu:%standard-phases - (delete configure) - (add-after unpack gitify gitify) - (replace build build) - (replace install install) - (replace check check))) + (delete 'configure) + (add-after 'unpack 'gitify gitify) + (replace 'build build) + (replace 'install install) + (replace 'check check))) (define* (ruby-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args) diff --git a/guix/build/utils.scm b/guix/build/utils.scm index a5a6167a8c..676a0120e3 100644 --- a/guix/build/utils.scm +++ b/guix/build/utils.scm @@ -32,6 +32,7 @@ #:re-export (alist-cons alist-delete) #:export (%store-directory + store-file-name? parallel-job-count directory-exists? @@ -44,6 +45,7 @@ mkdir-p copy-recursively delete-file-recursively + file-name-predicate find-files search-path-as-list @@ -80,6 +82,10 @@ (or (getenv "NIX_STORE") "/gnu/store")) +(define (store-file-name? file) + "Return true if FILE is in the store." + (string-prefix? (%store-directory) file)) + (define parallel-job-count ;; Number of processes to be passed next to GNU Make's `-j' argument. (make-parameter @@ -263,33 +269,46 @@ errors." ;; Don't follow symlinks. lstat))) -(define (find-files dir regexp) - "Return the lexicographically sorted list of files under DIR whose basename -matches REGEXP." - (define file-rx - (if (regexp? regexp) - regexp - (make-regexp regexp))) - - ;; Sort the result to get deterministic results. - (sort (file-system-fold (const #t) - (lambda (file stat result) ; leaf - (if (regexp-exec file-rx (basename file)) - (cons file result) - result)) - (lambda (dir stat result) ; down - result) - (lambda (dir stat result) ; up - result) - (lambda (file stat result) ; skip - result) - (lambda (file stat errno result) - (format (current-error-port) "find-files: ~a: ~a~%" - file (strerror errno)) - result) - '() - dir) - string<?)) +(define (file-name-predicate regexp) + "Return a predicate that returns true when passed a file name whose base +name matches REGEXP." + (let ((file-rx (if (regexp? regexp) + regexp + (make-regexp regexp)))) + (lambda (file stat) + (regexp-exec file-rx (basename file))))) + +(define* (find-files dir #:optional (pred (const #t)) + #:key (stat lstat)) + "Return the lexicographically sorted list of files under DIR for which PRED +returns true. PRED is passed two arguments: the absolute file name, and its +stat buffer; the default predicate always returns true. PRED can also be a +regular expression, in which case it is equivalent to (file-name-predicate +PRED). STAT is used to obtain file information; using 'lstat' means that +symlinks are not followed." + (let ((pred (if (procedure? pred) + pred + (file-name-predicate pred)))) + ;; Sort the result to get deterministic results. + (sort (file-system-fold (const #t) + (lambda (file stat result) ; leaf + (if (pred file stat) + (cons file result) + result)) + (lambda (dir stat result) ; down + result) + (lambda (dir stat result) ; up + result) + (lambda (file stat result) ; skip + result) + (lambda (file stat errno result) + (format (current-error-port) "find-files: ~a: ~a~%" + file (strerror errno)) + result) + '() + dir + stat) + string<?))) ;;; @@ -446,13 +465,13 @@ an expression evaluating to a procedure." (define-syntax %modify-phases (syntax-rules (delete replace add-before add-after) ((_ phases (delete old-phase-name)) - (alist-delete 'old-phase-name phases)) + (alist-delete old-phase-name phases)) ((_ phases (replace old-phase-name new-phase)) - (alist-replace 'old-phase-name new-phase phases)) + (alist-replace old-phase-name new-phase phases)) ((_ phases (add-before old-phase-name new-phase-name new-phase)) - (alist-cons-before 'old-phase-name 'new-phase-name new-phase phases)) + (alist-cons-before old-phase-name new-phase-name new-phase phases)) ((_ phases (add-after old-phase-name new-phase-name new-phase)) - (alist-cons-after 'old-phase-name 'new-phase-name new-phase phases)))) + (alist-cons-after old-phase-name new-phase-name new-phase phases)))) ;;; diff --git a/guix/build/waf-build-system.scm b/guix/build/waf-build-system.scm index d172c5a836..85f0abcfd6 100644 --- a/guix/build/waf-build-system.scm +++ b/guix/build/waf-build-system.scm @@ -70,10 +70,10 @@ (define %standard-phases (modify-phases gnu:%standard-phases - (replace configure configure) - (replace build build) - (replace check check) - (replace install install))) + (replace 'configure configure) + (replace 'build build) + (replace 'check check) + (replace 'install install))) (define* (waf-build #:key inputs (phases %standard-phases) #:allow-other-keys #:rest args) diff --git a/guix/cvs-download.scm b/guix/cvs-download.scm index 8a0d479fa4..72478dd2c2 100644 --- a/guix/cvs-download.scm +++ b/guix/cvs-download.scm @@ -66,7 +66,7 @@ HASH-ALGO (a symbol). Use NAME as the file name, or a generic name if #f." '#$(cvs-reference-module ref) '#$(cvs-reference-revision ref) #$output - #:cvs-command (string-append #$cvs "/bin/cvs")))) + #:cvs-command (string-append #+cvs "/bin/cvs")))) (mlet %store-monad ((guile (package->derivation guile system))) (gexp->derivation (or name "cvs-checkout") build diff --git a/guix/download.scm b/guix/download.scm index d87d02e2af..3e4024fe1f 100644 --- a/guix/download.scm +++ b/guix/download.scm @@ -241,12 +241,12 @@ in the store." (define builder #~(begin - #$(if need-gnutls? + #+(if need-gnutls? ;; Add GnuTLS to the inputs and to the load path. #~(eval-when (load expand eval) (set! %load-path - (cons (string-append #$(gnutls-package) + (cons (string-append #+(gnutls-package) "/share/guile/site/" (effective-version)) %load-path))) diff --git a/guix/git-download.scm b/guix/git-download.scm index 94a1245480..f4b48d7a6b 100644 --- a/guix/git-download.scm +++ b/guix/git-download.scm @@ -76,7 +76,7 @@ HASH-ALGO (a symbol). Use NAME as the file name, or a generic name if #f." ;; The 'git submodule' commands expects Coreutils, sed, ;; grep, etc. to be in $PATH. (set-path-environment-variable "PATH" '("bin") - (match '#$inputs + (match '#+inputs (((names dirs) ...) dirs))) @@ -84,7 +84,7 @@ HASH-ALGO (a symbol). Use NAME as the file name, or a generic name if #f." '#$(git-reference-commit ref) #$output #:recursive? '#$(git-reference-recursive? ref) - #:git-command (string-append #$git "/bin/git")))) + #:git-command (string-append #+git "/bin/git")))) (mlet %store-monad ((guile (package->derivation guile system))) (gexp->derivation (or name "git-checkout") build diff --git a/guix/packages.scm b/guix/packages.scm index ec0e79d08b..8ebe8d06b5 100644 --- a/guix/packages.scm +++ b/guix/packages.scm @@ -26,6 +26,7 @@ #:use-module (guix base32) #:use-module (guix derivations) #:use-module (guix build-system) + #:use-module (guix gexp) #:use-module (ice-9 match) #:use-module (ice-9 vlist) #:use-module (srfi srfi-1) @@ -106,6 +107,7 @@ package->bag bag->derivation + bag-direct-inputs bag-transitive-inputs bag-transitive-host-inputs bag-transitive-build-inputs @@ -334,8 +336,10 @@ corresponds to the arguments expected by `set-path-environment-variable'." ("bzip2" ,(ref '(gnu packages compression) 'bzip2)) ("gzip" ,(ref '(gnu packages compression) 'gzip)) ("lzip" ,(ref '(gnu packages compression) 'lzip)) + ("unzip" ,(ref '(gnu packages zip) 'unzip)) ("patch" ,(ref '(gnu packages base) 'patch)) - ("locales" ,(ref '(gnu packages base) 'glibc-utf8-locales))))) + ("locales" ,(ref '(gnu packages commencement) + 'glibc-utf8-locales-final))))) (define (default-guile) "Return the default Guile package used to run the build code of @@ -349,10 +353,9 @@ the build code of derivation." (package->derivation (default-guile) system #:graft? #f)) -;; TODO: Rewrite using %STORE-MONAD and gexps. -(define* (patch-and-repack store source patches +(define* (patch-and-repack source patches #:key - (inputs '()) + inputs (snippet #f) (flags '("-p1")) (modules '()) @@ -370,10 +373,20 @@ IMPORTED-MODULES specify modules to use/import for use by SNIPPET." (derivation->output-path source) source)) + (define lookup-input + ;; The default value of the 'patch-inputs' field, and thus INPUTS is #f, + ;; so deal with that. + (let ((inputs (or inputs (%standard-patch-inputs)))) + (lambda (name) + (match (assoc-ref inputs name) + ((package) package) + (#f #f))))) + (define decompression-type (cond ((string-suffix? "gz" source-file-name) "gzip") ((string-suffix? "bz2" source-file-name) "bzip2") ((string-suffix? "lz" source-file-name) "lzip") + ((string-suffix? "zip" source-file-name) "unzip") (else "xz"))) (define original-file-name @@ -398,115 +411,95 @@ IMPORTED-MODULES specify modules to use/import for use by SNIPPET." ".xz" ".tar.xz")))) - (define patch-inputs - (map (lambda (number patch) - (list (string-append "patch" (number->string number)) - (match patch - ((? string?) - (add-to-store store (basename patch) #t - "sha256" patch)) - ((? origin?) - (package-source-derivation store patch system))))) - (iota (length patches)) - - patches)) - - (define builder - `(begin - (use-modules (ice-9 ftw) - (srfi srfi-1) - (guix build utils)) - - ;; Encoding/decoding errors shouldn't be silent. - (fluid-set! %default-port-conversion-strategy 'error) - - (let ((locales (assoc-ref %build-inputs "locales")) - (out (assoc-ref %outputs "out")) - (xz (assoc-ref %build-inputs "xz")) - (decomp (assoc-ref %build-inputs ,decompression-type)) - (source (assoc-ref %build-inputs "source")) - (tar (string-append (assoc-ref %build-inputs "tar") - "/bin/tar")) - (patch (string-append (assoc-ref %build-inputs "patch") - "/bin/patch"))) - (define (apply-patch input) - (let ((patch* (assoc-ref %build-inputs input))) - (format (current-error-port) "applying '~a'...~%" patch*) - - ;; Use '--force' so that patches that do not apply perfectly are - ;; rejected. - (zero? (system* patch "--force" ,@flags "--input" patch*)))) - - (define (first-file directory) - ;; Return the name of the first file in DIRECTORY. - (car (scandir directory - (lambda (name) - (not (member name '("." ".."))))))) - - (when locales - ;; First of all, install a UTF-8 locale so that UTF-8 file names - ;; are correctly interpreted. During bootstrap, LOCALES is #f. - (setenv "LOCPATH" (string-append locales "/lib/locale")) - (setlocale LC_ALL "en_US.UTF-8")) - - (setenv "PATH" (string-append xz "/bin" ":" - decomp "/bin")) - - ;; SOURCE may be either a directory or a tarball. - (and (if (file-is-directory? source) - (let* ((store (or (getenv "NIX_STORE") "/gnu/store")) - (len (+ 1 (string-length store))) - (base (string-drop source len)) - (dash (string-index base #\-)) - (directory (string-drop base (+ 1 dash)))) - (mkdir directory) - (copy-recursively source directory) - #t) - (zero? (system* tar "xvf" source))) - (let ((directory (first-file "."))) - (format (current-error-port) - "source is under '~a'~%" directory) - (chdir directory) - - (and (every apply-patch ',(map car patch-inputs)) - - ,@(if snippet - `((let ((module (make-fresh-user-module))) - (module-use-interfaces! module - (map resolve-interface - ',modules)) - (module-define! module '%build-inputs - %build-inputs) - (module-define! module '%outputs %outputs) - ((@ (system base compile) compile) - ',snippet - #:to 'value - #:opts %auto-compilation-options - #:env module))) - '()) - - (begin (chdir "..") #t) - (zero? (system* tar "cvfa" out directory)))))))) - - - (let ((name (tarxz-name original-file-name)) - (inputs (filter-map (match-lambda - ((name (? package? p)) - (and (member name (cons decompression-type - '("tar" "xz" "patch"))) - (list name - (package-derivation store p system - #:graft? #f))))) - (or inputs (%standard-patch-inputs)))) - (modules (delete-duplicates (cons '(guix build utils) modules)))) - - (build-expression->derivation store name builder - #:inputs `(("source" ,source) - ,@inputs - ,@patch-inputs) - #:system system - #:modules modules - #:guile-for-build guile-for-build))) + (define instantiate-patch + (match-lambda + ((? string? patch) + (interned-file patch #:recursive? #t)) + ((? origin? patch) + (origin->derivation patch system)))) + + (mlet %store-monad ((tar -> (lookup-input "tar")) + (xz -> (lookup-input "xz")) + (patch -> (lookup-input "patch")) + (locales -> (lookup-input "locales")) + (decomp -> (lookup-input decompression-type)) + (patches (sequence %store-monad + (map instantiate-patch patches)))) + (define build + #~(begin + (use-modules (ice-9 ftw) + (srfi srfi-1) + (guix build utils)) + + (define (apply-patch patch) + (format (current-error-port) "applying '~a'...~%" patch) + + ;; Use '--force' so that patches that do not apply perfectly are + ;; rejected. + (zero? (system* (string-append #+patch "/bin/patch") + "--force" #+@flags "--input" patch))) + + (define (first-file directory) + ;; Return the name of the first file in DIRECTORY. + (car (scandir directory + (lambda (name) + (not (member name '("." ".."))))))) + + ;; Encoding/decoding errors shouldn't be silent. + (fluid-set! %default-port-conversion-strategy 'error) + + (when #+locales + ;; First of all, install a UTF-8 locale so that UTF-8 file names + ;; are correctly interpreted. During bootstrap, LOCALES is #f. + (setenv "LOCPATH" (string-append #+locales "/lib/locale")) + (setlocale LC_ALL "en_US.UTF-8")) + + (setenv "PATH" (string-append #+xz "/bin" ":" + #+decomp "/bin")) + + ;; SOURCE may be either a directory or a tarball. + (and (if (file-is-directory? #+source) + (let* ((store (or (getenv "NIX_STORE") "/gnu/store")) + (len (+ 1 (string-length store))) + (base (string-drop #+source len)) + (dash (string-index base #\-)) + (directory (string-drop base (+ 1 dash)))) + (mkdir directory) + (copy-recursively #+source directory) + #t) + #+(if (string=? decompression-type "unzip") + #~(zero? (system* "unzip" #+source)) + #~(zero? (system* (string-append #+tar "/bin/tar") + "xvf" #+source)))) + (let ((directory (first-file "."))) + (format (current-error-port) + "source is under '~a'~%" directory) + (chdir directory) + + (and (every apply-patch '#+patches) + #+@(if snippet + #~((let ((module (make-fresh-user-module))) + (module-use-interfaces! module + (map resolve-interface + '#+modules)) + ((@ (system base compile) compile) + '#+snippet + #:to 'value + #:opts %auto-compilation-options + #:env module))) + #~()) + + (begin (chdir "..") #t) + (zero? (system* (string-append #+tar "/bin/tar") + "cvfa" #$output directory))))))) + + (let ((name (tarxz-name original-file-name)) + (modules (delete-duplicates (cons '(guix build utils) modules)))) + (gexp->derivation name build + #:graft? #f + #:system system + #:modules modules + #:guile-for-build guile-for-build)))) (define (transitive-inputs inputs) (let loop ((inputs inputs) @@ -586,13 +579,17 @@ supported by its dependencies." (_ systems))) (package-supported-systems package) - (package-direct-inputs package))) + (bag-direct-inputs (package->bag package)))) + +(define (bag-direct-inputs bag) + "Same as 'package-direct-inputs', but applied to a bag." + (append (bag-build-inputs bag) + (bag-host-inputs bag) + (bag-target-inputs bag))) (define (bag-transitive-inputs bag) "Same as 'package-transitive-inputs', but applied to a bag." - (transitive-inputs (append (bag-build-inputs bag) - (bag-host-inputs bag) - (bag-target-inputs bag)))) + (transitive-inputs (bag-direct-inputs bag))) (define (bag-transitive-build-inputs bag) "Same as 'package-transitive-native-inputs', but applied to a bag." @@ -954,9 +951,6 @@ cross-compilation target triplet." (package->cross-derivation package target system) (package->derivation package system))) -(define patch-and-repack* - (store-lift patch-and-repack)) - (define* (origin->derivation source #:optional (system (%current-system))) "When SOURCE is an <origin> object, return its derivation for SYSTEM. When @@ -976,14 +970,14 @@ outside of the store) or SOURCE itself (if SOURCE is already a store item.)" (default-guile)) system #:graft? #f))) - (patch-and-repack* source patches - #:inputs inputs - #:snippet snippet - #:flags flags - #:system system - #:modules modules - #:imported-modules modules - #:guile-for-build guile))) + (patch-and-repack source patches + #:inputs inputs + #:snippet snippet + #:flags flags + #:system system + #:modules modules + #:imported-modules modules + #:guile-for-build guile))) ((and (? string?) (? direct-store-path?) file) (with-monad %store-monad (return file))) diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm index c40d76b558..cced1bda66 100644 --- a/guix/scripts/lint.scm +++ b/guix/scripts/lint.scm @@ -19,6 +19,7 @@ ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. (define-module (guix scripts lint) + #:use-module (guix store) #:use-module (guix base32) #:use-module (guix download) #:use-module (guix ftp-client) @@ -32,6 +33,8 @@ #:use-module (ice-9 regex) #:use-module (ice-9 format) #:use-module (web uri) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) #:use-module ((guix build download) #:select (maybe-expand-mirrors open-connection-for-uri)) @@ -41,12 +44,15 @@ #:use-module (srfi srfi-9) #:use-module (srfi srfi-11) #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) #:use-module (srfi srfi-37) #:export (guix-lint check-description-style check-inputs-should-be-native - check-patches + check-patch-file-names check-synopsis-style + check-derivation check-home-page check-source)) @@ -348,26 +354,30 @@ warning for PACKAGE mentionning the FIELD." (package-home-page package)) 'home-page))))) -(define (check-patches package) - ;; Emit a warning if the patches requires by PACKAGE are badly named. - (let ((patches (and=> (package-source package) origin-patches)) - (name (package-name package)) - (full-name (package-full-name package))) - (when (and patches - (any (match-lambda - ((? string? patch) - (let ((filename (basename patch))) - (not (or (eq? (string-contains filename name) 0) - (eq? (string-contains filename full-name) - 0))))) - (_ - ;; This must be an <origin> or something like that. - #f)) - patches)) - (emit-warning package - (_ "file names of patches should start with \ +(define (check-patch-file-names package) + "Emit a warning if the patches requires by PACKAGE are badly named or if the +patch could not be found." + (guard (c ((message-condition? c) ;raised by 'search-patch' + (emit-warning package (condition-message c) + 'patch-file-names))) + (let ((patches (and=> (package-source package) origin-patches)) + (name (package-name package)) + (full-name (package-full-name package))) + (when (and patches + (any (match-lambda + ((? string? patch) + (let ((file (basename patch))) + (not (or (eq? (string-contains file name) 0) + (eq? (string-contains file full-name) + 0))))) + (_ + ;; This must be an <origin> or something like that. + #f)) + patches)) + (emit-warning package + (_ "file names of patches should start with \ the package name") - 'patches)))) + 'patch-file-names))))) (define (escape-quotes str) "Replace any quote character in STR by an escaped quote character." @@ -434,6 +444,25 @@ descriptions maintained upstream." (append-map (cut maybe-expand-mirrors <> %mirrors) uris)))))) +(define (check-derivation package) + "Emit a warning if we fail to compile PACKAGE to a derivation." + (catch #t + (lambda () + (guard (c ((nix-protocol-error? c) + (emit-warning package + (format #f (_ "failed to create derivation: ~a") + (nix-protocol-error-message c)))) + ((message-condition? c) + (emit-warning package + (format #f (_ "failed to create derivation: ~a") + (condition-message c))))) + (with-store store + (package-derivation store package)))) + (lambda args + (emit-warning package + (format #f (_ "failed to create derivation: ~s~%") + args))))) + ;;; @@ -455,9 +484,9 @@ descriptions maintained upstream." (description "Identify inputs that should be native inputs") (check check-inputs-should-be-native)) (lint-checker - (name 'patch-filenames) - (description "Validate file names of patches") - (check check-patches)) + (name 'patch-file-names) + (description "Validate file names and availability of patches") + (check check-patch-file-names)) (lint-checker (name 'home-page) (description "Validate home-page URLs") @@ -467,6 +496,10 @@ descriptions maintained upstream." (description "Validate source URLs") (check check-source)) (lint-checker + (name 'derivation) + (description "Report failure to compile a package to a derivation") + (check check-derivation)) + (lint-checker (name 'synopsis) (description "Validate package synopses") (check check-synopsis-style)))) diff --git a/guix/scripts/refresh.scm b/guix/scripts/refresh.scm index 04886499a2..28519d78e2 100644 --- a/guix/scripts/refresh.scm +++ b/guix/scripts/refresh.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org> +;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org> ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org> ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org> ;;; @@ -207,16 +207,13 @@ update would trigger a complete rebuild." (list-dependent? (assoc-ref opts 'list-dependent?)) (key-download (assoc-ref opts 'key-download)) (packages - (match (concatenate - (filter-map (match-lambda - (('argument . value) - (let ((p (find-packages-by-name value))) - (when (null? p) - (leave (_ "~a: no package by that name~%") - value)) - p)) + (match (filter-map (match-lambda + (('argument . spec) + ;; Take either the specified version or the + ;; latest one. + (specification->package spec)) (_ #f)) - opts)) + opts) (() ; default to all packages (let ((select? (match (assoc-ref opts 'select) ('core core-package?) diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm index 1b64e6fb92..1838e89452 100644 --- a/guix/scripts/system.scm +++ b/guix/scripts/system.scm @@ -69,21 +69,7 @@ (set-current-module %user-module) (primitive-load file)))) (lambda args - (match args - (('system-error . _) - (let ((err (system-error-errno args))) - (leave (_ "failed to open operating system file '~a': ~a~%") - file (strerror err)))) - (('syntax-error proc message properties form . rest) - (let ((loc (source-properties->location properties))) - (format (current-error-port) (_ "~a: error: ~a~%") - (location->string loc) message) - (exit 1))) - ((error args ...) - (report-error (_ "failed to load operating system file '~a':~%") - file) - (apply display-error #f (current-error-port) args) - (exit 1)))))) + (report-load-error file args)))) ;;; diff --git a/guix/svn-download.scm b/guix/svn-download.scm index 92b03d13f3..d6853ca861 100644 --- a/guix/svn-download.scm +++ b/guix/svn-download.scm @@ -62,7 +62,7 @@ HASH-ALGO (a symbol). Use NAME as the file name, or a generic name if #f." (svn-fetch '#$(svn-reference-url ref) '#$(svn-reference-revision ref) #$output - #:svn-command (string-append #$svn "/bin/svn")))) + #:svn-command (string-append #+svn "/bin/svn")))) (mlet %store-monad ((guile (package->derivation guile system))) (gexp->derivation (or name "svn-checkout") build diff --git a/guix/ui.scm b/guix/ui.scm index 67c65aa14d..5ca5afe457 100644 --- a/guix/ui.scm +++ b/guix/ui.scm @@ -47,6 +47,8 @@ P_ report-error leave + report-load-error + warn-about-load-error show-version-and-exit show-bug-report-information string->number* @@ -130,6 +132,38 @@ messages." (report-error args ...) (exit 1))) +(define (report-load-error file args) + "Report the failure to load FILE, a user-provided Scheme file, and exit. +ARGS is the list of arguments received by the 'throw' handler." + (match args + (('system-error . _) + (let ((err (system-error-errno args))) + (leave (_ "failed to load '~a': ~a~%") file (strerror err)))) + (('syntax-error proc message properties form . rest) + (let ((loc (source-properties->location properties))) + (format (current-error-port) (_ "~a: error: ~a~%") + (location->string loc) message) + (exit 1))) + ((error args ...) + (report-error (_ "failed to load '~a':~%") file) + (apply display-error #f (current-error-port) args) + (exit 1)))) + +(define (warn-about-load-error file args) ;FIXME: factorize with ↑ + "Report the failure to load FILE, a user-provided Scheme file, without +exiting. ARGS is the list of arguments received by the 'throw' handler." + (match args + (('system-error . _) + (let ((err (system-error-errno args))) + (warning (_ "failed to load '~a': ~a~%") file (strerror err)))) + (('syntax-error proc message properties form . rest) + (let ((loc (source-properties->location properties))) + (format (current-error-port) (_ "~a: warning: ~a~%") + (location->string loc) message))) + ((error args ...) + (warning (_ "failed to load '~a':~%") file) + (apply display-error #f (current-error-port) args)))) + (define (install-locale) "Install the current locale settings." (catch 'system-error |