summaryrefslogtreecommitdiff
path: root/guix
diff options
context:
space:
mode:
authorMarius Bakke <mbakke@fastmail.com>2020-02-03 15:45:44 +0100
committerMarius Bakke <mbakke@fastmail.com>2020-02-03 15:45:44 +0100
commit52665d2b6bd709ba46c1e364a6d6164f5f4824ff (patch)
tree55fd79b3939c08f6f6e9fe383f0df5e4caa82b57 /guix
parent584d08c5c98cb1893e4f44bd1c4191f405b13f01 (diff)
parent0a83339bb1429332ee889e9a976aa214ae2ac0db (diff)
downloadpatches-52665d2b6bd709ba46c1e364a6d6164f5f4824ff.tar
patches-52665d2b6bd709ba46c1e364a6d6164f5f4824ff.tar.gz
Merge branch 'staging' into core-updates
Diffstat (limited to 'guix')
-rw-r--r--guix/build-system/ocaml.scm20
-rw-r--r--guix/build/cargo-build-system.scm6
-rw-r--r--guix/build/compile.scm6
-rw-r--r--guix/build/qt-build-system.scm14
-rw-r--r--guix/derivations.scm7
-rw-r--r--guix/licenses.scm2
-rw-r--r--guix/scripts/archive.scm65
-rw-r--r--guix/scripts/build.scm131
-rw-r--r--guix/scripts/graph.scm27
-rw-r--r--guix/self.scm25
-rw-r--r--guix/serialization.scm19
-rw-r--r--guix/ui.scm11
12 files changed, 191 insertions, 142 deletions
diff --git a/guix/build-system/ocaml.scm b/guix/build-system/ocaml.scm
index de3e71a5aa..c5996bf0cf 100644
--- a/guix/build-system/ocaml.scm
+++ b/guix/build-system/ocaml.scm
@@ -92,7 +92,11 @@
(let ((module (resolve-interface '(gnu packages ocaml))))
(module-ref module 'ocaml4.07-findlib)))
-(define* (package-with-explicit-ocaml ocaml findlib old-prefix new-prefix
+(define (default-ocaml4.07-dune)
+ (let ((module (resolve-interface '(gnu packages ocaml))))
+ (module-ref module 'ocaml4.07-dune)))
+
+(define* (package-with-explicit-ocaml ocaml findlib dune old-prefix new-prefix
#:key variant-property)
"Return a procedure of one argument, P. The procedure creates a package
with the same fields as P, which is assumed to use OCAML-BUILD-SYSTEM, such
@@ -100,6 +104,10 @@ that it is compiled with OCAML and FINDLIB instead. The inputs are changed
recursively accordingly. If the name of P starts with OLD-PREFIX, this is
replaced by NEW-PREFIX; otherwise, NEW-PREFIX is prepended to the name.
+When the package uses the DUNE-BUILD-SYSTEM, the procedure creates a package
+with the same fields as P, such that it is compiled with OCAML, FINDLIB and DUNE
+instead.
+
When VARIANT-PROPERTY is present, it is used as a key to search for
pre-defined variants of this transformation recorded in the 'properties' field
of packages. The property value must be the promise of a package. This is a
@@ -132,10 +140,15 @@ pre-defined variants."
name))))
(arguments
(let ((ocaml (if (promise? ocaml) (force ocaml) ocaml))
- (findlib (if (promise? findlib) (force findlib) findlib)))
+ (findlib (if (promise? findlib) (force findlib) findlib))
+ (dune (if (promise? dune) (force dune) dune)))
(ensure-keyword-arguments (package-arguments p)
`(#:ocaml ,ocaml
- #:findlib ,findlib))))))
+ #:findlib ,findlib
+ ,@(if (eq? (package-build-system p)
+ (default-dune-build-system))
+ `(#:dune ,dune)
+ '())))))))
(else p)))
(define (cut? p)
@@ -148,6 +161,7 @@ pre-defined variants."
(define package-with-ocaml4.07
(package-with-explicit-ocaml (delay (default-ocaml4.07))
(delay (default-ocaml4.07-findlib))
+ (delay (default-ocaml4.07-dune))
"ocaml-" "ocaml4.07-"
#:variant-property 'ocaml4.07-variant))
diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-system.scm
index 8a8d74ee1b..0721989589 100644
--- a/guix/build/cargo-build-system.scm
+++ b/guix/build/cargo-build-system.scm
@@ -2,7 +2,7 @@
;;; Copyright © 2016 David Craven <david@craven.ch>
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
;;; Copyright © 2019 Ivan Petkov <ivanppetkov@gmail.com>
-;;; Copyright © 2019 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2019, 2020 Efraim Flashner <efraim@flashner.co.il>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -58,7 +58,7 @@
(define (crate-src? path)
"Check if PATH refers to a crate source, namely a gzipped tarball with a
Cargo.toml file present at its root."
- (and (gzip-file? path)
+ (and (not (directory-exists? path)) ; not a tarball
;; First we print out all file names within the tarball to see if it
;; looks like the source of a crate. However, the tarball will include
;; an extra path component which we would like to ignore (since we're
@@ -119,6 +119,8 @@ directory = '" port)
;; upgrading the compiler for example.
(setenv "RUSTFLAGS" "--cap-lints allow")
(setenv "CC" (string-append (assoc-ref inputs "gcc") "/bin/gcc"))
+ (setenv "LIBGIT2_SYS_USE_PKG_CONFIG" "1")
+ (setenv "LIBSSH2_SYS_USE_PKG_CONFIG" "1")
;; We don't use the Cargo.lock file to determine the package versions we use
;; during building, and in any case if one is not present it is created
diff --git a/guix/build/compile.scm b/guix/build/compile.scm
index 3781e148ce..4b6472784c 100644
--- a/guix/build/compile.scm
+++ b/guix/build/compile.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
;;;
;;; This file is part of GNU Guix.
@@ -29,9 +29,7 @@
#:use-module (guix build utils)
#:use-module (language tree-il optimize)
#:use-module (language cps optimize)
- #:export (%default-optimizations
- %lightweight-optimizations
- compile-files))
+ #:export (compile-files))
;;; Commentary:
;;;
diff --git a/guix/build/qt-build-system.scm b/guix/build/qt-build-system.scm
index be2b808901..005157b0a4 100644
--- a/guix/build/qt-build-system.scm
+++ b/guix/build/qt-build-system.scm
@@ -2,7 +2,7 @@
;;; Copyright © 2014 Federico Beffa <beffa@fbengineering.ch>
;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
-;;; Copyright © 2019 Hartmut Goebel <h.goebel@crazy-compilers.com>
+;;; Copyright © 2019, 2020 Hartmut Goebel <h.goebel@crazy-compilers.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -36,6 +36,17 @@
;;
;; Code:
+(define* (check-setup #:rest args)
+ ;; Make Qt render "offscreen". In many cases this allows to run tests
+ ;; without starting a X11 server.
+ (setenv "QT_QPA_PLATFORM" "offscreen")
+ ;; Qt/KDE tests often need dbus (`dbus-launch …`) which is not fully
+ ;; set-up the the build container.
+ (setenv "DBUS_FATAL_WARNINGS" "0")
+ ;; Set here to ease overwriting 'check (even if set there, too)
+ (setenv "CTEST_OUTPUT_ON_FAILURE" "1")
+ #t)
+
(define (variables-for-wrapping base-directories)
(define (collect-sub-dirs base-directories subdirectory)
@@ -101,6 +112,7 @@ add a dependency of that output on Qt."
(define %standard-phases
(modify-phases cmake:%standard-phases
+ (add-before 'check 'check-setup check-setup)
(add-after 'install 'qt-wrap wrap-all-programs)))
(define* (qt-build #:key inputs (phases %standard-phases)
diff --git a/guix/derivations.scm b/guix/derivations.scm
index 16aa95d2c7..7db61d272f 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -240,6 +240,13 @@ the store."
"Return a list of inputs, such that when INPUTS contains the same DRV twice,
they are coalesced, with their sub-derivations merged. This is needed because
Nix itself keeps only one of them."
+ (define (find pred lst) ;inlinable copy of 'find'
+ (let loop ((lst lst))
+ (match lst
+ (() #f)
+ ((head . tail)
+ (if (pred head) head (loop tail))))))
+
(fold (lambda (input result)
(match input
(($ <derivation-input> (= derivation-file-name path) sub-drvs)
diff --git a/guix/licenses.scm b/guix/licenses.scm
index 41d4fefad2..a44a5bac0d 100644
--- a/guix/licenses.scm
+++ b/guix/licenses.scm
@@ -286,7 +286,7 @@ at URI, which may be a file:// URI pointing the package's tree."
(define giftware
(license "Giftware"
- "http://liballeg.org/license.html"
+ "https://liballeg.org/license.html"
"The Allegro 4 license"))
(define gpl1
diff --git a/guix/scripts/archive.scm b/guix/scripts/archive.scm
index 2b4d39c7b8..4f39920fe7 100644
--- a/guix/scripts/archive.scm
+++ b/guix/scripts/archive.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -371,36 +371,33 @@ output port."
(cons line result)))))
(with-error-handling
- ;; Ask for absolute file names so that .drv file names passed from the
- ;; user to 'read-derivation' are absolute when it returns.
- (with-fluids ((%file-port-name-canonicalization 'absolute))
- (let ((opts (parse-command-line args %options (list %default-options))))
- (parameterize ((%graft? (assoc-ref opts 'graft?)))
- (cond ((assoc-ref opts 'generate-key)
- =>
- generate-key-pair)
- ((assoc-ref opts 'authorize)
- (authorize-key))
- (else
- (with-status-verbosity (assoc-ref opts 'verbosity)
- (with-store store
- (set-build-options-from-command-line store opts)
- (cond ((assoc-ref opts 'export)
- (export-from-store store opts))
- ((assoc-ref opts 'import)
- (import-paths store (current-input-port)))
- ((assoc-ref opts 'missing)
- (let* ((files (lines (current-input-port)))
- (missing (remove (cut valid-path? store <>)
- files)))
- (format #t "~{~a~%~}" missing)))
- ((assoc-ref opts 'list)
- (list-contents (current-input-port)))
- ((assoc-ref opts 'extract)
- =>
- (lambda (target)
- (restore-file (current-input-port) target)))
- (else
- (leave
- (G_ "either '--export' or '--import' \
-must be specified~%")))))))))))))
+ (let ((opts (parse-command-line args %options (list %default-options))))
+ (parameterize ((%graft? (assoc-ref opts 'graft?)))
+ (cond ((assoc-ref opts 'generate-key)
+ =>
+ generate-key-pair)
+ ((assoc-ref opts 'authorize)
+ (authorize-key))
+ (else
+ (with-status-verbosity (assoc-ref opts 'verbosity)
+ (with-store store
+ (set-build-options-from-command-line store opts)
+ (cond ((assoc-ref opts 'export)
+ (export-from-store store opts))
+ ((assoc-ref opts 'import)
+ (import-paths store (current-input-port)))
+ ((assoc-ref opts 'missing)
+ (let* ((files (lines (current-input-port)))
+ (missing (remove (cut valid-path? store <>)
+ files)))
+ (format #t "~{~a~%~}" missing)))
+ ((assoc-ref opts 'list)
+ (list-contents (current-input-port)))
+ ((assoc-ref opts 'extract)
+ =>
+ (lambda (target)
+ (restore-file (current-input-port) target)))
+ (else
+ (leave
+ (G_ "either '--export' or '--import' \
+must be specified~%"))))))))))))
diff --git a/guix/scripts/build.scm b/guix/scripts/build.scm
index bf307d1421..f054fc2bce 100644
--- a/guix/scripts/build.scm
+++ b/guix/scripts/build.scm
@@ -809,7 +809,11 @@ build---packages, gexps, derivations, and so on."
(cond ((derivation-path? spec)
(catch 'system-error
(lambda ()
- (list (read-derivation-from-file spec)))
+ ;; Ask for absolute file names so that .drv file
+ ;; names passed from the user to 'read-derivation'
+ ;; are absolute when it returns.
+ (let ((spec (canonicalize-path spec)))
+ (list (read-derivation-from-file spec))))
(lambda args
;; Non-existent .drv files can be substituted down
;; the road, so don't error out.
@@ -927,67 +931,64 @@ needed."
(list %default-options)))
(with-error-handling
- ;; Ask for absolute file names so that .drv file names passed from the
- ;; user to 'read-derivation' are absolute when it returns.
- (with-fluids ((%file-port-name-canonicalization 'absolute))
- (with-status-verbosity (assoc-ref opts 'verbosity)
- (with-store store
- ;; Set the build options before we do anything else.
- (set-build-options-from-command-line store opts)
-
- (parameterize ((current-terminal-columns (terminal-columns)))
- (let* ((mode (assoc-ref opts 'build-mode))
- (drv (options->derivations store opts))
- (urls (map (cut string-append <> "/log")
- (if (assoc-ref opts 'substitutes?)
- (or (assoc-ref opts 'substitute-urls)
- ;; XXX: This does not necessarily match the
- ;; daemon's substitute URLs.
- %default-substitute-urls)
- '())))
- (items (filter-map (match-lambda
- (('argument . (? store-path? file))
- ;; If FILE is a .drv that's not in
- ;; store, keep it so that it can be
- ;; substituted.
- (and (or (not (derivation-path? file))
- (not (file-exists? file)))
- file))
- (_ #f))
- opts))
- (roots (filter-map (match-lambda
- (('gc-root . root) root)
- (_ #f))
- opts)))
-
- (unless (or (assoc-ref opts 'log-file?)
- (assoc-ref opts 'derivations-only?))
- (show-what-to-build store drv
- #:use-substitutes?
- (assoc-ref opts 'substitutes?)
- #:dry-run? (assoc-ref opts 'dry-run?)
- #:mode mode))
-
- (cond ((assoc-ref opts 'log-file?)
- ;; Pass 'show-build-log' the output file names, not the
- ;; derivation file names, because there can be several
- ;; derivations leading to the same output.
- (for-each (cut show-build-log store <> urls)
- (delete-duplicates
- (append (map derivation->output-path drv)
- items))))
- ((assoc-ref opts 'derivations-only?)
- (format #t "~{~a~%~}" (map derivation-file-name drv))
- (for-each (cut register-root store <> <>)
- (map (compose list derivation-file-name) drv)
- roots))
- ((not (assoc-ref opts 'dry-run?))
- (and (build-derivations store (append drv items)
- mode)
- (for-each show-derivation-outputs drv)
- (for-each (cut register-root store <> <>)
- (map (lambda (drv)
- (map cdr
- (derivation->output-paths drv)))
- drv)
- roots)))))))))))
+ (with-status-verbosity (assoc-ref opts 'verbosity)
+ (with-store store
+ ;; Set the build options before we do anything else.
+ (set-build-options-from-command-line store opts)
+
+ (parameterize ((current-terminal-columns (terminal-columns)))
+ (let* ((mode (assoc-ref opts 'build-mode))
+ (drv (options->derivations store opts))
+ (urls (map (cut string-append <> "/log")
+ (if (assoc-ref opts 'substitutes?)
+ (or (assoc-ref opts 'substitute-urls)
+ ;; XXX: This does not necessarily match the
+ ;; daemon's substitute URLs.
+ %default-substitute-urls)
+ '())))
+ (items (filter-map (match-lambda
+ (('argument . (? store-path? file))
+ ;; If FILE is a .drv that's not in
+ ;; store, keep it so that it can be
+ ;; substituted.
+ (and (or (not (derivation-path? file))
+ (not (file-exists? file)))
+ file))
+ (_ #f))
+ opts))
+ (roots (filter-map (match-lambda
+ (('gc-root . root) root)
+ (_ #f))
+ opts)))
+
+ (unless (or (assoc-ref opts 'log-file?)
+ (assoc-ref opts 'derivations-only?))
+ (show-what-to-build store drv
+ #:use-substitutes?
+ (assoc-ref opts 'substitutes?)
+ #:dry-run? (assoc-ref opts 'dry-run?)
+ #:mode mode))
+
+ (cond ((assoc-ref opts 'log-file?)
+ ;; Pass 'show-build-log' the output file names, not the
+ ;; derivation file names, because there can be several
+ ;; derivations leading to the same output.
+ (for-each (cut show-build-log store <> urls)
+ (delete-duplicates
+ (append (map derivation->output-path drv)
+ items))))
+ ((assoc-ref opts 'derivations-only?)
+ (format #t "~{~a~%~}" (map derivation-file-name drv))
+ (for-each (cut register-root store <> <>)
+ (map (compose list derivation-file-name) drv)
+ roots))
+ ((not (assoc-ref opts 'dry-run?))
+ (and (build-derivations store (append drv items)
+ mode)
+ (for-each show-derivation-outputs drv)
+ (for-each (cut register-root store <> <>)
+ (map (lambda (drv)
+ (map cdr
+ (derivation->output-paths drv)))
+ drv)
+ roots))))))))))
diff --git a/guix/scripts/graph.scm b/guix/scripts/graph.scm
index 53f407b2fc..fca1e3777c 100644
--- a/guix/scripts/graph.scm
+++ b/guix/scripts/graph.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015, 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2019 Simon Tournier <zimon.toutoune@gmail.com>
;;;
;;; This file is part of GNU Guix.
@@ -552,20 +552,17 @@ Emit a representation of the dependency graph of PACKAGE...\n"))
(read/eval-package-expression exp)))
(_ #f))
opts)))
- ;; Ask for absolute file names so that .drv file names passed from the
- ;; user to 'read-derivation' are absolute when it returns.
- (with-fluids ((%file-port-name-canonicalization 'absolute))
- (run-with-store store
- ;; XXX: Since grafting can trigger unsolicited builds, disable it.
- (mlet %store-monad ((_ (set-grafting #f))
- (nodes (mapm %store-monad
- (node-type-convert type)
- items)))
- (export-graph (concatenate nodes)
- (current-output-port)
- #:node-type type
- #:backend backend))
- #:system (assq-ref opts 'system))))))
+ (run-with-store store
+ ;; XXX: Since grafting can trigger unsolicited builds, disable it.
+ (mlet %store-monad ((_ (set-grafting #f))
+ (nodes (mapm %store-monad
+ (node-type-convert type)
+ items)))
+ (export-graph (concatenate nodes)
+ (current-output-port)
+ #:node-type type
+ #:backend backend))
+ #:system (assq-ref opts 'system)))))
#t)
;;; graph.scm ends here
diff --git a/guix/self.scm b/guix/self.scm
index 207e80d842..6b633f9bc0 100644
--- a/guix/self.scm
+++ b/guix/self.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -28,7 +28,6 @@
#:use-module (guix sets)
#:use-module (guix modules)
#:use-module ((guix build utils) #:select (find-files))
- #:use-module ((guix build compile) #:select (%lightweight-optimizations))
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-35)
@@ -49,13 +48,13 @@
(let ((ref (lambda (module variable)
(module-ref (resolve-interface module) variable))))
(match-lambda
- ("guile" (ref '(gnu packages commencement) 'guile-final))
- ("guile-json" (ref '(gnu packages guile) 'guile-json-3))
- ("guile-ssh" (ref '(gnu packages ssh) 'guile-ssh))
- ("guile-git" (ref '(gnu packages guile) 'guile-git))
- ("guile-sqlite3" (ref '(gnu packages guile) 'guile-sqlite3))
- ("guile-gcrypt" (ref '(gnu packages gnupg) 'guile-gcrypt))
- ("gnutls" (ref '(gnu packages tls) 'gnutls))
+ ("guile" (ref '(gnu packages guile) 'guile-3.0))
+ ("guile-json" (ref '(gnu packages guile) 'guile3.0-json))
+ ("guile-ssh" (ref '(gnu packages ssh) 'guile3.0-ssh))
+ ("guile-git" (ref '(gnu packages guile) 'guile3.0-git))
+ ("guile-sqlite3" (ref '(gnu packages guile) 'guile3.0-sqlite3))
+ ("guile-gcrypt" (ref '(gnu packages gnupg) 'guile3.0-gcrypt))
+ ("gnutls" (ref '(gnu packages tls) 'guile3.0-gnutls))
("zlib" (ref '(gnu packages compression) 'zlib))
("lzlib" (ref '(gnu packages compression) 'lzlib))
("gzip" (ref '(gnu packages compression) 'gzip))
@@ -1121,9 +1120,9 @@ is not supported."
version))
(define guile
- ;; When PULL-VERSION >= 1, produce a self-contained Guix and use Guile 2.2
- ;; unconditionally.
- (default-guile))
+ ;; When PULL-VERSION >= 1, produce a self-contained Guix and use the
+ ;; current Guile unconditionally.
+ (specification->package "guile"))
(when (and (< pull-version 1)
(not (string=? (package-version guile) guile-version)))
@@ -1142,7 +1141,7 @@ is not supported."
(shorten version))
#:pull-version pull-version
#:guile-version (if (>= pull-version 1)
- "2.2" guile-version)
+ "3.0" guile-version)
#:guile-for-build guile)))
(if guix
(lower-object guix)
diff --git a/guix/serialization.scm b/guix/serialization.scm
index 9452303730..836ad06caf 100644
--- a/guix/serialization.scm
+++ b/guix/serialization.scm
@@ -27,6 +27,7 @@
#:use-module ((ice-9 rdelim) #:prefix rdelim:)
#:use-module (ice-9 match)
#:use-module (ice-9 ftw)
+ #:use-module (system foreign)
#:export (write-int read-int
write-long-long read-long-long
write-padding
@@ -80,6 +81,17 @@
(port port)))))
bv))
+(define (sub-bytevector bv len)
+ "Return a bytevector that aliases the first LEN bytes of BV."
+ (define max (bytevector-length bv))
+ (cond ((= len max) bv)
+ ((< len max)
+ ;; Yes, this is safe because the result of each conversion procedure
+ ;; has its life cycle synchronized with that of its argument.
+ (pointer->bytevector (bytevector->pointer bv) len))
+ (else
+ (error "sub-bytevector called to get a super bytevector"))))
+
(define (write-int n p)
(let ((b (make-bytevector 8 0)))
(bytevector-u32-set! b 0 n (endianness little))
@@ -119,10 +131,9 @@
(define (read-byte-string p)
(let* ((len (read-int p))
(m (modulo len 8))
- (bv (get-bytevector-n* p len)))
- (or (zero? m)
- (get-bytevector-n* p (- 8 m)))
- bv))
+ (pad (if (zero? m) 0 (- 8 m)))
+ (bv (get-bytevector-n* p (+ len pad))))
+ (sub-bytevector bv len)))
(define (read-string p)
(utf8->string (read-byte-string p)))
diff --git a/guix/ui.scm b/guix/ui.scm
index 4857a88827..a47dafecd4 100644
--- a/guix/ui.scm
+++ b/guix/ui.scm
@@ -770,6 +770,17 @@ directories:~{ ~a~}~%")
(gettext (condition-message c) %gettext-domain))
(display-hint (condition-fix-hint c))
(exit 1))
+
+ ;; On Guile 3.0.0, exceptions such as 'unbound-variable' come are
+ ;; compound and include a '&message'. However, that message only
+ ;; contains the format string. Thus, special-case it here to
+ ;; avoid displaying a bare format string.
+ ((cond-expand
+ (guile-3
+ ((exception-predicate &exception-with-kind-and-args) c))
+ (else #f))
+ (raise c))
+
((message-condition? c)
;; Normally '&message' error conditions have an i18n'd message.
(leave (G_ "~a~%")