unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling
@ 2021-04-18 11:20 Maxime Devos
  2021-04-19 19:04 ` [bug#47869] [PATCH v2 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
  0 siblings, 1 reply; 9+ messages in thread
From: Maxime Devos @ 2021-04-18 11:20 UTC (permalink / raw)
  To: 47869


[-- Attachment #1.1: Type: text/plain, Size: 2557 bytes --]

The procedure ‘which’ from (guix build utils)
is used for two different purposes:

 1. for finding the absolute file name of a binary
    that we need to run during the build process

 2. for finding the absolute file name of a binary,
    for the target system (as in --target=TARGET),
    e.g. for substituting sh->/gnu/store/.../bin/sh,
    python->/gnu/store/.../bin/python

When compiling natively (SYSTEM=TARGET modulo nix/autotools differences),
this is perfectly fine.

However, when cross-compiling, we have a problem.
"which" looks in $PATH for binaries.  That's good for purpose (1),
but incorrect for (2), as the $PATH contains binaries from native-inputs
instead of inputs.

Admittedly, ‘which’ is simply very convenient (although incorrect
when cross-compiling), and we don't have the right tool ...
until now, that is (see patch)!

This patch adds an optional 'inputs' argument.  When it is present,
'which' will look in the bin and sbin subdirectories of the directories
in the 'inputs' alist.

Use it like this:

  (package [...]
    (arguments
     `(#:modules (guix build utils)
       #:phases
       (modify-phases %standard-phases
         (delete 'configure)
         (delete 'check)
         (add-after 'install 'wrap
           (lambda* (#:key outputs inputs #:allow-other-keys)
             (let ((growpart (string-append (assoc-ref outputs "out")
                                            "/bin/growpart")))
               (wrap-program growpart
                 `("PATH" ":" prefix (,(dirname (which "sfdisk" inputs))
                                      ,(dirname (which "readlink" inputs)))))))))))

(Examples comes from the "cloud-utils" package)
The only change is adding adding the 'inputs' argument.  Isn't that easy?

Alternative methods I've seen:
* (string-append (assoc-ref inputs "coreutils") "/bin/readlink")
* (let ((coreutils (assoc-ref inputs "coreutils")))
    (setenv "PATH" (string-append coreutils "/bin"))
    [code using (which "readlink")])
* (which "readlink") ; possibly incorrect when cross-compiling

I've tested this with "cloud-utils", though admittedly I didn't try to cross-compile
yet, and I've placed my adjusted "which" in a separate module to avoid having to rebuild
everything.  (The attached patch just modifies (guix build utils).)  I've written
a few tests, which pass.  I also documented the new functionality in the manual.

Currently incorrect uses of "which" can be fixed in a follow-up patch.

Thoughts?
Maxime.

[-- Attachment #1.2: 0001-build-Add-argument-to-which-for-specifying-where-to-.patch --]
[-- Type: text/x-patch, Size: 5530 bytes --]

From dc01abf110b1c8db05442ce3986683c10e784f26 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Sun, 18 Apr 2021 12:45:13 +0200
Subject: [PATCH 1/2] build: Add argument to which for specifying where to
 search.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The procedure ‘which’ from (guix build utils)
is used for two different purposes:

 1. for finding the absolute file name of a binary
    that needs to run during the build process

 2. for finding the absolute file name of a binary,
    for the target system (as in --target=TARGET),
    e.g. for substituting sh->/gnu/store/.../bin/sh,
    python->/gnu/store/.../bin/python.

When compiling natively (SYSTEM=TARGET modulo nix/autotools differences),
this is perfectly fine.

However, when cross-compiling, there is a problem.
"which" looks in $PATH for binaries.  That's good for purpose (1),
but incorrect for (2), as the $PATH contains binaries from native-inputs
instead of inputs.

This commit adds an optional 'inputs' argument.  When it is present,
'which' will look in the bin and sbin subdirectories of the directories
in the 'inputs' alist.

* guix/build/utils.scm (which): Add optional 'inputs' argument
* tests/build/utils.scm
  ("which, inputs in /bin", "which, inputs in /sbin")
  ("which, empty inputs", "which, using $PATH"): Test both old and new
  functionality of this procedure.
  (touch): Define procedure.
  (with-artificial-inputs): Define macro.
---
 guix/build/utils.scm  | 16 +++++++++----
 tests/build-utils.scm | 53 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index 6c37021673..5eb9f9580b 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -7,6 +7,7 @@
 ;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -607,10 +608,17 @@ denoting file names to look for under the directories designated by FILES:
           (format #t "environment variable `~a' set to `~a'~%"
                   env-var value)))))
 
-(define (which program)
-  "Return the complete file name for PROGRAM as found in $PATH, or #f if
-PROGRAM could not be found."
-  (search-path (search-path-as-string->list (getenv "PATH"))
+(define* (which program #:optional inputs)
+  "Return the complete file name for PROGRAM as found in $PATH, or #false if
+PROGRAM could not be found.  If INPUTS is not #false, instead look in the
+/bin and /sbin subdirectories of INPUTS.  INPUTS is an alist; its keys
+are ignored."
+  (define (input->path input)
+    `(,(string-append (cdr input) "/bin")
+      ,(string-append (cdr input) "/sbin")))
+  (search-path (if inputs
+                   (append-map input->path inputs)
+                   (search-path-as-string->list (getenv "PATH")))
                program))
 
 \f
diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index 31be7ff80f..05e455a807 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2012, 2015, 2016, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -263,4 +264,56 @@ print('hello world')"))
          (lambda _
            (get-string-all (current-input-port))))))))
 
+(define (touch file)
+  (call-with-output-file file (const #t)))
+
+(define-syntax-rule (with-artificial-inputs inputs
+                      ((x key relative-name) ...)
+                      exp exp* ...)
+  "For the duration of EXP EXP* ..., create a temporary directory.
+In this directory, the files RELATIVE-NAME ... are created, and
+X ... are bound to their absolute name.  INPUTS is bound to
+an alist with as keys KEY ... and as values the absolute file names
+of the grandparents of RELATIVE-NAME ... ."
+  (call-with-temporary-directory
+   (lambda (tempdir)
+     (let* ((x (in-vicinity tempdir relative-name))
+            ...
+            (inputs `((key . ,(dirname (dirname x))) ...)))
+       (for-each (compose mkdir-p dirname) (list x ...))
+       (for-each touch (list x ...))
+       exp exp* ...))))
+
+(test-equal "which, inputs in /bin"
+  '(#t #t)
+  (with-artificial-inputs inputs
+    ((x "package-x" "x-1.0/bin/x")
+     (y "package-y" "y-1.0/bin/y"))
+    (list (string=? x (which "x" (pk 'i inputs)))
+          (string=? y (which "y" inputs)))))
+
+(test-equal "which, inputs in /sbin"
+  '(#t #t)
+  (with-artificial-inputs inputs
+    ((x "package-x" "x-1.0/sbin/x")
+     (y "package-y" "y-1.0/sbin/y"))
+    (list (string=? x (which "x" inputs))
+          (string=? y (which "y" inputs)))))
+
+(test-equal "which, empty inputs"
+  #f
+  (which "ls" '()))
+
+(test-assert "which, using $PATH"
+  (call-with-temporary-directory
+   (lambda (dirname)
+     (touch (in-vicinity dirname "ls"))
+     (with-environment-variable "PATH" dirname
+                                (lambda ()
+         (string=? (in-vicinity dirname "ls") (which "ls")))))))
+
 (test-end)
+
+;;; Local Variables:
+;;; eval: (put 'with-artificial-inputs 'scheme-indent-function 1)
+;;; End:
-- 
2.31.1


[-- Attachment #1.3: 0002-doc-Document-new-functionality-of-which.patch --]
[-- Type: text/x-patch, Size: 2229 bytes --]

From 6561c943fa134ca1e2a17e43f8f5498fca9b1560 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Sun, 18 Apr 2021 13:15:08 +0200
Subject: [PATCH 2/2] =?UTF-8?q?doc:=20Document=20new=20functionality=20of?=
 =?UTF-8?q?=20=E2=80=98which=E2=80=99.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* doc/guix.texi (File Search)[which]: Document the optional
  'inputs' argument, and give an example on how to use the
  procedure.
---
 doc/guix.texi | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 6464fa32cb..365cb13604 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -87,6 +87,7 @@ Copyright @copyright{} 2020 Daniel Brooks@*
 Copyright @copyright{} 2020 John Soo@*
 Copyright @copyright{} 2020 Jonathan Brielmaier@*
 Copyright @copyright{} 2020 Edgar Vincent@*
+Copyright @copyright{} 2021 Maxime Devos@*
 
 Permission is granted to copy, distribute and/or modify this document
 under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -8598,11 +8599,25 @@ the root of the Guix source tree:
 @result{} ("./libformat.a" "./libstore.a" @dots{})
 @end lisp
 
-@deffn {Scheme Procedure} which @var{program}
+@deffn {Scheme Procedure} which @var{program} [@var{inputs}=#false]
 Return the complete file name for @var{program} as found in
-@code{$PATH}, or @code{#f} if @var{program} could not be found.
+@code{$PATH}, or @code{#false} if @var{program} could not be found.
+If @var{INPUTS} is not @code{#false}, instead look in the
+@file{/bin} and @file{/sbin} subdirectories of @var{INPUTS}.
+@var{inputs} is an alist; its keys are ignored."
 @end deffn
 
+Here is an example using the @code{which} procedure in a build phase:
+
+@lisp
+(lambda* (#:key outputs inputs #:allow-other-keys)
+  (let ((growpart (string-append (assoc-ref outputs "out")
+                                          "/bin/growpart")))
+     (wrap-program growpart
+                   `("PATH" ":" prefix (,(dirname (which "sfdisk" inputs))
+                                        ,(dirname (which "readlink" inputs)))))))
+@end lisp
+
 @subsection Build Phases
 
 @cindex build phases
-- 
2.31.1


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [bug#47869] [PATCH v2 core-updates] various cross-compilation fixes in guix/build/utils.scm
  2021-04-18 11:20 [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Maxime Devos
@ 2021-04-19 19:04 ` Maxime Devos
  2021-05-18 20:51   ` [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès
                     ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Maxime Devos @ 2021-04-19 19:04 UTC (permalink / raw)
  To: 47869


[-- Attachment #1.1: Type: text/plain, Size: 451 bytes --]

This is version two of the patch series, removing a 'pk' that
I added for debugging, and also fixing 'wrap-script' and 'wrap-program'.
To fix 'wrap-script' and 'wrap-program', I added a required 'inputs' argument.
All callers have been adjusted to pass it.

Perhaps 'patch-shebang' can be fixed and needs to be fixed, but I don't
have investigated that closely yet.  ('patch-shebangs' (with a #\s) works
properly IIUC).

Greetings,
Maxime.

[-- Attachment #1.2: 0001-build-Add-argument-to-which-for-specifying-where-to-.patch --]
[-- Type: text/x-patch, Size: 5522 bytes --]

From 42e7cf4ca6e4d6e1cd31c2807f608275a5ca759a Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Sun, 18 Apr 2021 12:45:13 +0200
Subject: [PATCH 1/7] build: Add argument to which for specifying where to
 search.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The procedure ‘which’ from (guix build utils)
is used for two different purposes:

 1. for finding the absolute file name of a binary
    that needs to run during the build process

 2. for finding the absolute file name of a binary,
    for the target system (as in --target=TARGET),
    e.g. for substituting sh->/gnu/store/.../bin/sh,
    python->/gnu/store/.../bin/python.

When compiling natively (SYSTEM=TARGET modulo nix/autotools differences),
this is perfectly fine.

However, when cross-compiling, there is a problem.
"which" looks in $PATH for binaries.  That's good for purpose (1),
but incorrect for (2), as the $PATH contains binaries from native-inputs
instead of inputs.

This commit adds an optional 'inputs' argument.  When it is present,
'which' will look in the bin and sbin subdirectories of the directories
in the 'inputs' alist.

* guix/build/utils.scm (which): Add optional 'inputs' argument
* tests/build/utils.scm
  ("which, inputs in /bin", "which, inputs in /sbin")
  ("which, empty inputs", "which, using $PATH"): Test both old and new
  functionality of this procedure.
  (touch): Define procedure.
  (with-artificial-inputs): Define macro.
---
 guix/build/utils.scm  | 16 +++++++++----
 tests/build-utils.scm | 53 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index 6c37021673..5eb9f9580b 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -7,6 +7,7 @@
 ;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -607,10 +608,17 @@ denoting file names to look for under the directories designated by FILES:
           (format #t "environment variable `~a' set to `~a'~%"
                   env-var value)))))
 
-(define (which program)
-  "Return the complete file name for PROGRAM as found in $PATH, or #f if
-PROGRAM could not be found."
-  (search-path (search-path-as-string->list (getenv "PATH"))
+(define* (which program #:optional inputs)
+  "Return the complete file name for PROGRAM as found in $PATH, or #false if
+PROGRAM could not be found.  If INPUTS is not #false, instead look in the
+/bin and /sbin subdirectories of INPUTS.  INPUTS is an alist; its keys
+are ignored."
+  (define (input->path input)
+    `(,(string-append (cdr input) "/bin")
+      ,(string-append (cdr input) "/sbin")))
+  (search-path (if inputs
+                   (append-map input->path inputs)
+                   (search-path-as-string->list (getenv "PATH")))
                program))
 
 \f
diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index 31be7ff80f..636fa40c47 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2012, 2015, 2016, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -263,4 +264,56 @@ print('hello world')"))
          (lambda _
            (get-string-all (current-input-port))))))))
 
+(define (touch file)
+  (call-with-output-file file (const #t)))
+
+(define-syntax-rule (with-artificial-inputs inputs
+                      ((x key relative-name) ...)
+                      exp exp* ...)
+  "For the duration of EXP EXP* ..., create a temporary directory.
+In this directory, the files RELATIVE-NAME ... are created, and
+X ... are bound to their absolute name.  INPUTS is bound to
+an alist with as keys KEY ... and as values the absolute file names
+of the grandparents of RELATIVE-NAME ... ."
+  (call-with-temporary-directory
+   (lambda (tempdir)
+     (let* ((x (in-vicinity tempdir relative-name))
+            ...
+            (inputs `((key . ,(dirname (dirname x))) ...)))
+       (for-each (compose mkdir-p dirname) (list x ...))
+       (for-each touch (list x ...))
+       exp exp* ...))))
+
+(test-equal "which, inputs in /bin"
+  '(#t #t)
+  (with-artificial-inputs inputs
+    ((x "package-x" "x-1.0/bin/x")
+     (y "package-y" "y-1.0/bin/y"))
+    (list (string=? x (which "x" inputs))
+          (string=? y (which "y" inputs)))))
+
+(test-equal "which, inputs in /sbin"
+  '(#t #t)
+  (with-artificial-inputs inputs
+    ((x "package-x" "x-1.0/sbin/x")
+     (y "package-y" "y-1.0/sbin/y"))
+    (list (string=? x (which "x" inputs))
+          (string=? y (which "y" inputs)))))
+
+(test-equal "which, empty inputs"
+  #f
+  (which "ls" '()))
+
+(test-assert "which, using $PATH"
+  (call-with-temporary-directory
+   (lambda (dirname)
+     (touch (in-vicinity dirname "ls"))
+     (with-environment-variable "PATH" dirname
+                                (lambda ()
+         (string=? (in-vicinity dirname "ls") (which "ls")))))))
+
 (test-end)
+
+;;; Local Variables:
+;;; eval: (put 'with-artificial-inputs 'scheme-indent-function 1)
+;;; End:
-- 
2.31.1


[-- Attachment #1.3: 0002-doc-Document-new-functionality-of-which.patch --]
[-- Type: text/x-patch, Size: 1841 bytes --]

From fc4419098213673f713181d75f98df30255bd62c Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Sun, 18 Apr 2021 13:15:08 +0200
Subject: [PATCH 2/7] =?UTF-8?q?doc:=20Document=20new=20functionality=20of?=
 =?UTF-8?q?=20=E2=80=98which=E2=80=99.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* doc/guix.texi (File Search)[which]: Document the optional
  'inputs' argument, and give an example on how to use the
  procedure.
---
 doc/guix.texi | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index a89701dd68..e8a9a31e1a 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8679,11 +8679,25 @@ the root of the Guix source tree:
 @result{} ("./libformat.a" "./libstore.a" @dots{})
 @end lisp
 
-@deffn {Scheme Procedure} which @var{program}
+@deffn {Scheme Procedure} which @var{program} [@var{inputs}=#false]
 Return the complete file name for @var{program} as found in
-@code{$PATH}, or @code{#f} if @var{program} could not be found.
+@code{$PATH}, or @code{#false} if @var{program} could not be found.
+If @var{INPUTS} is not @code{#false}, instead look in the
+@file{/bin} and @file{/sbin} subdirectories of @var{INPUTS}.
+@var{inputs} is an alist; its keys are ignored.
 @end deffn
 
+Here is an example using the @code{which} procedure in a build phase:
+
+@lisp
+(lambda* (#:key outputs inputs #:allow-other-keys)
+  (let ((growpart (string-append (assoc-ref outputs "out")
+                                          "/bin/growpart")))
+     (wrap-program growpart
+                   `("PATH" ":" prefix (,(dirname (which "sfdisk" inputs))
+                                        ,(dirname (which "readlink" inputs)))))))
+@end lisp
+
 @subsection Build Phases
 
 @cindex build phases
-- 
2.31.1


[-- Attachment #1.4: 0003-build-utils-Make-inputs-of-wrap-script-explicit.patch --]
[-- Type: text/x-patch, Size: 13646 bytes --]

From e78d2d8651d5f56afa7d57be78c5cccccebb117a Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Sun, 18 Apr 2021 20:44:28 +0200
Subject: [PATCH 3/7] build: utils: Make inputs of 'wrap-script' explicit.

Previously, 'wrap-script' used (which "guile") to determine where to locate
the guile interpreter.  But this is incorrect when cross-compiling.  When
cross-compiling, this would locate the (native) guile interpreter that is
in the PATH, while a guile interpreter for the target is required.

Remove the optional #:guile argument which is only used in tests and replace
it with a required 'inputs' argument and adjust all callers.  Write a new
test verifying a guile for the target is located, instead of a native guile.

* guix/build/utils.scm (wrap-script): Remove optional 'guile' argument.
  Add required 'inputs' argument.  Adjust call to 'update-env'
  appropriately. Look up "guile" in 'inputs' with 'which'.  Also allow
  'inputs' to be a string, which is convenient for tests.
* tests/build-utils.scm
  ("wrap-script, simple case", "wrap-script, with encoding declaration")
  ("wrap-script, raises condition"): Adjust tests to new calling convention.
  ("wrap-script, searches in inputs"): New test.
* gnu/packages/audio.scm
  (carla)[arguments]<#:phases>{wrap-executables}: Add 'inputs' argument
  to call to 'wrap-script'.
* gnu/packages/bash.scm (bats)[arguments]<#:builder>: Likewise.
* gnu/packages/bioinformatics.scm
  (proteinortho)[arguments]<#:phases>{wrap-programs}: Likewise.
  (prinseq)[arguments]<#:phases>{install}: Likewise.
  (gess)[arguments]<#:phases>{install}: Likewise.
  (nanopolish)[arguments]<#:phases>{wrap-programs}: Likewise.
* gnu/packages/mail.scm
  (sieve-connect)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/vpn.scm
  (vpnc-scripts)[arguments]<#:phases>{wrap-scripts}: Likewise.
* gnu/packages/xdisorg.scm
  (clipmenu)[arguments]<#:phases>{wrap-script}: Likewise.
---
 gnu/packages/audio.scm          |  4 +--
 gnu/packages/bash.scm           |  2 +-
 gnu/packages/bioinformatics.scm | 13 ++++++----
 gnu/packages/mail.scm           |  2 +-
 gnu/packages/vpn.scm            |  2 +-
 gnu/packages/xdisorg.scm        |  2 +-
 guix/build/utils.scm            | 14 ++++++-----
 tests/build-utils.scm           | 43 ++++++++++++++++++++++++++++++---
 8 files changed, 62 insertions(+), 20 deletions(-)

diff --git a/gnu/packages/audio.scm b/gnu/packages/audio.scm
index 30e38cef70..50627cc3e7 100644
--- a/gnu/packages/audio.scm
+++ b/gnu/packages/audio.scm
@@ -4712,9 +4712,9 @@ as is the case with audio plugins.")
                (chmod (string-append out "/share/carla/carla") #o555)
                #t)))
          (add-after 'install 'wrap-executables
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
-               (wrap-script (string-append out "/bin/carla")
+               (wrap-script (string-append out "/bin/carla") inputs
                             `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (inputs
diff --git a/gnu/packages/bash.scm b/gnu/packages/bash.scm
index ed2931fd97..51013b5bc1 100644
--- a/gnu/packages/bash.scm
+++ b/gnu/packages/bash.scm
@@ -408,7 +408,7 @@ capturing.")
                            line)))
          ;; Install phase
          (invoke "./install.sh" %output)
-         (wrap-script (string-append %output "/bin/bats")
+         (wrap-script (string-append %output "/bin/bats") %build-inputs
                       (list "PATH" 'prefix (string-split (getenv "PATH")
                                                          #\:))))))
     (build-system trivial-build-system)
diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 313c70784a..2ca56d3962 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -5395,7 +5395,8 @@ predicts the locations of structural units in the sequences.")
              (let ((path (getenv "PATH"))
                    (out (assoc-ref outputs "out")))
                (for-each (lambda (script)
-                           (wrap-script script `("PATH" ":" prefix (,path))))
+                           (wrap-script script inputs
+                                        `("PATH" ":" prefix (,path))))
                          (cons (string-append out "/bin/proteinortho")
                                (find-files out "\\.(pl|py)$"))))
              #t)))))
@@ -7461,13 +7462,14 @@ experience substantial biological insertions and deletions.")
          (delete 'configure)
          (delete 'build)
          (replace 'install
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin")))
                (for-each (lambda (file)
                            (chmod file #o555)
                            (install-file file bin)
                            (wrap-script (string-append bin "/" (basename file))
+                                        inputs
                                         `("PERL5LIB" ":" prefix
                                           (,(getenv "PERL5LIB")))))
                          (find-files "." "prinseq.*.pl"))))))))
@@ -10115,7 +10117,7 @@ import matplotlib
 matplotlib.use('Agg')
 " line)))
                ;; Make sure GESS has all modules in its path
-               (wrap-script (string-append target "GESS.py")
+               (wrap-script (string-append target "GESS.py") inputs
                  `("GUIX_PYTHONPATH" ":" = (,target ,(getenv "GUIX_PYTHONPATH"))))
                (mkdir-p bin)
                (symlink (string-append target "GESS.py")
@@ -13456,7 +13458,7 @@ choosing which reads pass the filter.")
                            (find-files "scripts" ".*"))
                  #t)))
            (add-after 'install 'wrap-programs
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let ((pythonpath (getenv "GUIX_PYTHONPATH"))
                      (perl5lib (getenv "PERL5LIB"))
                      (scripts (string-append (assoc-ref outputs "out")
@@ -13465,7 +13467,8 @@ choosing which reads pass the filter.")
                              (wrap-program file `("GUIX_PYTHONPATH" ":" prefix (,pythonpath))))
                            (find-files scripts "\\.py"))
                  (for-each (lambda (file)
-                             (wrap-script file `("PERL5LIB" ":" prefix (,perl5lib))))
+                             (wrap-script file inputs
+                                          `("PERL5LIB" ":" prefix (,perl5lib))))
                            (find-files scripts "\\.pl"))))))))
       (inputs
        `(("guile" ,guile-3.0) ; for wrappers
diff --git a/gnu/packages/mail.scm b/gnu/packages/mail.scm
index 35584c497a..39cf827d84 100644
--- a/gnu/packages/mail.scm
+++ b/gnu/packages/mail.scm
@@ -2924,7 +2924,7 @@ transfer protocols.")
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out"))
                    (path (getenv "PERL5LIB")))
-               (wrap-script (string-append out "/bin/sieve-connect")
+               (wrap-script (string-append out "/bin/sieve-connect") inputs
                  `("PERL5LIB" ":" = (,path)))
                #t))))))
     (inputs
diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index adb48b1b97..398d4b040b 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -195,7 +195,7 @@ Only \"Universal TUN/TAP device driver support\" is needed in the kernel.")
                (let ((out (assoc-ref outputs "out")))
                  (for-each
                   (lambda (script)
-                    (wrap-script (string-append out "/etc/vpnc/" script)
+                    (wrap-script (string-append out "/etc/vpnc/" script) inputs
                       `("PATH" ":" prefix
                         ,(map (lambda (name)
                                 (let ((input (assoc-ref inputs name)))
diff --git a/gnu/packages/xdisorg.scm b/gnu/packages/xdisorg.scm
index 4202a7168e..76b0156678 100644
--- a/gnu/packages/xdisorg.scm
+++ b/gnu/packages/xdisorg.scm
@@ -2550,7 +2550,7 @@ tools to complement clipnotify.")
                       (xsel              (assoc-ref inputs "xsel")))
                  (for-each
                   (lambda (prog)
-                    (wrap-script (string-append out "/bin/" prog)
+                    (wrap-script (string-append out "/bin/" prog) inputs
                       `("PATH" ":" prefix
                         ,(map (lambda (dir)
                                 (string-append dir "/bin"))
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index 5eb9f9580b..b725237ce6 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -1353,7 +1353,7 @@ with definitions for VARS."
         (coding-line-regex
          (make-regexp
           ".*#.*coding[=:][[:space:]]*([-a-zA-Z_0-9.]+)")))
-    (lambda* (prog #:key (guile (which "guile")) #:rest vars)
+    (lambda* (prog inputs #:rest vars)
       "Wrap the script PROG such that VARS are set first.  The format of VARS
 is the same as in the WRAP-PROGRAM procedure.  This procedure differs from
 WRAP-PROGRAM in that it does not create a separate shell script.  Instead,
@@ -1413,12 +1413,14 @@ not supported."
 #\\-~s
 #\\-~s
 "
-                                   guile
+                                   ;; This is convenient for tests, but should
+                                   ;; not be used in real package definitions.
+                                   ;; See tests/build-utils.scm.
+                                   (if (string? inputs)
+                                       inputs
+                                       (which "guile" inputs))
                                    (or coding-line "Guix wrapper")
-                                   (cons 'begin (map update-env
-                                                     (match vars
-                                                       ((#:guile _ . vars) vars)
-                                                       (_ vars))))
+                                   (cons 'begin (map update-env vars))
                                    `(let ((cl (command-line)))
                                       (apply execl ,interpreter
                                              (car cl)
diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index 636fa40c47..620cddbbfc 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -178,7 +178,7 @@ echo hello world"))
            (lambda (port)
              (display script-contents port)))
          (chmod script-file-name #o777)
-         (wrap-script script-file-name
+         (wrap-script script-file-name (which "guile")
                       `("GUIX_FOO" prefix ("/some/path"
                                            "/some/other/path")))
          (let ((str (call-with-input-file script-file-name get-string-all)))
@@ -220,7 +220,7 @@ print('hello world')"))
          (chmod script-file-name #o777)
 
          (wrap-script script-file-name
-                      #:guile "MYGUILE"
+                      "MYGUILE"
                       `("GUIX_FOO" prefix ("/some/path"
                                            "/some/other/path")))
          (let ((str (call-with-input-file script-file-name get-string-all)))
@@ -238,11 +238,48 @@ print('hello world')"))
        (chmod script-file-name #o777)
        (guard (c ((wrap-error? c) #t))
          (wrap-script script-file-name
-                      #:guile "MYGUILE"
+                      "MYGUILE"
                       `("GUIX_FOO" prefix ("/some/path"
                                            "/some/other/path")))
          #f)))))
 
+;; for cross-compilation purposes, it is important 'wrap-script'
+;; looks in the INPUTS, and doesn't simply use the native guile.
+(test-assert "wrap-script, searches in inputs"
+  (call-with-temporary-directory
+   (lambda (directory)
+     (let* ((guile-bindir (string-append directory "/bin"))
+            (guile-binary (string-append guile-bindir "/guile"))
+            (inputs `(("guile" . ,directory)))
+            (script-file-name (string-append directory "/foo"))
+            (script-contents
+             "#!/anything/cabbage-bash-1.2.3/bin/sh
+
+echo hello world"))
+       (mkdir-p guile-bindir)
+       (call-with-output-file guile-binary
+         (lambda (port)
+           (display "This pretends to be guile" port)))
+       (make-file-writable guile-binary)
+       (call-with-output-file script-file-name
+         (lambda (port)
+           (display script-contents port)))
+       (wrap-script script-file-name inputs)
+       (string=? (format #f
+                         "#!~a --no-auto-compile
+#!#; Guix wrapper
+#\\-(begin)
+#\\-~s
+#!/anything/cabbage-bash-1.2.3/bin/sh
+
+echo hello world"
+                         guile-binary
+                         '(let ((cl (command-line)))
+                            (apply execl "/anything/cabbage-bash-1.2.3/bin/sh"
+                                   (car cl) (cons (car cl)
+                                                  (append '("") cl))))))
+       (call-with-input-file script-file-name get-string-all)))))
+
 (test-equal "substitute*, text contains a NUL byte, UTF-8"
   "c\0d"
   (with-fluids ((%default-port-encoding "UTF-8")
-- 
2.31.1


[-- Attachment #1.5: 0004-doc-Document-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1629 bytes --]

From a2b93f190123f9e0bba0ba5b2bf14e4e952ecfe8 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Sun, 18 Apr 2021 21:17:01 +0200
Subject: [PATCH 4/7] doc: Document 'wrap-script'.

* doc/guix.texi (Wrapping Code)[wrap-script]: New section.
  Document 'wrap-script'.  Reuse its docstring.
---
 doc/guix.texi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index e8a9a31e1a..a2ff13fe0f 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8698,6 +8698,27 @@ Here is an example using the @code{which} procedure in a build phase:
                                         ,(dirname (which "readlink" inputs)))))))
 @end lisp
 
+@subsection Wrapping Code
+
+This section documents procedures that create ‘wrappers’ around existing
+binaries, that e.g. set environment variables required during execution.
+
+@c TODO document wrap-program
+
+@deffn {Scheme Procedure} wrap-script @var{prog} @var{inputs} @var{vars}
+Wrap the script @var{prog} such that @var{vars} are set first.  The format
+of @var{vars} is the same as in the @code{wrap-program} procedure.  This
+procedure differs from @code{wrap-program} in that it does not create a
+separate shell script.  Instead, @var{prog} is modified directly by prepending
+a Guile script, which is interpreted as a comment in the script's language.
+
+Special encoding comments as supported by Python are recreated on the second
+line.
+
+Note that this procedure can only be used once per file as Guile scripts are
+not supported.
+@end deffn
+
 @subsection Build Phases
 
 @cindex build phases
-- 
2.31.1


[-- Attachment #1.6: 0005-tests-build-utils-Remove-obsolete-comment.patch --]
[-- Type: text/x-patch, Size: 1137 bytes --]

From 9991ce1e78e9753ddf1dfe24595b7ea82476578e Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Sun, 18 Apr 2021 22:01:10 +0200
Subject: [PATCH 5/7] tests: build-utils: Remove obsolete comment.

* tests/build-utils.scm
  ("wrap-program, one input, multiple calls"): Remove obsolete, and now
  factually incorrect comment, that claimed this test creates a symlink.
---
 tests/build-utils.scm | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index 620cddbbfc..a5dfab576d 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -107,10 +107,6 @@
                    bash)))
        (chmod foo #o777)
 
-       ;; wrap-program uses `which' to find bash for the wrapper shebang, but
-       ;; it can't know about the bootstrap bash in the store, since it's not
-       ;; named "bash".  Help it out a bit by providing a symlink it this
-       ;; package's output.
        (with-environment-variable "PATH" (dirname bash)
          (wrap-program foo `("GUIX_FOO" prefix ("hello")))
          (wrap-program foo `("GUIX_BAR" prefix ("world")))
-- 
2.31.1


[-- Attachment #1.7: 0006-build-utils-wrap-program-look-up-bash-in-inputs-not-.patch --]
[-- Type: text/x-patch, Size: 119254 bytes --]

From 8b843f0dd8803120718747b480983bd5888b1617 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 19 Apr 2021 16:56:00 +0200
Subject: [PATCH 6/7] build: utils: wrap-program: look up bash in inputs, not
 in PATH

'wrap-program' is almost always used for creating wrappers for the
target system.  It is only rarely (once) used for creating wrappers for
the native system.  However, 'wrap-program' always creates wrappers for
the native system and provides no option for creating wrappers for the
target system instead.

To fix this, add an explicit 'inputs' argument to 'wrap-program' listing
inputs (for the target) where "bash" might be found and use that argument.
Most package definitions should simply pass the 'inputs' argument from
the phase procedure.

* guix/build/utils.scm (wrap-program): Add 'inputs' argument. Pass 'inputs'
  argument to call '(which "bash")'.
* tests/build-utils.scm ("wrap-program, one input, multiple calls"): Add
  'inputs' argument.  Populate directory with bootstrap bash under 'bin'
  for the 'inputs' argument.
* guix/build/glib-or-gtk-build-system.scm (wrap-all-programs): Pass 'inputs'
  to 'wrap-program'.
* guix/build/python-build-system.scm (wrap): Likewise.
* guix/build/qt-build-system.scm (wrap)[handle-output]: Likewise.
* guix/build/rakudo-build-system.scm (wrap): Likewise.
* guix/build/qt-utils.scm (wrap-qt-program): Likewise, and add 'inputs'
  argument to 'wrap-qt-program'.
* gnu/packages/admin.scm (cloud-utils)[arguments]<#:phases>{wrap}:
  Pass 'inputs' argument to 'wrap-program'.
  (isc-dhcp)[arguments]<#:phases>{post-install}: Likewise.
  (clusterssh)[arguments]<#:phases>{augment-library-path}: Likewise.
  (rename)[arguments]<#:phases>{find-itself}: Likewise.
  (wpa-supplicant-gui)[arguments]<#:phases>{install}: Likewise.
  (nmap)[arguments]<#:phases>{install}: Likewise.
  (dstat)[arguments]<#:phases>{wrap}: Likewise.
  (screenfetch)[arguments]<#:builder>: Likewise, but using %build-inputs.
  (inxi-minimal)[arguments]<#:builder>: Likewise, but using %build-inputs.
* gnu/packages/animation.scm
  (synfigstudio)[arguments]<#:phases>{wrap-program}: Likewise.
  (papagayo)[arguments]<#:phases>{wrap-executable}: Likewise.
  (pencil2d)[arguments]<#:phases>{wrap-executable}: Likewise.
* gnu/packages/arcan.scm
  (arcan)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/audio.scm
  (jack-2)[arguments]<#:phases>{wrap-python-scripts}: Likewise.
* gnu/packages/backup.scm
  (dirvish)[arguments]<#:phases>{install}: Likewise.
* gnu/packages/benchmarks.scm
  (fio)[arguments]<#:phases>{move-outputs}: Likewise.
* gnu/packages/bioinformatics.scm
  (bamm)[arguments]<#:phases>{wrap-executable}: Likewise.
  (ribotaper)[arguments]<#:phases>{wrap-executables}: Likewise.
  (bioperl-minimal)[arguments]<#:phases>{wrap-programs}: Likewise.
  (tetoolkit)[arguments]<#:phases>{wrap-program}: Likewise.
  (couger)[arguments]<#:phases>{wrap-program}: Likewise.
  (repeat-masker)[arguments]<#:phases>{install}: Likewise.
  (edirect)[arguments]<#:phases>{wrap-program}: Likewise.
  (mafft)[arguments]<#:phases>{wrap-programs}: Likewise.
  (prank)[arguments]<#:phases>{install}: Likewise.
  (roary)[arguments]<#:phases>{wrap-programs}: Likewise.
  (rsem)[arguments]<#:phases>{wrap-program}: Likewise.
  (rcas-web)[arguments]<#:phases>{wrap-executable}: Likewise.
  (find-circ)[arguments]<#:phases>{install}: Likewise.
  (jamm)[arguments]<#:phases>{install}: Likewise.
  (filtlong)[arguments]<#:phases>{install}: Likewise.
  (nanopolish)[arguments]<#:phases>{wrap-programs}: Likewise.
  (arriba)[arguments]<#:phases>{install}: Likewise.
  (pplacer-scripts)[arguments]<#:phases>{wrap-executables}: Likewise.
* gnu/packages/bittorrent.scm
  (qbittorrent)[arguments]<#:phases>{wrap-qt}: Likewise, but for
  'wrap-qt-program'.
  (deluge)[arguments]<#:phases>{wrap}: Likewise.
* gnu/packages/cdrom.scm
  (xorisso)[arguments]<#:phases>{move-gui-to-separate-output}: Likewise.
  (dvdstyler)[arguments]<#:phases>{wrap-program}: Likewise.
  (abcde)[arguments]<#:phases>{wrap}: Likewise.
  (asunder)[arguments]<#:phases>{wrap}: Likewise.
  (cdemu-client)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/chromium.scm
  (ungoogled-chromium)[arguments]<#:phases>{install}: Likewise.
* gnu/packages/ci.scm
  (cuirass)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/code.scm
  (cloc)[arguments]<#:phases>{wrap-program}: Likewise.
  (lcov)[arguments]<#:phases>{wrap}: Likewise.
* gnu/packages/connman.scm
  (econnman)[arguments]<#:phases>{wrap-binary}: Likewise.
* gnu/packages/crypto.scm
  (tomb)[arguments]<#:phases>{wrap}: Likewise.
* gnu/packages/cups.scm
  (cups-filters)[arguments]<#:phases>{wrap-filters}: Likewise.
  (foo2zjs)[arguments]<#:phases>{wrap-wrappers}: Likewise.
* gnu/packages/databases.scm
  (ephemeralpg)[arguments]<#:phases>{wrap}: Likewise.
  (sqitch)[arguments]<#:phases>{wrap-progam}: Likewise.
* gnu/packages/debian.scm
  (debootstrap)[arguments]<#:phases>{wrap-executable}: Likewise.
* gnu/packages/debug.scm
  (c-reduce)[arguments]<#:phases>{set-load-paths}: Likewise.
  (scanmem)[arguments]<#:phases>{wrap-gameconqueror}: Likewise.
* gnu/packages/dictionaries.scm
  (translate-shell)[arguments]<#:phases>{wrap-binary}: Likewise.
* gnu/packages/disk.scm
  (ranger)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/display-managers.scm
  (lightdm)[arguments]<#:phases>{pre-check}: Likewise, but use native-inputs
  instead, as this is for the test suite.
  (lightdm-gtk-greeter)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/djvu.scm
  (didjvu)[arguments]<#:phases>{wrap-path}: Likewise.
  (ocrodjvu)[arguments]<#:phases>{wrap-path}: Likewise.
* gnu/packages/dns.scm
  (knot-resolver)[arguments]<#:phases>{wrap-binary}: Likewise.
  (ddclient)[arguments]<#:builder>: Likewise, but use %build-inputs instead.
* gnu/packages/docbook.scm
  (dblatex)[arguments]<#:phases>{set-path}: Likewise.
* gnu/packages/documentation.scm
  (zeal)[arguments]<#:phases>{wrap-qt-process-path}: Likewise.
* gnu/packages/ebook.scm
  (calibre)[arguments]<#:phases>{wrap-program}: Likewise.
  (cozy)[arguments]<#:phases>{wrap-libs}: Likewise.
* gnu/packages/education.scm
  (gcompris-qt)[arguments]<#:phases>{wrap-executable}: Likewise.
  (anki)[arguments]<#:phases>{wrap}: Likewise.
* gnu/packages/emacs-xyz.scm
  (emacsspeak)[arguments]<#:phases>{wrap-program}: Likewise.
  (emacs-ert-runner)[arguments]<#:phases>{install-executable}: Likewise.
  (emacs-edbi)[arguments]<#:phases>{patch-pad}: Likewise.
* gnu/packages/emulators.scm
  (higan)[arguments]<#:phases>{wrap-higan-executable}: Likewise.
  (nestopia-ue)[arguments]<#:phases>{wrap-program}: Likewise.
  (pcsxr)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/engineering.scm
  (librecad)[arguments]<#:phases>{wrap-executable}: Likewise.
  (pcb)[arguments]<#:phases>{wrap}: Likewise.
  (kicad)[arguments]<#:phases>{wrap-program}: Likewise.
  (volk)[arguments]<#:phases>{wrap-pythonpath}: Likewise.
  (freehdl)[arguments]<#:phases>{make-wrapper}: Likewise.
  (qucs)[arguments]<#:phases>{make-wrapper}: Likewise.
  (qucs-s)[arguments]<#:phases>{make-wrapper}: Likewise.
  (freecad)[arguments]<#:phases>{wrap-pythonpath}: Likewise.
* gnu/packages/file-systems.scm
  (bcachefs-tools)[arguments]<#:phases>{promote-mount.bcachefs.sh}: Likewise.
* gnu/packages/finance.scm
  (electron-cash)[arguments]<#:phases>{wrap-qt}: Likewise,
  but for 'wrap-qt-program'.
* gnu/packages/fontutils.scm
  (fontforge)[arguments]<#:phases>{set-library-path}: Likewise.
  (fntsample)[arguments]<#:phases>{set-library-path}: Likewise.
* gnu/packages/freedesktop.scm
  (xdg-utils)[arguments]<#:phases>{post-install}: Likewise.
  (udisks)[arguments]<#:phases>{wrap-udisksd}: Likewise.
  (perl-file-mimeinfo)[arguments]<#:phases>{wrap-programs}: Likewise.
  (udiskie)[arguments]<#:phases>{wrap-gi-typelib}: Likewise.
* gnu/packages/game-development.scm
  (renpy)[arguments]<#:phases>{wrap}: Likewise.
  (godot)[arguments]<#:phases>{install}: Likewise.
* gnu/packages/games.scm
  (corsix-th)[arguments]<#:phases>{wrap-binary}: Likewise.
  (gamine)[arguments]<#:phases>{wrap-gamine}: Likewise.
  (tuxpaint)[arguments]<#:phases>{fix-import}: Likewise.
  (xonotic)[arguments]<#:phases>{wrap-binaries}: Likewise.
  (frozen-bubble)[arguments]<#:phases>{wrap-perl-libs}: Likewise.
  (flightgear)[arguments]<#:phases>{wrap-executable}: Likewise.
  (kajongg)[arguments]<#:phases>{wrap}: Likewise.
  (neverball)[arguments]<#:phases>{fix-some-broken-fonts}: Likewise.
* gnu/packages/genealogy.scm
  (gramps)[arguments]<#:phases>{wrap-with-GI_TYPELIB_PATH}: Likewise.
* gnu/packages/geo.scm
  (gnome-maps)[arguments]<#:phases>{wrap}: Likewise.
  (qmapshack)[arguments]<#:phases>{wrap}: Likewise.
  (grass)[arguments]<#:phases>{wrap-with-python-interpreter}: Likewise.
  (qgis)[arguments]<#:phases>{wrap-qt}: Likewise, but for wrap-qt-program.
  (qgis)[arguments]<#:phases>{wrap-gis}: Likewise.
* gnu/packages/gettext.scm
  (po4a)[arguments]<#:phases>{wrap-programs}: Likewise.
* gnu/packages/glib.scm
  (itstool)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/gnome-xyz.scm
  (gnome-shell-extension-gsconnect)[arguments]<#:phases>{wrap-daemons}:
  Likewise.
* gnu/packages/gnome.scm
  (gnome-photos)[arguments]<#:phases>{wrap-gnome-photos}: Likewise.
  (gnome-music)[arguments]<#:phases>{wrap-gnome-music}: Likewise.
  (sushi)[arguments]<#:phases>{wrap-typelib}: Likewise.
  (gnome-characters)[arguments]<#:phases>{wrap}: Likewise.
  (gtg)[arguments]<#:phases>{python-and-gi-wrap}: Likewise.
  (icon-naming-utils)[arguments]<#:phases>{set-load-paths}: Likewise.
  (system-config-printer)[arguments]<#:phases>{wrap}: Likewise.
  (totem)[arguments]<#:phases>{wrap-totem}: Likewise.
  (rhythmbox)[arguments]<#:phases>{wrap-rhythmbox}: Likewise.
  (eog)[arguments]<#:phases>{wrap-eog}: Likewise.
  (eolie)[arguments]<#:phases>{wrap-more}: Likewise.
  (d-feet)[arguments]<#:phases>{wrap-program}: Likewise.
  (gnome-session)[arguments]<#:phases>{wrap-gnome-session}: Likewise.
  (gedit)[arguments]<#:phases>{wrap-gedit}: Likewise.
  (caribou)[arguments]<#:phases>{wrap-programs}: Likewise.
  (gnome-shell)[arguments]<#:phases>{wrap-programs}: Likewise.
  (gnome-control-center)[arguments]<#:phases>{wrap-programs}: Likewise.
  (gnome-weather)[arguments]<#:phases>{wrap}: Likewise.
  (authenticator)[arguments]<#:phases>{python-and-gi-wrap}: Likewise.
  (gnome-todo)[arguments]<#:phases>{wrap-gnome-todo}: Likewise.
  (gnome-tweaks)[arguments]<#:phases>{wrap-gi-typelib}: Likewise.
  (orca)[arguments]<#:phases>{wrap-orca}: Likewise.
  (lollypop)[arguments]<#:phases>{wrap-program}: Likewise.
  (cheese)[arguments]<#:phases>{wrap-cheese}: Likewise.
  (passwordsafe)[arguments]<#:phases>{python-and-gi-wrap}: Likewise.
  (soundconverter)[arguments]<#:phases>{wrap-sound-converter}: Likewise.
  (terminator)[arguments]<#:phases>{wrap-program}: Likewise.
  (gitg)[arguments]<#:phases>{wrap-typelib}: Likewise.
  (polari)[arguments]<#:phases>{wrap-typelib}: Likewise.
  (setzer)[arguments]<#:phases>{python-and-gi-wrap}: Likewise.
  (libratbag)[arguments]<#:phases>{wrap}: Likewise.
  (piper)[arguments]<#:phases>{wrap}: Likewise.
  (parlatype)[arguments]<#:phases>{wrap-parlatype}: Likewise.
  (komikku)[arguments]<#:phases>{python-and-gi-wrap}: Likewise.
  (ocrfeeder)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/gnucash.scm
  (gnucash)[arguments]<#:phases>{wrap-programs}: Likewise.
* gnu/packages/gnupg.scm
  (signing-party)[arguments]<#:phases>{wrap-programs}: Likewise.
  (pinentry-rofi)[arguments]<#:phases>{hall-wrap-binaries}: Likewise.
  (gpa)[arguments]<#:phases>{wrap-program}: Likewise.
  (parcimonie)[arguments]<#:phases>{wrap-program}: Likewise.
* gnu/packages/password-utils.scm
  (qtpass)[arguments]<#:phases>{wrap-qt}: Likewise, but for
  'wrap-qt-program'.
* gnu/packages/video.scm
  (openshot)[arguments]<#:phases>{wrap-program}: Likewise, but for
  'wrap-qt-program'.
* gnu/packages/web-browsers.scm
  (luakit)[arguments]<#:phases>{wrap}: Likewise.
  (kristall)[arguments]<#:phases>{wrap-program}: Likewise, but for
  'wrap-qt-program'.
  (qutebrowser)[arguments]<#:phases>{wrap-qt-process-path}: Likewise.
  (nyxt)[arguments]<#:phases>{wrap-program}: Likewise.
---
 gnu/packages/admin.scm                  | 28 ++++----
 gnu/packages/animation.scm              |  3 +
 gnu/packages/arcan.scm                  |  3 +-
 gnu/packages/audio.scm                  |  1 +
 gnu/packages/backup.scm                 |  1 +
 gnu/packages/benchmark.scm              |  3 +-
 gnu/packages/bioinformatics.scm         | 51 +++++++++-----
 gnu/packages/bittorrent.scm             |  8 +--
 gnu/packages/cdrom.scm                  | 12 ++--
 gnu/packages/chromium.scm               |  2 +-
 gnu/packages/ci.scm                     |  1 +
 gnu/packages/code.scm                   |  4 +-
 gnu/packages/connman.scm                |  4 +-
 gnu/packages/crypto.scm                 |  1 +
 gnu/packages/cups.scm                   |  4 +-
 gnu/packages/databases.scm              |  4 +-
 gnu/packages/debian.scm                 |  4 +-
 gnu/packages/debug.scm                  |  4 +-
 gnu/packages/dictionaries.scm           |  2 +-
 gnu/packages/disk.scm                   |  2 +-
 gnu/packages/display-managers.scm       |  4 +-
 gnu/packages/djvu.scm                   |  2 +
 gnu/packages/dns.scm                    |  3 +-
 gnu/packages/docbook.scm                |  1 +
 gnu/packages/documentation.scm          |  2 +-
 gnu/packages/ebook.scm                  |  6 +-
 gnu/packages/education.scm              |  3 +-
 gnu/packages/emacs-xyz.scm              |  5 +-
 gnu/packages/emulators.scm              |  5 +-
 gnu/packages/engineering.scm            | 13 ++--
 gnu/packages/file-systems.scm           |  2 +-
 gnu/packages/finance.scm                |  5 +-
 gnu/packages/fontutils.scm              |  3 +-
 gnu/packages/freedesktop.scm            |  9 ++-
 gnu/packages/game-development.scm       |  2 +
 gnu/packages/games.scm                  | 29 +++++---
 gnu/packages/genealogy.scm              |  1 +
 gnu/packages/geo.scm                    | 11 +--
 gnu/packages/gettext.scm                |  2 +-
 gnu/packages/glib.scm                   |  4 +-
 gnu/packages/gnome-xyz.scm              |  1 +
 gnu/packages/gnome.scm                  | 92 +++++++++++++++----------
 gnu/packages/gnucash.scm                |  1 +
 gnu/packages/gnupg.scm                  | 12 ++--
 gnu/packages/password-utils.scm         |  4 +-
 gnu/packages/video.scm                  |  4 +-
 gnu/packages/web-browsers.scm           |  9 +--
 guix/build/glib-or-gtk-build-system.scm | 14 ++--
 guix/build/python-build-system.scm      |  2 +-
 guix/build/qt-build-system.scm          |  2 +-
 guix/build/qt-utils.scm                 |  3 +-
 guix/build/rakudo-build-system.scm      |  2 +-
 guix/build/utils.scm                    |  4 +-
 tests/build-utils.scm                   | 19 +++--
 54 files changed, 262 insertions(+), 161 deletions(-)

diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index 4be6250cbd..a31d3e1084 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -391,9 +391,9 @@ inspired by @command{vi}.")
            (lambda* (#:key outputs inputs #:allow-other-keys)
              (let ((growpart (string-append (assoc-ref outputs "out")
                                             "/bin/growpart")))
-               (wrap-program growpart
-                 `("PATH" ":" prefix (,(dirname (which "sfdisk"))
-                                      ,(dirname (which "readlink"))))))
+               (wrap-program growpart inputs
+                 `("PATH" ":" prefix (,(dirname (which "sfdisk" inputs))
+                                      ,(dirname (which "readlink" inputs))))))
              #t)))))
     (inputs
      `(("python" ,python)
@@ -1224,8 +1224,8 @@ connection alive.")
                  (copy-file "client/scripts/linux"
                             (string-append libexec "/dhclient-script"))
 
-                 (wrap-program
-                     (string-append libexec "/dhclient-script")
+                 (wrap-program (string-append libexec "/dhclient-script")
+                   inputs
                    `("PATH" ":" prefix
                      ,(map (lambda (dir)
                              (string-append dir "/bin:"
@@ -1384,7 +1384,7 @@ by bandwidth they use.")
                (with-directory-excursion bin
                  (for-each
                   (lambda (program)
-                    (wrap-program program
+                    (wrap-program program inputs
                       `("PERL5LIB" ":" prefix
                         ,(map (lambda (file-name)
                                 (string-append file-name
@@ -1451,13 +1451,13 @@ over ssh connections.")
        (modify-phases %standard-phases
          (add-after 'install 'find-itself
            ;; Fix run-time 'Can't locate File/Rename.pm in @INC' failure.
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin")))
                (with-directory-excursion bin
                  (for-each
                   (lambda (program)
-                    (wrap-program program
+                    (wrap-program program inputs
                       `("PERL5LIB" ":" prefix
                         (,(string-append out "/lib/perl5/site_perl")))))
                   (find-files "." ".*")))
@@ -1873,6 +1873,7 @@ command.")
                         (copy-recursively "icons/hicolor"
                                           (string-append out "/share/icons/hicolor"))
                         (wrap-program (string-append out "/bin/wpa_gui")
+                          inputs
                           `("QT_PLUGIN_PATH" ":" prefix
                             ,(map (lambda (label)
                                     (string-append (assoc-ref inputs label)
@@ -2851,7 +2852,7 @@ done with the @code{auditctl} utility.")
                (("build-dnet build-lua") "build-dnet"))
              #t))
          (replace 'install
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (define (make out . args)
                (apply invoke "make"
                       (string-append "prefix=" out)
@@ -2871,6 +2872,7 @@ done with the @code{auditctl} utility.")
                  "install-nping")
                (make ndiff "install-ndiff")
                (wrap-program (string-append ndiff "/bin/ndiff")
+                 inputs
                  `("GUIX_PYTHONPATH" prefix
                    (,(python-path ndiff)))))
              #t))
@@ -2923,9 +2925,10 @@ results (ndiff), and a packet generation and response analysis tool (nping).")
              #t))
          (delete 'configure)            ; no configure script
          (add-after 'install 'wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/dstat")
+                 inputs
                  `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (inputs
@@ -3456,8 +3459,8 @@ you are running, what theme or icon set you are using, etc.")
              (("/usr/bin/env bash")
               (string-append (assoc-ref %build-inputs "bash")
                              "/bin/bash")))
-           (wrap-program
-               (string-append out "/bin/screenfetch")
+           (wrap-program (string-append out "/bin/screenfetch")
+             %build-inputs
              `("PATH" ":" prefix
                (,(string-append (assoc-ref %build-inputs "bc") "/bin:"
                                 (assoc-ref %build-inputs "scrot") "/bin:"
@@ -3849,6 +3852,7 @@ Python loading in HPC environments.")
              (let ((bin (string-append %output "/bin")))
                (install-file "inxi" bin)
                (wrap-program (string-append bin "/inxi")
+                 %build-inputs
                  `("PATH" ":" =
                    ("$PATH"
                     ,@(map (lambda (input)
diff --git a/gnu/packages/animation.scm b/gnu/packages/animation.scm
index 3a915c7fda..659955fb7a 100644
--- a/gnu/packages/animation.scm
+++ b/gnu/packages/animation.scm
@@ -218,6 +218,7 @@ for tweening, preventing the need to hand-draw each frame.")
                     (gtk (assoc-ref inputs "gtk+"))
                     (gtk-share (string-append gtk "/share")))
                (wrap-program (string-append out "/bin/synfigstudio")
+                 inputs
                  `("XDG_DATA_DIRS" ":" prefix (,gtk-share)))
                #t))))))
     (inputs
@@ -367,6 +368,7 @@ audio or video backends, ensuring good performance.")
                (let* ((out (assoc-ref outputs "out"))
                       (qt '("qt" "qtmultimedia")))
                  (wrap-program (string-append out "/bin/Papagayo")
+                   inputs
                    `("QT_PLUGIN_PATH" ":" prefix
                      ,(map (lambda (label)
                              (string-append (assoc-ref inputs label)
@@ -420,6 +422,7 @@ waveform until they line up with the proper sounds.")
              (let ((out (assoc-ref outputs "out"))
                    (plugin-path (getenv "QT_PLUGIN_PATH")))
                (wrap-program (string-append out "/bin/pencil2d")
+                 inputs
                  `("QT_PLUGIN_PATH" ":" prefix (,plugin-path)))
                #t))))))
     (home-page "https://www.pencil2d.org")
diff --git a/gnu/packages/arcan.scm b/gnu/packages/arcan.scm
index a84bf0d8dd..a3cfca601c 100644
--- a/gnu/packages/arcan.scm
+++ b/gnu/packages/arcan.scm
@@ -99,9 +99,10 @@
                (chdir "src")
                #t))
            (add-after 'install 'wrap-program
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let ((out (assoc-ref outputs "out")))
                  (wrap-program (string-append out "/bin/arcan")
+                   inputs
                    `("ARCAN_RESOURCEPATH" ":" suffix
                      (,(string-append out "/share/arcan/resources")))
                    `("ARCAN_STATEBASEPATH" ":" =
diff --git a/gnu/packages/audio.scm b/gnu/packages/audio.scm
index 50627cc3e7..90cef1eed4 100644
--- a/gnu/packages/audio.scm
+++ b/gnu/packages/audio.scm
@@ -2104,6 +2104,7 @@ synchronous execution of all clients, and low latency operation.")
              (let* ((out (assoc-ref outputs "out"))
                     (path (getenv "GUIX_PYTHONPATH")))
                (wrap-program (string-append out "/bin/jack_control")
+                 inputs
                  `("GUIX_PYTHONPATH" ":" prefix (,path))))
              #t)))))
     (inputs
diff --git a/gnu/packages/backup.scm b/gnu/packages/backup.scm
index beea447eb1..c84bb92359 100644
--- a/gnu/packages/backup.scm
+++ b/gnu/packages/backup.scm
@@ -816,6 +816,7 @@ NTFS volumes using @code{ntfs-3g}, preserving NTFS-specific attributes.")
                      (display text-to-write)))
                  (chmod target-file-location #o755)
                  (wrap-program target-file-location
+                   inputs
                    `("PERL5LIB" ":" prefix
                      ,(map (lambda (l) (string-append (assoc-ref %build-inputs l)
                                                       "/lib/perl5/site_perl"))
diff --git a/gnu/packages/benchmark.scm b/gnu/packages/benchmark.scm
index 70e878e866..4b3d60b701 100644
--- a/gnu/packages/benchmark.scm
+++ b/gnu/packages/benchmark.scm
@@ -90,7 +90,7 @@
          ;; Moving the auxiliary python and gnuplot scripts to a separate
          ;; output saves almost 400 MiB on the closure.
          (add-after 'install 'move-outputs
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((oldbin (string-append (assoc-ref outputs "out") "/bin"))
                    (newbin (string-append (assoc-ref outputs "utils") "/bin")))
                (mkdir-p newbin)
@@ -103,6 +103,7 @@
                            "fiologparser.py"))
                ;; Make sure numpy et.al is found.
                (wrap-program (string-append newbin "/fiologparser_hist.py")
+                 inputs
                  `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (outputs '("out" "utils"))
diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 2ca56d3962..dd4a6e6b72 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -248,6 +248,7 @@ structure of the predicted RNA.")
                     (path (getenv "PATH"))
                     (pythonpath (getenv "GUIX_PYTHONPATH")))
                (wrap-program (string-append out "/bin/bamm")
+                 inputs
                  `("PATH" ":" prefix (,path))
                  `("GUIX_PYTHONPATH" ":" prefix (,pythonpath)))))))))
     (native-inputs
@@ -682,6 +683,7 @@ cpp.find_library('hdf5_cpp', dirs : '~a'), "
                (for-each
                 (lambda (script)
                   (wrap-program (string-append out "/bin/" script)
+                    inputs
                     `("R_LIBS_SITE" ":" = (,(getenv "R_LIBS_SITE")))))
                 '("create_annotations_files.bash"
                   "create_metaplots.bash"
@@ -1063,7 +1065,7 @@ alignments and perform the following operations:
          (modify-phases %standard-phases
            (add-after
             'install 'wrap-programs
-            (lambda* (#:key outputs #:allow-other-keys)
+            (lambda* (#:key inputs outputs #:allow-other-keys)
               ;; Make sure all executables in "bin" find the required Perl
               ;; modules at runtime.  As the PERL5LIB variable contains also
               ;; the paths of native inputs, we pick the transitive target
@@ -1077,7 +1079,7 @@ alignments and perform the following operations:
                                        ',transitive-inputs))
                             ":")))
                 (for-each (lambda (file)
-                            (wrap-program file
+                            (wrap-program file inputs
                               `("PERL5LIB" ":" prefix (,path))))
                           (find-files bin "\\.pl$"))
                 #t))))))
@@ -2065,12 +2067,13 @@ high-throughput sequencing data – with an emphasis on simplicity.")
                 (string-append "\"" (which "Rscript") "\"")))
              #t))
          (add-after 'install 'wrap-program
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              ;; Make sure the executables find R packages.
              (let ((out (assoc-ref outputs "out")))
                (for-each
                 (lambda (script)
                   (wrap-program (string-append out "/bin/" script)
+                    inputs
                     `("R_LIBS_SITE" ":" = (,(getenv "R_LIBS_SITE")))))
                 '("TEtranscripts"
                   "TEcount")))
@@ -2271,6 +2274,7 @@ gene predictor designed to work with assembled, aligned RNA-seq transcripts.")
             (let* ((out (assoc-ref outputs "out"))
                    (path (getenv "GUIX_PYTHONPATH")))
               (wrap-program (string-append out "/bin/couger")
+                inputs
                 `("GUIX_PYTHONPATH" ":" prefix (,path))))
             #t)))))
     (inputs
@@ -2843,13 +2847,14 @@ bases are detected.")
                          (string-append (assoc-ref inputs "hmmer")
                                         "/bin"))))))
          (replace 'install
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out   (assoc-ref outputs "out"))
                     (share (string-append out "/share/RepeatMasker"))
                     (bin   (string-append out "/bin"))
                     (path  (getenv "PERL5LIB")))
                (install-file (string-append share "/RepeatMasker") bin)
                (wrap-program (string-append bin "/RepeatMasker")
+                 inputs
                  `("PERL5LIB" ":" prefix (,path ,share)))))))))
     (inputs
      `(("perl" ,perl)
@@ -3082,15 +3087,15 @@ quantitative phenotypes.")
                         (string-append bin "/rchive")))
              #t))
          (add-after 'install 'wrap-program
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
               ;; Make sure everything can run in a pure environment.
               (let ((out (assoc-ref outputs "out"))
                     (path (getenv "PERL5LIB")))
                 (for-each
                   (lambda (file)
-                    (wrap-program file
+                    (wrap-program file inputs
                       `("PERL5LIB" ":" prefix (,path)))
-                    (wrap-program file
+                    (wrap-program file inputs
                       `("PATH" ":" prefix (,(string-append out "/bin")
                                            ,(dirname (which "sed"))
                                            ,(dirname (which "gzip"))
@@ -4792,13 +4797,13 @@ sequencing tag position and orientation.")
              #t))
          (delete 'configure)
          (add-after 'install 'wrap-programs
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin"))
                     (path (string-append
                            (assoc-ref %build-inputs "coreutils") "/bin:")))
                (for-each (lambda (file)
-                           (wrap-program file
+                           (wrap-program file inputs
                              `("PATH" ":" prefix (,path))))
                          (find-files bin)))
              #t)))))
@@ -5322,7 +5327,7 @@ generated using the PacBio Iso-Seq protocol.")
              #t))
          (delete 'configure)
          (replace 'install
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin"))
                     (man (string-append out "/share/man/man1"))
@@ -5332,6 +5337,7 @@ generated using the PacBio Iso-Seq protocol.")
                            (assoc-ref %build-inputs "bppsuite") "/bin")))
                (install-file "prank" bin)
                (wrap-program (string-append bin "/prank")
+                 inputs
                  `("PATH" ":" prefix (,path)))
                (install-file "prank.1" man))
              #t)))))
@@ -5542,11 +5548,11 @@ partial genes, and identifies translation initiation sites.")
                     (path (getenv "PATH")))
                (for-each (lambda (prog)
                            (let ((binary (string-append out "/" prog)))
-                             (wrap-program binary
+                             (wrap-program binary inputs
                                `("PERL5LIB" ":" prefix
                                  (,(string-append perl5lib ":" out
                                                   "/lib/perl5/site_perl"))))
-                             (wrap-program binary
+                             (wrap-program binary inputs
                                `("PATH" ":" prefix
                                  (,(string-append path ":" out "/bin"))))))
                          (find-files "bin" ".*[^R]$"))
@@ -5555,10 +5561,10 @@ partial genes, and identifies translation initiation sites.")
                      (r-site-lib (getenv "R_LIBS_SITE"))
                      (coreutils-path
                       (string-append (assoc-ref inputs "coreutils") "/bin")))
-                 (wrap-program file
+                 (wrap-program file inputs
                    `("R_LIBS_SITE" ":" prefix
                      (,(string-append r-site-lib ":" out "/site-library/"))))
-                 (wrap-program file
+                 (wrap-program file inputs
                    `("PATH" ":" prefix
                      (,(string-append coreutils-path ":" out "/bin"))))))
              #t)))))
@@ -5705,10 +5711,11 @@ phylogenies.")
                (install-file "rsem_perl_utils.pm" perl))
              #t))
          (add-after 'install 'wrap-program
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (for-each (lambda (prog)
                            (wrap-program (string-append out "/bin/" prog)
+                             inputs
                              `("PERL5LIB" ":" prefix
                                (,(string-append out "/lib/perl5/site_perl")))))
                          '("rsem-calculate-expression"
@@ -8239,6 +8246,7 @@ library implementing most of the pipeline's features.")
                              json  "/share/guile/site/2.2:"
                              redis "/share/guile/site/2.2")))
                (wrap-program (string-append out "/bin/rcas-web")
+                 inputs
                  `("GUILE_LOAD_PATH" ":" = (,path))
                  `("GUILE_LOAD_COMPILED_PATH" ":" = (,path))
                  `("R_LIBS_SITE" ":" = (,(getenv "R_LIBS_SITE")))))
@@ -12351,13 +12359,14 @@ conversions, region filtering, FASTA sequence extraction and more.")
            (delete 'configure)
            (delete 'build)
            (replace 'install
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let* ((out (assoc-ref outputs "out"))
                       (bin (string-append out "/bin"))
                       (path (getenv "GUIX_PYTHONPATH")))
                  (for-each (lambda (script)
                              (install-file script bin)
                              (wrap-program (string-append bin "/" script)
+                               inputs
                                `("GUIX_PYTHONPATH" ":" prefix (,path))))
                            '("cmp_bed.py"
                              "find_circ.py"
@@ -13199,6 +13208,7 @@ of the Hierarchical Data Format (HDF5) standard.")
                   (chmod script #o555)
                   (install-file script bin)
                   (wrap-program (string-append bin "/" script)
+                    inputs
                     `("PATH" ":" prefix
                       (,(string-append (assoc-ref inputs "coreutils") "/bin")
                        ,(string-append (assoc-ref inputs "gawk") "/bin")
@@ -13386,6 +13396,7 @@ datasets.")
                       (path (getenv "GUIX_PYTHONPATH")))
                  (wrap-program (string-append out
                                               "/share/filtlong/scripts/histogram.py")
+                   inputs
                    `("GUIX_PYTHONPATH" ":" prefix (,path))))
                #t))
            (add-before 'check 'patch-tests
@@ -13464,7 +13475,8 @@ choosing which reads pass the filter.")
                      (scripts (string-append (assoc-ref outputs "out")
                                              "/share/nanopolish/scripts")))
                  (for-each (lambda (file)
-                             (wrap-program file `("GUIX_PYTHONPATH" ":" prefix (,pythonpath))))
+                             (wrap-program file inputs
+                                           `("GUIX_PYTHONPATH" ":" prefix (,pythonpath))))
                            (find-files scripts "\\.py"))
                  (for-each (lambda (file)
                              (wrap-script file inputs
@@ -13762,12 +13774,13 @@ includes a command line tool and an analysis pipeline.")
                 (string-append (which "samtools") " sort")))
              #t))
          (replace 'install
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((bin (string-append (assoc-ref outputs "out") "/bin")))
                (install-file "arriba" bin)
                (install-file "run_arriba.sh" bin)
                (install-file "draw_fusions.R" bin)
                (wrap-program (string-append bin "/draw_fusions.R")
+                 inputs
                  `("R_LIBS_SITE" ":" prefix (,(getenv "R_LIBS_SITE")))))
              #t)))))
     (inputs
@@ -13971,10 +13984,12 @@ downstream analysis.")
                             (assoc-ref inputs "infernal") "/bin")))
                  (display path)
                  (wrap-program (string-append bin "/refpkg_align.py")
+                   inputs
                    `("PATH" ":" prefix (,path))))
                (let ((path (string-append
                             (assoc-ref inputs "hmmer") "/bin")))
                  (wrap-program (string-append bin "/hrefpkg_query.py")
+                   inputs
                    `("PATH" ":" prefix (,path)))))
              #t)))))
     (inputs
diff --git a/gnu/packages/bittorrent.scm b/gnu/packages/bittorrent.scm
index 29b0d62ad2..34a1d271a7 100644
--- a/gnu/packages/bittorrent.scm
+++ b/gnu/packages/bittorrent.scm
@@ -448,8 +448,8 @@ desktops.")
        #:phases
        (modify-phases %standard-phases
          (add-after 'install 'wrap-qt
-           (lambda* (#:key outputs #:allow-other-keys)
-             (wrap-qt-program (assoc-ref outputs "out") "qbittorrent")
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (wrap-qt-program (assoc-ref outputs "out") "qbittorrent" inputs)
              #t)))))
     (native-inputs
      `(("pkg-config" ,pkg-config)
@@ -524,12 +524,12 @@ features.")
                (("names='ngettext'") "names=['ngettext']"))
              #t))
          (add-after 'install 'wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out               (assoc-ref outputs "out"))
                    (gi-typelib-path   (getenv "GI_TYPELIB_PATH")))
                (for-each
                 (lambda (program)
-                  (wrap-program program
+                  (wrap-program program inputs
                     `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
                 (map (lambda (name)
                        (string-append out "/bin/" name))
diff --git a/gnu/packages/cdrom.scm b/gnu/packages/cdrom.scm
index dd1283b26d..f612bd4b30 100644
--- a/gnu/packages/cdrom.scm
+++ b/gnu/packages/cdrom.scm
@@ -183,7 +183,7 @@ libcdio.")
                (install-file "frontend/grub-mkrescue-sed.sh" out-bin)
                #t)))
          (add-after 'install 'move-gui-to-separate-output
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out"))
                    (gui (assoc-ref outputs "gui")))
                (for-each
@@ -195,6 +195,7 @@ libcdio.")
                        "/share/info/xorriso-tcltk.info"
                        "/share/man/man1/xorriso-tcltk.1"))
                (wrap-program (string-append gui "/bin/xorriso-tcltk")
+                 inputs
                  `("PATH" ":" prefix (,(string-append out "/bin"))))
                #t))))))
     (inputs
@@ -515,6 +516,7 @@ capacity is user-selectable.")
          (add-after 'install 'wrap-program
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (wrap-program (string-append (assoc-ref outputs "out") "/bin/dvdstyler")
+               inputs
                `("PATH" ":" prefix
                  (,(string-join
                     (map (lambda (in) (string-append (assoc-ref inputs in) "/bin"))
@@ -658,7 +660,7 @@ from an audio CD.")
                    (flac   (assoc-ref inputs "flac"))
                    (out    (assoc-ref outputs "out")))
                (define (wrap file)
-                 (wrap-program file
+                 (wrap-program file inputs
                                `("PATH" ":" prefix
                                  (,(string-append out "/bin:"
                                                   wget "/bin:"
@@ -760,7 +762,7 @@ information is written to standard error.")
                                                     "/bin/asunder")))
                         (define (bin-directory input-name)
                           (string-append (assoc-ref inputs input-name) "/bin"))
-                        (wrap-program program
+                        (wrap-program program inputs
                           `("PATH" ":" prefix
                             ,(map bin-directory (list "cdparanoia"
                                                       "lame"
@@ -1039,10 +1041,10 @@ drive and disc (including CD-ROMs and DVD-ROMs).")
                                            "/bin/cdemu"))
              #t))
          (add-after 'patch-shebang 'wrap-program
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/cdemu")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (home-page "https://cdemu.sourceforge.io/")
diff --git a/gnu/packages/chromium.scm b/gnu/packages/chromium.scm
index 835e9e2050..b8ffdf4349 100644
--- a/gnu/packages/chromium.scm
+++ b/gnu/packages/chromium.scm
@@ -777,7 +777,7 @@
                              (install-file so (string-append lib "/swiftshader")))
                            (find-files "swiftshader" "\\.so$"))
 
-                 (wrap-program exe
+                 (wrap-program exe inputs
                    ;; Avoid file manager crash.  See <https://bugs.gnu.org/26593>.
                    `("XDG_DATA_DIRS" ":" prefix (,(string-append gtk+ "/share")))
                    `("PATH" ":" prefix (,(string-append xdg-utils "/bin")))))
diff --git a/gnu/packages/ci.scm b/gnu/packages/ci.scm
index 8d93513332..75e1f1b333 100644
--- a/gnu/packages/ci.scm
+++ b/gnu/packages/ci.scm
@@ -145,6 +145,7 @@
                         1)))
                  ;; Make sure 'cuirass' can find the relevant Guile modules.
                  (wrap-program (string-append out "/bin/cuirass")
+                   inputs
                    `("PATH" ":" prefix (,(string-append out "/bin")))
                    `("GUILE_LOAD_PATH" ":" prefix (,mods))
                    `("GUILE_LOAD_COMPILED_PATH" ":" prefix (,objs)))
diff --git a/gnu/packages/code.scm b/gnu/packages/code.scm
index a79d8b4a2b..1670915f63 100644
--- a/gnu/packages/code.scm
+++ b/gnu/packages/code.scm
@@ -270,6 +270,7 @@ COCOMO model or user-provided parameters.")
                     (lambda* (#:key inputs outputs #:allow-other-keys)
                       (let ((out (assoc-ref outputs "out")))
                         (wrap-program (string-append out "/bin/cloc")
+                          inputs
                           `("PERL5LIB" ":" =
                             ,(string-split (getenv "PERL5LIB") #\:)))
                         #t))))
@@ -513,9 +514,10 @@ stack traces.")
              #t))
          (delete 'configure)            ;no configure script
          (add-after 'install 'wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/geninfo")
+                 inputs
                  `("PERL5LIB" ":" prefix (,(getenv "PERL5LIB")))))
              #t)))))
     (inputs `(("perl" ,perl)
diff --git a/gnu/packages/connman.scm b/gnu/packages/connman.scm
index 78204dbae7..fb99f67f2d 100644
--- a/gnu/packages/connman.scm
+++ b/gnu/packages/connman.scm
@@ -117,10 +117,10 @@ sharing) to clients via USB, ethernet, WiFi, cellular and Bluetooth.")
            ;; FATAL: Cannot create run dir '/homeless-shelter/.run' - errno=2
            (lambda _ (setenv "HOME" "/tmp") #t))
          (add-after 'install 'wrap-binary
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin/econnman-bin")))
-               (wrap-program bin
+               (wrap-program bin inputs
                  `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (native-inputs `(("pkg-config" ,pkg-config)))
diff --git a/gnu/packages/crypto.scm b/gnu/packages/crypto.scm
index fd0663ea3f..ab2d09d0da 100644
--- a/gnu/packages/crypto.scm
+++ b/gnu/packages/crypto.scm
@@ -541,6 +541,7 @@ total number of shares generated.")
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/tomb")
+                 inputs
                  `("PATH" ":" prefix
                    (,(string-append (assoc-ref inputs "mlocate") "/bin")
                     ,@(map (lambda (program)
diff --git a/gnu/packages/cups.scm b/gnu/packages/cups.scm
index 236b45d90e..c6eacf1812 100644
--- a/gnu/packages/cups.scm
+++ b/gnu/packages/cups.scm
@@ -205,7 +205,7 @@ driver is known to work with these printers:
                             (ghostscript (assoc-ref inputs "ghostscript"))
                             (grep        (assoc-ref inputs "grep")))
                         (for-each (lambda (file)
-                                    (wrap-program file
+                                    (wrap-program file inputs
                                       `("PATH" ":" prefix
                                         (,(string-append ghostscript "/bin:"
                                                          grep "/bin")))))
@@ -799,7 +799,7 @@ printer/driver specific, but spooler-independent PPD file.")
                             (coreutils (assoc-ref inputs "coreutils"))
                             (sed (assoc-ref inputs "sed")))
                         (for-each (lambda (file)
-                                    (wrap-program file
+                                    (wrap-program file inputs
                                       `("PATH" ":" prefix
                                         (,(string-append ghostscript "/bin:"
                                                          coreutils "/bin:"
diff --git a/gnu/packages/databases.scm b/gnu/packages/databases.scm
index 3c865b05c1..008939f462 100644
--- a/gnu/packages/databases.scm
+++ b/gnu/packages/databases.scm
@@ -217,6 +217,7 @@ either single machines or networked clusters.")
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/pg_tmp")
+                 inputs
                  `("PATH" ":" prefix
                    (,(string-append (assoc-ref inputs "util-linux")
                                     "/bin")
@@ -1522,10 +1523,11 @@ for example from a shell script.")
              (setenv "HOME" "/tmp")
              #t))
          (add-after 'install 'wrap-program
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (path (getenv "PERL5LIB")))
                (wrap-program (string-append out "/bin/sqitch")
+                 inputs
                  `("PERL5LIB" ":" prefix
                    (,(string-append out "/lib/perl5/site_perl"
                                     ":"
diff --git a/gnu/packages/debian.scm b/gnu/packages/debian.scm
index 26b7f5194e..8c640eb80e 100644
--- a/gnu/packages/debian.scm
+++ b/gnu/packages/debian.scm
@@ -177,11 +177,11 @@ contains the archive keys used for that.")
                              (string-append out "/share/man/man8"))
                #t)))
          (add-after 'install 'wrap-executable
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((debootstrap (string-append (assoc-ref outputs "out")
                                                "/sbin/debootstrap"))
                    (path        (getenv "PATH")))
-               (wrap-program debootstrap
+               (wrap-program debootstrap inputs
                              `("PATH" ":" prefix (,path)))
                #t))))
        #:make-flags (list (string-append "DESTDIR=" (assoc-ref %outputs "out")))
diff --git a/gnu/packages/debug.scm b/gnu/packages/debug.scm
index 9a4ce7067a..3baa3d4091 100644
--- a/gnu/packages/debug.scm
+++ b/gnu/packages/debug.scm
@@ -150,8 +150,7 @@ program to exhibit a bug.")
              ;; Tell creduce where to find the perl modules it needs.
              (let* ((out (assoc-ref outputs "out"))
                     (prog (string-append out "/bin/creduce")))
-               (wrap-program
-                   prog
+               (wrap-program prog inputs
                  `("PERL5LIB" ":" prefix
                    ,(map (lambda (p)
                            (string-append (assoc-ref inputs p)
@@ -515,6 +514,7 @@ input.  Zzuf's behaviour is deterministic, making it easy to reproduce bugs.")
                    (gi-typelib-path   (getenv "GI_TYPELIB_PATH"))
                    (python-path       (getenv "GUIX_PYTHONPATH")))
                (wrap-program (string-append out "/share/gameconqueror/GameConqueror.py")
+                 inputs
                  `("GI_TYPELIB_PATH"        ":" prefix (,gi-typelib-path))
                  `("GUIX_PYTHONPATH"             ":" prefix (,python-path))))
              #t)))))
diff --git a/gnu/packages/dictionaries.scm b/gnu/packages/dictionaries.scm
index 2c2a7f0118..4fbf702d75 100644
--- a/gnu/packages/dictionaries.scm
+++ b/gnu/packages/dictionaries.scm
@@ -269,7 +269,7 @@ and a Python library.")
                     (curl    (assoc-ref inputs "curl"))
                     (fribidi (assoc-ref inputs "fribidi"))
                     (rlwrap  (assoc-ref inputs "rlwrap")))
-               (wrap-program bin
+               (wrap-program bin inputs
                              `("PATH" ":" prefix
                                (,(string-append out "/bin:"
                                                 curl "/bin:"
diff --git a/gnu/packages/disk.scm b/gnu/packages/disk.scm
index bf0897b083..1b1dcf2964 100644
--- a/gnu/packages/disk.scm
+++ b/gnu/packages/disk.scm
@@ -758,7 +758,7 @@ Duperemove can also take input from the @command{fdupes} program.")
                     (w3m (assoc-ref inputs "w3m"))
                     (w3mimgdisplay (string-append w3m
                                    "/libexec/w3m/w3mimgdisplay")))
-               (wrap-program ranger
+               (wrap-program ranger inputs
                  `("W3MIMGDISPLAY_PATH" ":" prefix (,w3mimgdisplay)))
                #t)))
          (replace 'check
diff --git a/gnu/packages/display-managers.scm b/gnu/packages/display-managers.scm
index 264ad34ba3..589e07acbc 100644
--- a/gnu/packages/display-managers.scm
+++ b/gnu/packages/display-managers.scm
@@ -221,8 +221,9 @@ easy to use, login interface with a modern yet classy touch.")
              #t))
          (add-before 'check 'pre-check
            ;; Run test-suite under a dbus session.
-           (lambda* (#:key inputs #:allow-other-keys)
+           (lambda* (#:key native-inputs inputs #:allow-other-keys)
              (wrap-program "tests/src/test-python-greeter"
+               (or native-inputs inputs)
                `("GUIX_PYTHONPATH"      ":" prefix (,(getenv "GUIX_PYTHONPATH")))
                `("GI_TYPELIB_PATH" ":" prefix (,(getenv "GI_TYPELIB_PATH"))))
 
@@ -293,6 +294,7 @@ display manager which supports different greeters.")
              (let ((gtk (assoc-ref inputs "gtk+")))
                (wrap-program (string-append (assoc-ref outputs "out")
                                             "/sbin/lightdm-gtk-greeter")
+                 inputs
                  `("XDG_DATA_DIRS" ":" prefix
                    ,(cons "/run/current-system/profile/share"
                           (map (lambda (pkg)
diff --git a/gnu/packages/djvu.scm b/gnu/packages/djvu.scm
index 6423eb124f..74245bbdda 100644
--- a/gnu/packages/djvu.scm
+++ b/gnu/packages/djvu.scm
@@ -394,6 +394,7 @@ It is able to:
              (let ((out (assoc-ref outputs "out"))
                    (djvulibre (assoc-ref inputs "djvulibre")))
                (wrap-program (string-append out "/bin/didjvu")
+                 inputs
                  `("PATH" ":" prefix (,(string-append djvulibre "/bin"))))))))))
     (synopsis "DjVu encoder with foreground/background separation")
     (description
@@ -474,6 +475,7 @@ and background layers of images, which can then be encoded into a DjVu file.")
                    (tesseract (assoc-ref inputs "tesseract-ocr")))
                (for-each (lambda (file)
                            (wrap-program (string-append out "/bin/" file)
+                             inputs
                              `("PATH" ":" prefix
                                (,(string-append djvulibre "/bin:"
                                                 ocrad "/bin:"
diff --git a/gnu/packages/dns.scm b/gnu/packages/dns.scm
index 3cf88febae..cccddb386e 100644
--- a/gnu/packages/dns.scm
+++ b/gnu/packages/dns.scm
@@ -993,6 +993,7 @@ synthesis, and on-the-fly re-configuration.")
                     (lua-cpath (lambda (p)
                                  (string-append p "/lib/lua/5.1/?.so"))))
                (wrap-program (string-append out "/sbin/kresd")
+                 inputs
                  `("LUA_PATH" ";" prefix ,(map lua-path lua-*))
                  `("LUA_CPATH" ";" prefix ,(map lua-cpath lua-*)))
                #t))))))
@@ -1076,7 +1077,7 @@ LuaJIT, both a resolver library and a daemon.")
                (("\\$cachedir\\$program\\.cache")
                 "/var/cache/ddclient/ddclient.cache"))
              (install-file file bin)
-             (wrap-program (string-append bin "/" file)
+             (wrap-program (string-append bin "/" file) %build-inputs
                `("PATH" ":" =
                  ("$PATH"
                   ,@(map (lambda (input)
diff --git a/gnu/packages/docbook.scm b/gnu/packages/docbook.scm
index 3fd1930c79..65b32cc892 100644
--- a/gnu/packages/docbook.scm
+++ b/gnu/packages/docbook.scm
@@ -454,6 +454,7 @@ the in DocBook SGML DTDs.")
              (let ((out (assoc-ref outputs "out")))
                ;; dblatex executes helper programs at runtime.
                (wrap-program (string-append out "/bin/dblatex")
+                 inputs
                  `("PATH" ":" prefix
                    ,(map (lambda (input)
                            (string-append (assoc-ref inputs input)
diff --git a/gnu/packages/documentation.scm b/gnu/packages/documentation.scm
index ae8553436e..3293980cb3 100644
--- a/gnu/packages/documentation.scm
+++ b/gnu/packages/documentation.scm
@@ -339,7 +339,7 @@ local system.")
                       (qt-process-path (string-append
                                         (assoc-ref inputs "qtwebengine")
                                         "/lib/qt5/libexec/QtWebEngineProcess")))
-                 (wrap-program bin
+                 (wrap-program bin inputs
                    `("QTWEBENGINEPROCESS_PATH" = (,qt-process-path)))
                  #t))))))
       (native-inputs
diff --git a/gnu/packages/ebook.scm b/gnu/packages/ebook.scm
index 4731c0fa80..5998b5bf01 100644
--- a/gnu/packages/ebook.scm
+++ b/gnu/packages/ebook.scm
@@ -312,7 +312,7 @@ sip-include-dirs = [\"" pyqt "/share/sip" "\"]")))
                (with-directory-excursion (string-append out "/bin")
                  (for-each
                   (lambda (binary)
-                    (wrap-program binary
+                    (wrap-program binary inputs
                       ;; Make QtWebEngineProcess available.
                       `("QTWEBENGINEPROCESS_PATH" =
                         ,(list (string-append
@@ -501,7 +501,7 @@ following formats:
                (rename-file "com.github.geigi.cozy" "cozy"))
              #t))
          (add-after 'wrap 'wrap-libs
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out               (assoc-ref outputs "out"))
                     (pylib             (string-append
                                         out "/lib/python"
@@ -514,7 +514,7 @@ following formats:
                                         (assoc-ref %build-inputs "file")
                                         "/lib"))
                     (python-path     (getenv "GUIX_PYTHONPATH")))
-               (wrap-program (string-append out "/bin/cozy")
+               (wrap-program (string-append out "/bin/cozy") inputs
                  `("LD_LIBRARY_PATH" ":" prefix (,libmagic-path))
                  `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))
                  `("GST_PLUGIN_SYSTEM_PATH" ":" prefix (,gst-plugin-path))
diff --git a/gnu/packages/education.scm b/gnu/packages/education.scm
index 2118ebbf6e..8b87bb46ef 100644
--- a/gnu/packages/education.scm
+++ b/gnu/packages/education.scm
@@ -166,6 +166,7 @@ of categories with some of the activities available in that category.
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/gcompris-qt")
+                 inputs
                  `("QT_PLUGIN_PATH" ":" prefix
                    ,(map (lambda (label)
                            (string-append (assoc-ref inputs label)
@@ -783,7 +784,7 @@ adjust the level of difficulty.")
                ;; wrapped to avoid declaring Python libraries as propagated
                ;; inputs.
                (for-each (lambda (program)
-                           (wrap-program program
+                           (wrap-program program inputs
                              `("QTWEBENGINEPROCESS_PATH" =
                                (,qtwebengineprocess))
                              `("PATH" prefix (,(string-append
diff --git a/gnu/packages/emacs-xyz.scm b/gnu/packages/emacs-xyz.scm
index c8b31d7456..49879cbd83 100644
--- a/gnu/packages/emacs-xyz.scm
+++ b/gnu/packages/emacs-xyz.scm
@@ -12164,7 +12164,7 @@ highlights quasi-quoted expressions.")
                                            "/bin/espeak")))
                ;; The environment variable DTK_PROGRAM tells emacspeak what
                ;; program to use for speech.
-               (wrap-program emacspeak
+               (wrap-program emacspeak inputs
                  `("DTK_PROGRAM" ":" prefix (,espeak)))
                #t))))
        #:tests? #f))                    ; no check target
@@ -13243,7 +13243,7 @@ variable instead, to remind you of that variable's meaning.")
 		  (string-append "ERT_RUNNER=\"" out
 				 "/share/emacs/site-lisp")))
 	       (install-file "bin/ert-runner" (string-append out "/bin"))
-	       (wrap-program (string-append out "/bin/ert-runner")
+	       (wrap-program (string-append out "/bin/ert-runner") inputs
 		 (list "EMACSLOADPATH" ":" 'prefix
 		       ;; Do not capture the transient source directory in
 		       ;; the wrapper.
@@ -21482,6 +21482,7 @@ asynchronous communications, the RPC response is fairly good.")
                    (("\"perl\"") (string-append "\"" perl "/bin/perl\"")))
                  (chmod (string-append dir "/edbi-bridge.pl") #o555)
                  (wrap-program (string-append dir "/edbi-bridge.pl")
+                   inputs
                    `("PERL5LIB" ":" prefix (,(getenv "PERL5LIB"))))
                  #t))))))
       (synopsis "Database Interface for Emacs Lisp")
diff --git a/gnu/packages/emulators.scm b/gnu/packages/emulators.scm
index 584eb8800d..65068dca44 100644
--- a/gnu/packages/emulators.scm
+++ b/gnu/packages/emulators.scm
@@ -454,7 +454,7 @@ and a game metadata scraper.")
                        "exec " higan-original))))
                  (chmod higan #o555)
                  ;; Second, make sure higan will find icarus in PATH.
-                 (wrap-program higan
+                 (wrap-program higan inputs
                    `("PATH" ":" prefix (,bin)))
                  #t)))))
        #:make-flags
@@ -1220,7 +1220,7 @@ towards a working Mupen64Plus for casual users.")
                     (nestopia (string-append out "/bin/nestopia"))
                     (gtk (assoc-ref inputs "gtk+"))
                     (gtk-share (string-append gtk "/share")))
-               (wrap-program nestopia
+               (wrap-program nestopia inputs
                  `("XDG_DATA_DIRS" ":" prefix (,gtk-share)))))))
        ;; There are no tests.
        #:tests? #f))
@@ -1876,6 +1876,7 @@ emulator.")
              (lambda* (#:key inputs outputs #:allow-other-keys)
                (wrap-program (string-append (assoc-ref outputs "out")
                                             "/bin/pcsxr")
+                 inputs
                  ;; For GtkFileChooserDialog.
                  `("GSETTINGS_SCHEMA_DIR" =
                    (,(string-append (assoc-ref inputs "gtk+")
diff --git a/gnu/packages/engineering.scm b/gnu/packages/engineering.scm
index cbe9d79d78..a1952ada83 100644
--- a/gnu/packages/engineering.scm
+++ b/gnu/packages/engineering.scm
@@ -190,6 +190,7 @@
              (let* ((out (assoc-ref outputs "out"))
                     (qt '("qtbase" "qtsvg")))
                (wrap-program (string-append out "/bin/librecad")
+                 inputs
                  `("QT_PLUGIN_PATH" ":" prefix
                    ,(map (lambda (label)
                            (string-append (assoc-ref inputs label)
@@ -433,7 +434,7 @@ features.")))
              ;; Mesa can find libudev.so.0 through LD_LIBRARY_PATH.
              (let* ((out (assoc-ref outputs "out"))
                     (path (string-append (assoc-ref inputs "udev") "/lib")))
-               (wrap-program (string-append out "/bin/pcb")
+               (wrap-program (string-append out "/bin/pcb") inputs
                  `("LD_LIBRARY_PATH" ":" prefix (,path))))
              #t))
          (add-before 'check 'pre-check
@@ -937,7 +938,7 @@ Emacs).")
                              (package-version python))
                            "/site-packages:"
                            (getenv "GUIX_PYTHONPATH"))))
-               (wrap-program file
+               (wrap-program file inputs
                  `("GUIX_PYTHONPATH" ":" prefix (,path))
                  `("PATH" ":" prefix
                    (,(string-append python "/bin:")))))
@@ -1200,7 +1201,7 @@ the 'showing the effect of'-style of operation.")
                              (package-version python))
                            "/site-packages:"
                            (getenv "GUIX_PYTHONPATH"))))
-               (wrap-program file
+               (wrap-program file inputs
                  `("GUIX_PYTHONPATH" ":" prefix (,path))
                  `("PATH" ":" prefix
                    (,(string-append python "/bin:")))))
@@ -1989,7 +1990,7 @@ parallel computing platforms.  It also supports serial execution.")
              (let ((out (assoc-ref outputs "out")))
                ;; 'gvhdl' invokes the C compiler directly, so hard-code its
                ;; file name.
-               (wrap-program (string-append out "/bin/gvhdl")
+               (wrap-program (string-append out "/bin/gvhdl") inputs
                  `("CPLUS_INCLUDE_PATH" ":" prefix
                    (,(string-append (assoc-ref inputs "gcc-toolchain")
                                     "/include")))
@@ -2002,6 +2003,7 @@ parallel computing platforms.  It also supports serial execution.")
                     ,(string-append (assoc-ref inputs "coreutils")
                                     "/bin"))))
                (wrap-program (string-append out "/bin/freehdl-config")
+                 inputs
                  `("PKG_CONFIG_PATH" ":" prefix (,(string-append out "/lib/pkgconfig")))))
              #t)))))
     (inputs
@@ -2451,9 +2453,10 @@ comments.")))
              (substitute* "src/Main/MainGui.cpp"
                (("_?putenv\\(\"PYTHONPATH=\"\\);") ""))))
          (add-after 'install 'wrap-pythonpath
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/FreeCAD")
+                 inputs
                  (list "PYTHONPATH"
                        'prefix (list (getenv "PYTHONPATH"))))))))))
     (home-page "https://www.freecadweb.org/")
diff --git a/gnu/packages/file-systems.scm b/gnu/packages/file-systems.scm
index d970fe7198..acf167e896 100644
--- a/gnu/packages/file-systems.scm
+++ b/gnu/packages/file-systems.scm
@@ -373,7 +373,7 @@ from a mounted file system.")
                (with-directory-excursion (string-append out "/sbin")
                  (rename-file "mount.bcachefs.sh" "mount.bcachefs")
                  ;; WRAP-SCRIPT causes bogus ‘Insufficient arguments’ errors.
-                 (wrap-program "mount.bcachefs"
+                 (wrap-program "mount.bcachefs" inputs
                    `("PATH" ":" prefix
                      ,(cons (string-append out "/sbin")
                             (map (lambda (input)
diff --git a/gnu/packages/finance.scm b/gnu/packages/finance.scm
index f8d15b8856..e9ffabeb10 100644
--- a/gnu/packages/finance.scm
+++ b/gnu/packages/finance.scm
@@ -633,8 +633,9 @@ other machines/servers.  Electrum does not download the Bitcoin blockchain.")
                                (assoc-ref inputs "libsecp256k1")
                                "/lib/libsecp256k1.so.0'")))))
          (add-after 'install 'wrap-qt
-           (lambda* (#:key outputs #:allow-other-keys)
-             (wrap-qt-program (assoc-ref outputs "out") "electron-cash"))))))
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (wrap-qt-program (assoc-ref outputs "out") "electron-cash"
+                              inputs))))))
     (home-page "https://electroncash.org/")
     (synopsis "Bitcoin Cash wallet")
     (description
diff --git a/gnu/packages/fontutils.scm b/gnu/packages/fontutils.scm
index 764baf800d..25fdcf4068 100644
--- a/gnu/packages/fontutils.scm
+++ b/gnu/packages/fontutils.scm
@@ -685,7 +685,7 @@ definitions.")
           (lambda* (#:key inputs outputs #:allow-other-keys)
             (let ((out (assoc-ref outputs "out"))
                   (potrace (string-append (assoc-ref inputs "potrace") "/bin")))
-              (wrap-program (string-append out "/bin/fontforge")
+              (wrap-program (string-append out "/bin/fontforge") inputs
                 ;; Fontforge dynamically opens libraries.
                 `("LD_LIBRARY_PATH" ":" prefix
                   ,(map (lambda (input)
@@ -954,6 +954,7 @@ work well with other GTK+ desktop environments.")
                                              "/lib/perl5/site_perl/"
                                              ,(package-version perl))))
                (wrap-program (string-append out "/bin/pdfoutline")
+                 inputs
                  `("PERL5LIB" ":" prefix (,perllib)))
                #t))))))
     (native-inputs
diff --git a/gnu/packages/freedesktop.scm b/gnu/packages/freedesktop.scm
index 9e491ea6d8..679adfd79e 100644
--- a/gnu/packages/freedesktop.scm
+++ b/gnu/packages/freedesktop.scm
@@ -457,7 +457,7 @@ inappropriate content.")
                                         '("awk" "coreutils" "grep" "inetutils"
                                           "perl-file-mimeinfo" "sed" "xprop"
                                           "xset"))))))
-                   (for-each (cute wrap-program <>
+                   (for-each (cute wrap-program <> inputs
                                    `("PATH" ":" prefix ,path-ext))
                              (find-files "."))))
                #t))))))
@@ -1293,6 +1293,7 @@ Analysis and Reporting Technology) functionality.")
                    (cryptsetup (assoc-ref inputs "cryptsetup"))
                    (parted (assoc-ref inputs "parted")))
                (wrap-program (string-append out "/libexec/udisks2/udisksd")
+                 inputs
                  `("PATH" ":" prefix
                    (,(string-append utils "/bin") ;for 'mount'
                     ;; cryptsetup is required for setting encrypted
@@ -1901,10 +1902,11 @@ applications define in those files.")
        #:phases
        (modify-phases %standard-phases
          (add-after 'install 'wrap-programs
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (for-each (lambda (prog)
                            (wrap-program (string-append out "/bin/" prog)
+                             inputs
                              `("PERL5LIB" ":" prefix
                                (,(string-append (getenv "PERL5LIB") ":" out
                                                 "/lib/perl5/site_perl")))))
@@ -2003,10 +2005,11 @@ Python, that binds to the C library @code{uchardet} to increase performance.")
      `(#:phases
        (modify-phases %standard-phases
          (add-after 'install 'wrap-gi-typelib
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out"))
                    (gi-typelib-path (getenv "GI_TYPELIB_PATH")))
                (wrap-program (string-append out "/bin/udiskie")
+                 inputs
                  `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
              #t)))))
     (home-page "https://github.com/coldfix/udiskie")
diff --git a/gnu/packages/game-development.scm b/gnu/packages/game-development.scm
index 83f41da850..bb1349661e 100644
--- a/gnu/packages/game-development.scm
+++ b/gnu/packages/game-development.scm
@@ -1408,6 +1408,7 @@ if __name__ == \"__main__\":
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (wrap-program (string-append (assoc-ref outputs "out")
                                           "/bin/renpy")
+               inputs
                `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH"))))
              #t)))))
     (inputs
@@ -1712,6 +1713,7 @@ games.")
                  (install-file "godot_server" (string-append headless "/bin")))
                ;; Tell the editor where to find zenity for OS.alert().
                (wrap-program (string-append out "/bin/godot")
+                 inputs
                  `("PATH" ":" prefix (,(string-append zenity "/bin")))))
              #t))
          (add-after 'install 'install-godot-desktop
diff --git a/gnu/packages/games.scm b/gnu/packages/games.scm
index 9b2bbb036b..f7ac99e922 100644
--- a/gnu/packages/games.scm
+++ b/gnu/packages/games.scm
@@ -958,7 +958,7 @@ allows users to brew while offline.")
      `(#:phases
        (modify-phases %standard-phases
          (add-after 'install 'wrap-binary
-           (lambda _
+           (lambda (#:key inputs #:allow-other-keys)
              ;; Set Lua module paths and default MIDI soundfont on startup.
              (let* ((out (assoc-ref %outputs "out"))
                     (fluid (assoc-ref %build-inputs "fluid-3"))
@@ -966,10 +966,11 @@ allows users to brew while offline.")
                     (lua-cpath
                      (map (lambda (lib)
                             (string-append
-                             (assoc-ref %build-inputs (string-append "lua-" lib))
+                             (assoc-ref inputs (string-append "lua-" lib))
                              "/lib/lua/" lua-version "/?.so"))
                           '("filesystem" "lpeg"))))
                (wrap-program (string-append out "/bin/corsix-th")
+                 inputs
                  `("LUA_CPATH" ";" = ,lua-cpath)
                  `("SDL_SOUNDFONTS" ":" suffix
                    (,(string-append fluid "/share/soundfonts/FluidR3Mono_GM.sf3")))))
@@ -4171,10 +4172,11 @@ Battle for Wesnoth}.")))
          (delete 'configure)
          (add-after
           'install 'wrap-gamine
-          (lambda* (#:key outputs #:allow-other-keys)
+          (lambda* (#:key inputs outputs #:allow-other-keys)
             (let ((out             (assoc-ref outputs "out"))
                   (gst-plugin-path (getenv "GST_PLUGIN_SYSTEM_PATH")))
               (wrap-program (string-append out "/bin/gamine")
+                inputs
                 `("GST_PLUGIN_SYSTEM_PATH" ":" prefix (,gst-plugin-path))))
             #t)))))
     (home-page "http://gamine-game.sourceforge.net/")
@@ -5339,7 +5341,7 @@ safety of the Chromium vessel.")
                           (("/usr/local") out))
                         ;; tuxpaint-import uses a bunch of programs from
                         ;; netpbm, so make sure it knows where those are
-                        (wrap-program tpi
+                        (wrap-program tpi inputs
                           `("PATH" ":" prefix
                             (,(string-append net "/bin"))))))))))
     (native-search-paths
@@ -7827,16 +7829,16 @@ quotation from a collection of quotes.")
                     (bin-dedicated (string-append out "/bin/xonotic-dedicated"))
                     (curl (assoc-ref inputs "curl"))
                     (vorbis (assoc-ref inputs "libvorbis")))
-               (wrap-program bin
+               (wrap-program bin inputs
                  `("LD_LIBRARY_PATH" ":" prefix
                    (,(string-append curl "/lib:" vorbis "/lib"))))
-               (wrap-program bin-sdl
+               (wrap-program bin-sdl inputs
                  `("LD_LIBRARY_PATH" ":" prefix
                    (,(string-append curl "/lib:" vorbis "/lib"))))
-               (wrap-program bin-glx
+               (wrap-program bin-glx inputs
                  `("LD_LIBRARY_PATH" ":" prefix
                    (,(string-append curl "/lib:" vorbis "/lib"))))
-               (wrap-program bin-dedicated
+               (wrap-program bin-dedicated inputs
                  `("LD_LIBRARY_PATH" ":" prefix
                    (,(string-append curl "/lib:" vorbis "/lib"))))
                #t))))))
@@ -8094,11 +8096,12 @@ when packaged in Blorb container files or optionally from individual files.")
                     '("16" "32" "48" "64"))))
                #t))
            (add-after 'install 'wrap-perl-libs
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let ((out (assoc-ref outputs "out"))
                      (perl5lib (getenv "PERL5LIB")))
                  (for-each (lambda (prog)
                              (wrap-program (string-append out "/" prog)
+                               inputs
                                `("PERL5LIB" ":" prefix
                                  (,(string-append perl5lib ":" out
                                                   "/lib/perl5/site_perl")))))
@@ -9168,6 +9171,7 @@ and also provides the base for the FlightGear Flight Simulator.")
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/fgfs")
+                 inputs
                  `("QT_PLUGIN_PATH" ":" prefix
                    ,(map (lambda (label)
                            (string-append (assoc-ref inputs label)
@@ -10379,9 +10383,10 @@ This package is part of the KDE games module.")
      `(#:phases
        (modify-phases %standard-phases
          (add-after 'install 'wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/kajongg")
+                 inputs
                  `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (native-inputs
@@ -12081,11 +12086,13 @@ kingdom.")
                                         "/include/SDL2/")))
                #t))
            (add-after 'install 'fix-some-broken-fonts
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let* ((out (assoc-ref outputs "out")))
                  (wrap-program (string-append out "/bin/neverball")
+                   inputs
                    `("LANG" = ("en_US.utf8")))
                  (wrap-program (string-append out "/bin/neverputt")
+                   inputs
                    `("LANG" = ("en_US.utf8"))))
                #t)))))
       (native-inputs
diff --git a/gnu/packages/genealogy.scm b/gnu/packages/genealogy.scm
index 2c3781d361..0221673cab 100644
--- a/gnu/packages/genealogy.scm
+++ b/gnu/packages/genealogy.scm
@@ -100,6 +100,7 @@
                                         #f))))
                                inputs)))
                (wrap-program (string-append out "/bin/gramps")
+                 inputs
                  `("GI_TYPELIB_PATH" ":" prefix ,(filter identity paths))))
              #t))
          (add-after 'wrap 'glib-or-gtk-wrap
diff --git a/gnu/packages/geo.scm b/gnu/packages/geo.scm
index c4bdb6aca0..49ebe657e2 100644
--- a/gnu/packages/geo.scm
+++ b/gnu/packages/geo.scm
@@ -251,6 +251,7 @@ topology functions.")
                                     (assoc-ref inputs "webkitgtk")
                                     "/lib")))
                (wrap-program (string-append out "/bin/gnome-maps")
+                 inputs
                  `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))
 
                  ;; There seems to be no way to embed the path of
@@ -1699,7 +1700,7 @@ using the dataset of topographical information collected by
                                         (assoc-ref inputs "qtwebengine")
                                         "/lib/qt5/libexec/QtWebEngineProcess")))
                (for-each (lambda (program)
-                           (wrap-program program
+                           (wrap-program program inputs
                              `("QTWEBENGINEPROCESS_PATH" =
                                (,qtwebengineprocess))))
                          (find-files bin ".*")))
@@ -1996,9 +1997,10 @@ track your position right from your laptop.")
            (add-after 'install-links 'python:wrap
              (assoc-ref python:%standard-phases 'wrap))
            (add-after 'python:wrap 'wrap-with-python-interpreter
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let ((out (assoc-ref outputs "out")))
                  (wrap-program (string-append out "/bin/" ,grassxx)
+                   inputs
                    `("GRASS_PYTHON" = (,(which "python3"))))
                  #t))))))
       (synopsis "GRASS Geographic Information System")
@@ -2224,8 +2226,8 @@ growing set of geoscientific methods.")
          (add-after 'install 'wrap-python
            (assoc-ref python:%standard-phases 'wrap))
          (add-after 'wrap-python 'wrap-qt
-           (lambda* (#:key outputs #:allow-other-keys)
-             (wrap-qt-program (assoc-ref outputs "out") "qgis")
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (wrap-qt-program (assoc-ref outputs "out") "qgis" inputs)
              #t))
          (add-after 'wrap-qt 'wrap-gis
            (lambda* (#:key inputs outputs #:allow-other-keys)
@@ -2242,6 +2244,7 @@ growing set of geoscientific methods.")
                     (grass (string-append (assoc-ref inputs "grass")
                                           "/grass" grass-majorminor)))
                (wrap-program (string-append out "/bin/qgis")
+                 inputs
                  ;;`("PATH" ":" prefix (,saga))
                  `("QGIS_PREFIX_PATH" = (,out))
                  `("GISBASE" = (,grass))))
diff --git a/gnu/packages/gettext.scm b/gnu/packages/gettext.scm
index 9a3a24d89b..aab1204b1a 100644
--- a/gnu/packages/gettext.scm
+++ b/gnu/packages/gettext.scm
@@ -247,7 +247,7 @@ from Markdown files.")
                    (path (string-append out "/lib/perl5/site_perl:"
                                         Pod::Parser "/lib/perl5/site_perl")))
               (for-each (lambda (file)
-                          (wrap-program file
+                          (wrap-program file inputs
                             `("PERL5LIB" ":" prefix (,path))))
                         (find-files bin "\\.*$"))
               #t)))
diff --git a/gnu/packages/glib.scm b/gnu/packages/glib.scm
index b288528c8a..543c899ec0 100644
--- a/gnu/packages/glib.scm
+++ b/gnu/packages/glib.scm
@@ -513,10 +513,10 @@ The intltool collection can be used to do these things:
      '(#:phases
        (modify-phases %standard-phases
          (add-after 'install 'wrap-program
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/itstool")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (home-page "http://www.itstool.org")
diff --git a/gnu/packages/gnome-xyz.scm b/gnu/packages/gnome-xyz.scm
index af920c501d..ab33c0fb56 100644
--- a/gnu/packages/gnome-xyz.scm
+++ b/gnu/packages/gnome-xyz.scm
@@ -420,6 +420,7 @@ faster window switching.")
                                     "/gsconnect@andyholmes.github.io/service"))
                     (gi-typelib-path (getenv "GI_TYPELIB_PATH")))
                (wrap-program (string-append service-dir "/daemon.js")
+                 inputs
                  `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path)))
                #t))))))
     (inputs
diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index f393e768af..7ca1fc177f 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -883,6 +883,7 @@ tomorrow, the rest of the week and for special occasions.")
              (let*
                  ((out (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/gnome-photos")
+                 inputs
                  `("GRL_PLUGIN_PATH" = (,(getenv "GRL_PLUGIN_PATH")))))
              #t)))))
     (native-inputs
@@ -952,6 +953,7 @@ cloud integration is offered through GNOME Online Accounts.")
                                           (package-version python))
                                         "/site-packages")))
                (wrap-program (string-append out "/bin/gnome-music")
+                 inputs
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH")))
                  `("GST_PLUGIN_SYSTEM_PATH" = (,(getenv "GST_PLUGIN_SYSTEM_PATH")))
                  `("GRL_PLUGIN_PATH" = (,(getenv "GRL_PLUGIN_PATH")))
@@ -1553,12 +1555,12 @@ sharing to the masses.")
        #:phases
        (modify-phases %standard-phases
          (add-after 'glib-or-gtk-wrap 'wrap-typelib
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/sushi")))
                ;; Put existing typelibs before sushi's deps, so as to correctly
                ;; infer gdk-pixbuf
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GI_TYPELIB_PATH" suffix (,(getenv "GI_TYPELIB_PATH"))))
                #t))))))
     (native-inputs
@@ -2021,11 +2023,12 @@ to other formats.")
      `(#:glib-or-gtk? #t
        #:phases (modify-phases %standard-phases
                   (add-after 'install 'wrap
-                    (lambda* (#:key outputs #:allow-other-keys)
+                    (lambda* (#:key inputs outputs #:allow-other-keys)
                       ;; GNOME Characters needs Typelib files from GTK and
                       ;; gnome-desktop.
                       (wrap-program (string-append (assoc-ref outputs "out")
                                                    "/bin/gnome-characters")
+                        inputs
                         `("GI_TYPELIB_PATH" ":" prefix
                           (,(getenv "GI_TYPELIB_PATH"))))
                       #t)))))
@@ -2731,7 +2734,7 @@ and how they are displayed (View).")
        #:phases
        (modify-phases %standard-phases
          (add-after 'glib-or-gtk-wrap 'python-and-gi-wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/gtg"))
                    (pylib (string-append (assoc-ref outputs "out")
@@ -2739,7 +2742,7 @@ and how they are displayed (View).")
                                          ,(version-major+minor
                                            (package-version python))
                                          "/site-packages")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH") ,pylib))
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
                #t))))))
@@ -2790,11 +2793,10 @@ know, from small tasks to large projects.")
        (modify-phases %standard-phases
          (add-after 'install 'set-load-paths
            ;; Tell 'icon-name-mapping' where XML::Simple is.
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out  (assoc-ref outputs "out"))
                     (prog (string-append out "/libexec/icon-name-mapping")))
-               (wrap-program
-                   prog
+               (wrap-program prog inputs
                  `("PERL5LIB" = ,(list (getenv "PERL5LIB")))))
              #t)))))
     (home-page "http://tango.freedesktop.org/Standard_Icon_Naming_Specification")
@@ -2945,12 +2947,12 @@ database is translated at Transifex.")
          (add-after 'install 'wrap-for-python
            (@@ (guix build python-build-system) wrap))
          (add-after 'install 'wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out               (assoc-ref outputs "out"))
                    (gi-typelib-path   (getenv "GI_TYPELIB_PATH")))
                (for-each
                 (lambda (program)
-                  (wrap-program program
+                  (wrap-program program inputs
                     `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
                 (map (lambda (name)
                        (string-append out "/bin/" name))
@@ -6261,9 +6263,11 @@ discovery protocols.")
                   (gst-plugin-path (getenv "GST_PLUGIN_SYSTEM_PATH"))
                   (grl-plugin-path (getenv "GRL_PLUGIN_PATH")))
               (wrap-program (string-append out "/bin/totem")
+                inputs
                 `("GST_PLUGIN_SYSTEM_PATH" ":" prefix (,gst-plugin-path))
                 `("GRL_PLUGIN_PATH"        ":" prefix (,grl-plugin-path)))
               (wrap-program (string-append out "/bin/totem-video-thumbnailer")
+                inputs
                 `("GST_PLUGIN_SYSTEM_PATH" ":" prefix (,gst-plugin-path))))
             #t)))))
     (home-page "https://wiki.gnome.org/Apps/Videos")
@@ -6307,6 +6311,7 @@ which can read a large number of file formats.")
                  (grl-plugin-path   (getenv "GRL_PLUGIN_PATH"))
                  (python-path       (getenv "GUIX_PYTHONPATH")))
              (wrap-program (string-append out "/bin/rhythmbox")
+               inputs
                `("GI_TYPELIB_PATH"        ":" prefix (,gi-typelib-path))
                `("GST_PLUGIN_SYSTEM_PATH" ":" prefix (,gst-plugin-path))
                `("GRL_PLUGIN_PATH"        ":" prefix (,grl-plugin-path))
@@ -6389,10 +6394,11 @@ supports playlists, song ratings, and any codecs installed through gstreamer.")
                (("gtk-update-icon-cache") "true"))
              #t))
         (add-after 'install 'wrap-eog
-          (lambda* (#:key outputs #:allow-other-keys)
+          (lambda* (#:key inputs outputs #:allow-other-keys)
             (let ((out               (assoc-ref outputs "out"))
                   (gi-typelib-path   (getenv "GI_TYPELIB_PATH")))
               (wrap-program (string-append out "/bin/eog")
+                inputs
                 `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
             #t)))))
    (propagated-inputs
@@ -6681,6 +6687,7 @@ almost all of them.")
                                 libs)
                            ":")))
                (wrap-program (string-append out "/bin/eolie")
+                 inputs
                  `("LD_LIBRARY_PATH" ":" prefix (,path))
                  `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH")))
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH")))))
@@ -6824,10 +6831,10 @@ principles are simplicity and standards compliance.")
             #t))
          (add-after
           'install 'wrap-program
-          (lambda* (#:key outputs #:allow-other-keys)
+          (lambda* (#:key inputs outputs #:allow-other-keys)
             (let ((prog (string-append (assoc-ref outputs "out")
                                        "/bin/d-feet")))
-              (wrap-program prog
+              (wrap-program prog inputs
                 `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH")))
                 `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
               #t))))))
@@ -7154,6 +7161,7 @@ such as gzip tarballs.")
              (let ((glib (assoc-ref inputs "glib:bin"))
                    (out  (assoc-ref outputs "out")))
                (wrap-program (string-append out "/bin/gnome-session")
+                 inputs
                  `("PATH" ":" prefix (,(string-append glib "/bin"))))
                #t))))
 
@@ -7296,6 +7304,7 @@ javascript engine and the GObject introspection framework.")
                    (gi-typelib-path   (getenv "GI_TYPELIB_PATH"))
                    (python-path       (getenv "GUIX_PYTHONPATH")))
                (wrap-program (string-append out "/bin/gedit")
+                 inputs
                  ;; For plugins.
                  `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))
                  `("GUIX_PYTHONPATH" ":" prefix (,python-path))
@@ -7659,13 +7668,13 @@ Evolution (hence the name), but is now used by other packages as well.")
                                 out "/lib/libcaribou.so")))
               #t)))
          (add-after 'install 'wrap-programs
-          (lambda* (#:key outputs #:allow-other-keys)
+          (lambda* (#:key inputs outputs #:allow-other-keys)
             (let* ((out (assoc-ref outputs "out"))
                    (python-path (getenv "GUIX_PYTHONPATH"))
                    (gi-typelib-path (getenv "GI_TYPELIB_PATH")))
               (for-each
                (lambda (prog)
-                 (wrap-program prog
+                 (wrap-program prog inputs
                    `("GUIX_PYTHONPATH"      ":" prefix (,python-path))
                    `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
                (list (string-append out "/bin/caribou-preferences")
@@ -8575,6 +8584,7 @@ properties, screen resolution, and other GNOME parameters.")
                    (gi-typelib-path  (getenv "GI_TYPELIB_PATH"))
                    (python-path      (getenv "GUIX_PYTHONPATH")))
                (wrap-program (string-append out "/bin/gnome-shell")
+                 inputs
                  `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))
                  ;; FIXME: gnome-shell loads these libraries with unqualified
                  ;; names only, so they need to be on LD_LIBRARY_PATH.  The
@@ -8587,6 +8597,7 @@ properties, screen resolution, and other GNOME parameters.")
                (for-each
                 (lambda (prog)
                   (wrap-program (string-append out "/bin/" prog)
+                    inputs
                     `("GUIX_PYTHONPATH"      ":" prefix (,python-path))
                     `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
                 '("gnome-shell-extension-tool" "gnome-shell-perf-tool"))
@@ -9178,6 +9189,7 @@ associations for GNOME.")
                   (gi-typelib-path   (getenv "GI_TYPELIB_PATH")))
               ;; GNOME Weather needs the typelib files of GTK+, Pango etc at runtime.
               (wrap-program (string-append out "/bin/gnome-weather")
+                inputs
                 `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path)))
               #t))))))
    (synopsis "Weather monitoring for GNOME desktop")
@@ -9370,7 +9382,7 @@ specified duration and save it as a GIF encoded animated image file.")
                                          ,(version-major+minor
                                            (package-version python))
                                          "/site-packages")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH") ,pylib))
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
                #t))))))
@@ -9584,6 +9596,7 @@ desktop.  It supports multiple calendars, month, week and year view.")
                             (gi-typelib-path   (getenv "GI_TYPELIB_PATH"))
                             (python-path       (getenv "GUIX_PYTHONPATH")))
                         (wrap-program (string-append out "/bin/gnome-todo")
+                          inputs
                           ;; XXX: gi plugins are broken.
                           ;; See https://bugzilla.gnome.org/show_bug.cgi?id=787212
                           ;; For plugins.
@@ -9689,6 +9702,7 @@ existing databases over the internet.")
              (let ((out               (assoc-ref outputs "out"))
                    (gi-typelib-path   (getenv "GI_TYPELIB_PATH")))
                (wrap-program (string-append out "/bin/gnome-tweaks")
+                 inputs
                  `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
              #t)))))
     (native-inputs
@@ -10182,10 +10196,10 @@ accessibility infrastructure.")
                  (("'xkbcomp'") (format #f "'~a'" xkbcomp))))
              #t))
          (add-after 'install 'wrap-orca
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out  (assoc-ref outputs "out"))
                     (prog (string-append out "/bin/orca")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GI_TYPELIB_PATH" ":" prefix
                    (,(getenv "GI_TYPELIB_PATH")))
                  `("GST_PLUGIN_SYSTEM_PATH" ":" prefix
@@ -10350,10 +10364,11 @@ views can be printed as PDF or PostScript files, or exported to HTML.")
        #:phases
        (modify-phases %standard-phases
          (add-after 'install 'wrap-program
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out               (assoc-ref outputs "out"))
                    (gi-typelib-path   (getenv "GI_TYPELIB_PATH")))
                (wrap-program (string-append out "/bin/lollypop")
+                 inputs
                  `("GI_TYPELIB_PATH" ":" prefix (,gi-typelib-path))))
              #t))
          (add-after 'install 'wrap-python
@@ -10457,6 +10472,7 @@ photo-booth-like software, such as Cheese.")
              (let ((out             (assoc-ref outputs "out"))
                    (gst-plugin-path (getenv "GST_PLUGIN_SYSTEM_PATH")))
                (wrap-program (string-append out "/bin/cheese")
+                 inputs
                  `("GST_PLUGIN_SYSTEM_PATH" ":" prefix (,gst-plugin-path))))
              #t)))))
     (build-system meson-build-system)
@@ -10515,7 +10531,7 @@ apply fancy special effects and lets you share the fun with others.")
        #:phases
        (modify-phases %standard-phases
          (add-after 'glib-or-gtk-wrap 'python-and-gi-wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/gnome-passwordsafe"))
                    (pylib (string-append (assoc-ref outputs "out")
@@ -10523,7 +10539,7 @@ apply fancy special effects and lets you share the fun with others.")
                                          ,(version-major+minor
                                            (package-version python))
                                          "/site-packages")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH") ,pylib))
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
                #t))))))
@@ -10624,6 +10640,7 @@ mp3, Ogg Vorbis and FLAC")
                    (gi-typelib-path   (getenv "GI_TYPELIB_PATH"))
                    (gst-plugin-path   (getenv "GST_PLUGIN_SYSTEM_PATH")))
                (wrap-program (string-append out "/bin/soundconverter")
+                 inputs
                  `("GI_TYPELIB_PATH"        ":" prefix (,gi-typelib-path))
                  `("GST_PLUGIN_SYSTEM_PATH" ":" prefix (,gst-plugin-path))))
              #t)))))
@@ -10948,7 +10965,7 @@ advanced image management tool")
                (("'dbus-python',") ""))
              #t))
          (add-after 'install 'wrap-program
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/terminator"))
                    (pylib (string-append (assoc-ref outputs "out")
@@ -10956,7 +10973,7 @@ advanced image management tool")
                                          ,(version-major+minor
                                            (package-version python))
                                          "/site-packages")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("PYTHONPATH" = (,(getenv "PYTHONPATH") ,pylib))
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
                #t)))
@@ -11098,10 +11115,10 @@ higher level porcelain stuff.")
                (("/bin/bash") (which "bash")))
              #t))
          (add-after 'glib-or-gtk-wrap 'wrap-typelib
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/gitg")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
                #t))))))
     (inputs
@@ -11307,10 +11324,10 @@ environment.")
                (("gtk-update-icon-cache") (which "true")))
              #t))
          (add-after 'glib-or-gtk-wrap 'wrap-typelib
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/polari")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
                #t))))))
     (inputs
@@ -11582,7 +11599,7 @@ and toolbars.")
        #:phases
        (modify-phases %standard-phases
          (add-after 'glib-or-gtk-wrap 'python-and-gi-wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((prog (string-append (assoc-ref outputs "out")
                                         "/bin/setzer"))
                    (pylib (string-append (assoc-ref outputs "out")
@@ -11590,7 +11607,7 @@ and toolbars.")
                                          ,(version-major+minor
                                            (package-version python))
                                          "/site-packages")))
-               (wrap-program prog
+               (wrap-program prog inputs
                  `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH") ,pylib))
                  `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
                #t))))))
@@ -11654,6 +11671,7 @@ GTK+.  It integrates well with the GNOME desktop environment.")
                     (python-wrap
                      `("GUIX_PYTHONPATH" = (,evdev ,pygo))))
                (wrap-program (string-append out "/bin/" "ratbagctl")
+                 inputs
                  python-wrap)
                #t))))))
     (native-inputs
@@ -11734,9 +11752,10 @@ your operating-system definition:
          (add-after 'install 'wrap-python
            (assoc-ref python:%standard-phases 'wrap))
          (add-after 'wrap-python 'wrap
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (wrap-program
-                 (string-append (assoc-ref outputs "out" )"/bin/piper")
+                 (string-append (assoc-ref outputs "out") "/bin/piper")
+               inputs
                `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
              #t)))))
     (home-page "https://github.com/libratbag/piper/")
@@ -11773,13 +11792,14 @@ provided there is a DBus service present:
          (add-after 'install 'wrap-parlatype
            ;; Add gstreamer plugin provided in this package to system's
            ;; plugins.
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (gst-plugin-path (string-append
                                       out "/lib/gstreamer-1.0/"
                                       ":"
                                       (getenv "GST_PLUGIN_SYSTEM_PATH"))))
                (wrap-program (string-append out "/bin/parlatype")
+                 inputs
                  `("GST_PLUGIN_SYSTEM_PATH" ":" = (,gst-plugin-path))))
              #t)))))
     (native-inputs
@@ -12030,10 +12050,10 @@ integrated profiler via Sysprof, debugging support, and more.")
                (("gtk-update-icon-cache") (which "true")))
              #t))
          (add-after 'glib-or-gtk-wrap 'python-and-gi-wrap
-          (lambda* (#:key outputs #:allow-other-keys)
+          (lambda* (#:key inputs outputs #:allow-other-keys)
             (let ((prog (string-append (assoc-ref outputs "out")
                                        "/bin/komikku")))
-              (wrap-program prog
+              (wrap-program prog inputs
                 `("GUIX_PYTHONPATH" = (,(getenv "GUIX_PYTHONPATH")))
                 `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
               #t))))))
@@ -12215,7 +12235,7 @@ world.")
        (modify-phases %standard-phases
          (add-after
           'install 'wrap-program
-          (lambda* (#:key outputs #:allow-other-keys)
+          (lambda* (#:key inputs outputs #:allow-other-keys)
             (let ((prog (string-append (assoc-ref outputs "out")
                                        "/bin/" "ocrfeeder"))
                   (pylib (string-append (assoc-ref outputs "out")
@@ -12223,7 +12243,7 @@ world.")
                                         ,(version-major+minor
                                           (package-version python))
                                         "/site-packages")))
-              (wrap-program prog
+              (wrap-program inputs prog
                 `("PYTHONPATH" = (,(getenv "PYTHONPATH") ,pylib))
                 `("GI_TYPELIB_PATH" = (,(getenv "GI_TYPELIB_PATH"))))
               #t))))))
diff --git a/gnu/packages/gnucash.scm b/gnu/packages/gnucash.scm
index f71e8209fa..27e04ebe10 100644
--- a/gnu/packages/gnucash.scm
+++ b/gnu/packages/gnucash.scm
@@ -175,6 +175,7 @@
              (for-each (lambda (prog)
                          (wrap-program (string-append (assoc-ref outputs "out")
                                                       "/bin/" prog)
+                           inputs
                            `("GNC_DBD_DIR" =
                              (,(string-append
                                 (assoc-ref inputs "libdbi-drivers")
diff --git a/gnu/packages/gnupg.scm b/gnu/packages/gnupg.scm
index e8df4632c5..420d9daeb7 100644
--- a/gnu/packages/gnupg.scm
+++ b/gnu/packages/gnupg.scm
@@ -753,10 +753,10 @@ PGP keysigning parties.")
                   "process_keys.1" "pgpring.1" "keyanalyze.1")))
              #t))
          (add-after 'install 'wrap-programs
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out")))
-               (wrap-program
-                   (string-append out "/bin/caff")
+               (wrap-program (string-append out "/bin/caff")
+                 inputs
                  `("PERL5LIB" ":" prefix (,(getenv "PERL5LIB")))))
              #t)))))
     (synopsis "Collection of scripts for simplifying gnupg key signing")
@@ -922,8 +922,8 @@ passphrase when @code{gpg} is run and needs it.")))
                     (rofi-bin (string-append (assoc-ref inputs "rofi") "/bin")))
                (match (scandir site)
                  (("." ".." version)
-                  (wrap-program
-                      (string-append bin "pinentry-rofi")
+                  (wrap-program (string-append bin "pinentry-rofi")
+                    inputs
                     (list "PATH" ":" 'prefix `(,rofi-bin)))
                   #t)))))
          (add-after 'compress-documentation 'installcheck
@@ -1029,6 +1029,7 @@ however, pgpdump produces more detailed and easier to understand output.")
              (let ((out (assoc-ref outputs "out"))
                    (gnupg (assoc-ref inputs "gnupg")))
                (wrap-program (string-append out "/bin/gpa")
+                 inputs
                  `("PATH" ":" prefix (,(string-append gnupg "/bin"))))
                #t))))))
     (native-inputs
@@ -1130,6 +1131,7 @@ files, to verify signatures, and to manage the private and public keys.")
                     (perllib (string-append out "/lib/perl5/site_perl/"
                                             ,(package-version perl))))
                (wrap-program (string-append out "/bin/parcimonie")
+                 inputs
                  `("PERL5LIB" ":"
                    prefix (,(string-append perllib ":" (getenv "PERL5LIB")))))
                #t))))))
diff --git a/gnu/packages/password-utils.scm b/gnu/packages/password-utils.scm
index 6b1b32b147..e693edeb2f 100644
--- a/gnu/packages/password-utils.scm
+++ b/gnu/packages/password-utils.scm
@@ -683,8 +683,8 @@ key URIs using the standard otpauth:// scheme.")
                (install-file "qtpass.1" man)
                #t)))
          (add-after 'install 'wrap-qt
-           (lambda* (#:key outputs #:allow-other-keys)
-             (wrap-qt-program (assoc-ref outputs "out") "qtpass")
+           (lambda* (#:key inputs outputs #:allow-other-keys)
+             (wrap-qt-program (assoc-ref outputs "out") "qtpass" inputs)
              #t))
          (add-before 'check 'check-setup
            ;; Make Qt render "offscreen", required for tests.
diff --git a/gnu/packages/video.scm b/gnu/packages/video.scm
index 1e90874a1c..3e3f15e097 100644
--- a/gnu/packages/video.scm
+++ b/gnu/packages/video.scm
@@ -4556,9 +4556,9 @@ API.  It includes bindings for Python, Ruby, and other languages.")
                       (setenv "HOME" "/tmp")
                       #t))
                   (add-after 'install 'wrap-program
-                    (lambda* (#:key outputs #:allow-other-keys)
+                    (lambda* (#:key inputs outputs #:allow-other-keys)
                       (let ((out (assoc-ref outputs "out")))
-                        (wrap-qt-program out "openshot-qt"))
+                        (wrap-qt-program out "openshot-qt" inputs))
                       #t)))))
     (home-page "https://www.openshot.org/")
     (synopsis "Video editor")
diff --git a/gnu/packages/web-browsers.scm b/gnu/packages/web-browsers.scm
index cff761a344..9e6bfe6740 100644
--- a/gnu/packages/web-browsers.scm
+++ b/gnu/packages/web-browsers.scm
@@ -280,6 +280,7 @@ features including, tables, builtin image display, bookmarks, SSL and more.")
                     (gtk (assoc-ref inputs "gtk+"))
                     (gtk-share (string-append gtk "/share")))
                (wrap-program (string-append luakit "/bin/luakit")
+                 inputs
                  `("LUA_CPATH" prefix
                    (,(string-append lua5.1-filesystem
                                     "/lib/lua/5.1/?.so;;")))
@@ -443,9 +444,9 @@ access.")
                    "/share/fonts/truetype/NotoColorEmoji")))
                #t))
            (add-after 'install 'wrap-program
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let ((out (assoc-ref outputs "out")))
-                 (wrap-qt-program out "kristall"))
+                 (wrap-qt-program out "kristall" inputs))
                #t)))))
       (native-inputs
        `(("breeze-stylesheet"
@@ -551,7 +552,7 @@ interface.")
                     (qt-process-path (string-append
                                       (assoc-ref inputs "qtwebengine")
                                       "/lib/qt5/libexec/QtWebEngineProcess")))
-               (wrap-program bin
+               (wrap-program bin inputs
                  `("QTWEBENGINEPROCESS_PATH" = (,qt-process-path)))
                #t))))))
     (home-page "https://qutebrowser.org/")
@@ -657,7 +658,7 @@ driven and does not detract you from your daily work.")
                                       (string-append (assoc-ref inputs lib) "/share"))
                                     libs)
                                ":")))
-               (wrap-program bin
+               (wrap-program bin inputs
                  `("GIO_EXTRA_MODULES" prefix
                    (,(string-append glib-networking "/lib/gio/modules")))
                  `("GI_TYPELIB_PATH" prefix (,gi-path))
diff --git a/guix/build/glib-or-gtk-build-system.scm b/guix/build/glib-or-gtk-build-system.scm
index ba680fd1a9..d0cb3cec2e 100644
--- a/guix/build/glib-or-gtk-build-system.scm
+++ b/guix/build/glib-or-gtk-build-system.scm
@@ -164,36 +164,36 @@ add a dependency of that output on GLib and GTK+."
                     #f)))
           (cond
            ((and data-env-var gtk-mod-env-var gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> inputs
                            data-env-var
                            gtk-mod-env-var
                            gio-mod-env-var)
                       bin-list))
            ((and data-env-var gtk-mod-env-var (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> inputs
                            data-env-var
                            gtk-mod-env-var)
                       bin-list))
            ((and data-env-var (not gtk-mod-env-var) gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> inputs
                            data-env-var
                            gio-mod-env-var)
                       bin-list))
            ((and (not data-env-var) gtk-mod-env-var gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> inputs
                            gio-mod-env-var
                            gtk-mod-env-var)
                       bin-list))
            ((and data-env-var (not gtk-mod-env-var) (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> inputs
                            data-env-var)
                       bin-list))
            ((and (not data-env-var) gtk-mod-env-var (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> inputs
                            gtk-mod-env-var)
                       bin-list))
            ((and (not data-env-var) (not gtk-mod-env-var) gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> inputs
                            gio-mod-env-var)
                       bin-list))))))))
 
diff --git a/guix/build/python-build-system.scm b/guix/build/python-build-system.scm
index 8ade1d5911..47fc6fb03a 100644
--- a/guix/build/python-build-system.scm
+++ b/guix/build/python-build-system.scm
@@ -239,7 +239,7 @@ running checks after installing the package."
                   (or (getenv "GUIX_PYTHONPATH") "")))))
     (for-each (lambda (dir)
                 (let ((files (list-of-files dir)))
-                  (for-each (cut wrap-program <> var)
+                  (for-each (cut wrap-program <> inputs var)
                             files)))
               bindirs)))
 
diff --git a/guix/build/qt-build-system.scm b/guix/build/qt-build-system.scm
index f59b0c420f..b01121e2a0 100644
--- a/guix/build/qt-build-system.scm
+++ b/guix/build/qt-build-system.scm
@@ -132,7 +132,7 @@ add a dependency of that output on Qt."
                              (append (list directory)
                                      input-directories))))
           (when (not (null? vars-to-wrap))
-            (for-each (cut apply wrap-program <> vars-to-wrap)
+            (for-each (cut apply wrap-program <> inputs vars-to-wrap)
                       bin-list)))))))
 
   (for-each handle-output outputs)
diff --git a/guix/build/qt-utils.scm b/guix/build/qt-utils.scm
index d2486ee86c..8c661d234d 100644
--- a/guix/build/qt-utils.scm
+++ b/guix/build/qt-utils.scm
@@ -20,7 +20,7 @@
   #:use-module (guix build utils)
   #:export (wrap-qt-program))
 
-(define (wrap-qt-program out program)
+(define (wrap-qt-program out program inputs)
   (define (suffix env-var path)
     (let ((env-val (getenv env-var)))
       (if env-val (string-append env-val ":" path) path)))
@@ -34,6 +34,7 @@
         (xdg-config-path (suffix "XDG_CONFIG_DIRS"
                                  (string-append out "/etc/xdg"))))
     (wrap-program (string-append out "/bin/" program)
+      inputs
       `("QML2_IMPORT_PATH" = (,qml-path))
       `("QT_PLUGIN_PATH" = (,plugin-path))
       `("XDG_DATA_DIRS" = (,xdg-data-path))
diff --git a/guix/build/rakudo-build-system.scm b/guix/build/rakudo-build-system.scm
index dbdeb1ccd2..23d9dc6ffd 100644
--- a/guix/build/rakudo-build-system.scm
+++ b/guix/build/rakudo-build-system.scm
@@ -116,7 +116,7 @@
                         (or (getenv "PERL6LIB") "") #\,)))))
     (for-each (lambda (dir)
                 (let ((files (list-of-files dir)))
-                  (for-each (cut wrap-program <> var)
+                  (for-each (cut wrap-program <> inputs var)
                             files)))
               bindirs)
     #t))
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index b725237ce6..581e09a24f 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -1242,7 +1242,7 @@ known as `nuke-refs' in Nixpkgs."
          (and (string-prefix? "." base)
               (string-suffix? "-real" base)))))
 
-(define* (wrap-program prog #:rest vars)
+(define* (wrap-program prog inputs #:rest vars)
   "Make a wrapper for PROG.  VARS should look like this:
 
   '(VARIABLE DELIMITER POSITION LIST-OF-DIRECTORIES)
@@ -1332,7 +1332,7 @@ with definitions for VARS."
           (lambda (port)
             (format port
                     "#!~a~%~a~%exec -a \"$0\" \"~a\" \"$@\"~%"
-                    (which "bash")
+                    (which "bash" inputs)
                     (string-join (map export-variable vars) "\n")
                     (canonicalize-path wrapped-file))))
 
diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index a5dfab576d..15732a36a9 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -97,7 +97,8 @@
   "hello world\n"
   (call-with-temporary-directory
    (lambda (directory)
-     (let ((bash (search-bootstrap-binary "bash" (%current-system)))
+     (let ((bash-source (search-bootstrap-binary "bash" (%current-system)))
+           (bash (string-append directory "/bash/bin/bash"))
            (foo  (string-append directory "/foo")))
 
        (call-with-output-file foo
@@ -107,9 +108,19 @@
                    bash)))
        (chmod foo #o777)
 
-       (with-environment-variable "PATH" (dirname bash)
-         (wrap-program foo `("GUIX_FOO" prefix ("hello")))
-         (wrap-program foo `("GUIX_BAR" prefix ("world")))
+       ;; wrap-program uses (which "bash" inputs) to locate the
+       ;; "bash" interpreter.  As the bootstrap bash is located
+       ;; in a directory named [...]/SYSTEM/bash, 'which' cannot
+       ;; find the bootstrap bash, as 'which' expects binaries
+       ;; to be located in a [...]/bin or [...]/sbin directory.
+       ;;
+       ;; Help 'which' by copying bash to a [...]/bin directory.
+       (mkdir-p (dirname bash))
+       (copy-file bash-source bash)
+
+       (let ((inputs `(("bash" . ,(dirname (dirname bash))))))
+         (wrap-program foo inputs `("GUIX_FOO" prefix ("hello")))
+         (wrap-program foo inputs `("GUIX_BAR" prefix ("world")))
 
          ;; The bootstrap Bash is linked against an old libc and would abort
          ;; with an assertion failure when trying to load incompatible locale
-- 
2.31.1


[-- Attachment #1.8: 0007-doc-Document-wrap-program.patch --]
[-- Type: text/x-patch, Size: 2209 bytes --]

From cdd45bc0aef8b6cb60d351a8fded18700804e8db Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 19 Apr 2021 19:54:53 +0200
Subject: [PATCH 7/7] doc: Document 'wrap-program'.

* doc/guix.texi (Wrapping Code)[wrap-program]: Copy docstring from
  guix/build/utils.scm and use Texinfo markup.
---
 doc/guix.texi | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index a2ff13fe0f..6235ae9bf7 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8703,7 +8703,42 @@ Here is an example using the @code{which} procedure in a build phase:
 This section documents procedures that create ‘wrappers’ around existing
 binaries, that e.g. set environment variables required during execution.
 
-@c TODO document wrap-program
+@deffn {Scheme Procedure} wrap-program @var{prog} @var{inputs} @var{vars}
+Make a wrapper for @var{prog}.  @var{vars} should look like this:
+
+@lisp
+  '(VARIABLE DELIMITER POSITION LIST-OF-DIRECTORIES)
+@end lisp
+
+where @var{delimiter} is optional.  @samp{:} will be used if @var{delimiter}
+is not given.
+
+For example, this command:
+
+@lisp
+  (wrap-program "foo"
+                '("PATH" ":" = ("/gnu/.../bar/bin"))
+                '("CERT_PATH" suffix ("/gnu/.../baz/certs"
+                                        "/qux/certs")))
+@end lisp
+
+will copy @file{foo} to @file{.foo-real} and create the file @file{foo} with
+the following contents:
+
+@example
+  #!location/of/bin/bash
+  export PATH="/gnu/.../bar/bin"
+  export CERT_PATH="$CERT_PATH$@{CERT_PATH:+:@}/gnu/.../baz/certs:/qux/certs"
+  exec -a $0 location/of/.foo-real "$@@"
+@end example
+
+This is useful for scripts that expect particular programs to be in @env{PATH},
+for programs that expect particular shared libraries to be in
+@env{LD_LIBRARY_PATH}, or modules in @env{GUILE_LOAD_PATH}, etc.
+
+If @var{prog} has previously been wrapped by @code{wrap-program} the wrapper is
+extended with definitions for @var{vars}.
+@end deffn
 
 @deffn {Scheme Procedure} wrap-script @var{prog} @var{inputs} @var{vars}
 Wrap the script @var{prog} such that @var{vars} are set first.  The format
-- 
2.31.1


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling
  2021-04-19 19:04 ` [bug#47869] [PATCH v2 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
@ 2021-05-18 20:51   ` Ludovic Courtès
  2021-05-18 21:25     ` Maxime Devos
  2021-06-01 19:53   ` [bug#47869] [PATCH v3 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
  2021-06-02  7:56   ` [bug#47869] [PATCH v4 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
  2 siblings, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2021-05-18 20:51 UTC (permalink / raw)
  To: Maxime Devos; +Cc: 47869

Hi Maxime,

Maxime Devos <maximedevos@telenet.be> skribis:

> This is version two of the patch series, removing a 'pk' that
> I added for debugging, and also fixing 'wrap-script' and 'wrap-program'.
> To fix 'wrap-script' and 'wrap-program', I added a required 'inputs' argument.
> All callers have been adjusted to pass it.
>
> Perhaps 'patch-shebang' can be fixed and needs to be fixed, but I don't
> have investigated that closely yet.  ('patch-shebangs' (with a #\s) works
> properly IIUC).

Thanks for this long patch series, and sorry for the equally long delay!

Since we don’t get to change those interfaces very often, I’m going to
nitpick somewhat because I think we’d rather get them right.

> From 42e7cf4ca6e4d6e1cd31c2807f608275a5ca759a Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Sun, 18 Apr 2021 12:45:13 +0200
> Subject: [PATCH 1/7] build: Add argument to which for specifying where to
>  search.
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> The procedure ‘which’ from (guix build utils)
> is used for two different purposes:
>
>  1. for finding the absolute file name of a binary
>     that needs to run during the build process
>
>  2. for finding the absolute file name of a binary,
>     for the target system (as in --target=TARGET),
>     e.g. for substituting sh->/gnu/store/.../bin/sh,
>     python->/gnu/store/.../bin/python.

But note that only #1 is the intended purpose.

> When compiling natively (SYSTEM=TARGET modulo nix/autotools differences),
> this is perfectly fine.

Rather “target=#f” in Guix parlance

[...]

> +(define* (which program #:optional inputs)
> +  "Return the complete file name for PROGRAM as found in $PATH, or #false if
> +PROGRAM could not be found.  If INPUTS is not #false, instead look in the
> +/bin and /sbin subdirectories of INPUTS.  INPUTS is an alist; its keys
> +are ignored."

I find that this leads to a weird interface; ‘which’ is intended to be
like the same-named shell command, and the notion of “input alists”
seems out of place to me.

I was thinking we could make it:

--8<---------------cut here---------------start------------->8---
(define* (which program #:optional
                (path (search-path-as-string->list (getenv "PATH"))))
  "Return the complete file name for PROGRAM as found in $PATH, or #f if
PROGRAM could not be found."
  (search-path path program))
--8<---------------cut here---------------end--------------->8---

… but that doesn’t buy us much.

I think what we need is to do is find and fix misuses of ‘which’.

WDYT?


[...]

> +Here is an example using the @code{which} procedure in a build phase:
> +
> +@lisp
> +(lambda* (#:key outputs inputs #:allow-other-keys)
> +  (let ((growpart (string-append (assoc-ref outputs "out")
> +                                          "/bin/growpart")))
> +     (wrap-program growpart
> +                   `("PATH" ":" prefix (,(dirname (which "sfdisk" inputs))
> +                                        ,(dirname (which "readlink" inputs)))))))

That looks weird to me.  The “correct” way we do it right now is like
this:

        (lambda* (#:key outputs inputs #:allow-other-keys)
          (let ((out (assoc-ref outputs "out"))
                (curl (assoc-ref inputs "curl")))
            (wrap-program (string-append out "/bin/akku")
              `("LD_LIBRARY_PATH" ":" prefix (,(string-append curl "/lib"))))
            #t))

Here, when cross-compiling, (assoc-ref inputs "curl") returns the target
cURL.

> From e78d2d8651d5f56afa7d57be78c5cccccebb117a Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Sun, 18 Apr 2021 20:44:28 +0200
> Subject: [PATCH 3/7] build: utils: Make inputs of 'wrap-script' explicit.
>
> Previously, 'wrap-script' used (which "guile") to determine where to locate
> the guile interpreter.  But this is incorrect when cross-compiling.  When
> cross-compiling, this would locate the (native) guile interpreter that is
> in the PATH, while a guile interpreter for the target is required.
>
> Remove the optional #:guile argument which is only used in tests and replace
> it with a required 'inputs' argument and adjust all callers.  Write a new
> test verifying a guile for the target is located, instead of a native guile.

I think the #:guile argument was a fine interface: clear and
to-the-point.  The problem IMO is just that it’s not use where it
should.  :-)

[...]

> --- a/gnu/packages/audio.scm
> +++ b/gnu/packages/audio.scm
> @@ -4712,9 +4712,9 @@ as is the case with audio plugins.")
>                 (chmod (string-append out "/share/carla/carla") #o555)
>                 #t)))
>           (add-after 'install 'wrap-executables
> -           (lambda* (#:key outputs #:allow-other-keys)
> +           (lambda* (#:key inputs outputs #:allow-other-keys)
>               (let ((out (assoc-ref outputs "out")))
> -               (wrap-script (string-append out "/bin/carla")
> +               (wrap-script (string-append out "/bin/carla") inputs
>                              `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))

This would become:

  (wrap-script (string-append out "/bin/carla")
               `(…)
               #:guile (assoc-ref inputs "guile"))

WDYT?

> From 8b843f0dd8803120718747b480983bd5888b1617 Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Mon, 19 Apr 2021 16:56:00 +0200
> Subject: [PATCH 6/7] build: utils: wrap-program: look up bash in inputs, not
>  in PATH
>
> 'wrap-program' is almost always used for creating wrappers for the
> target system.  It is only rarely (once) used for creating wrappers for
> the native system.  However, 'wrap-program' always creates wrappers for
> the native system and provides no option for creating wrappers for the
> target system instead.

[...]

> -                 (wrap-program
> -                     (string-append libexec "/dhclient-script")
> +                 (wrap-program (string-append libexec "/dhclient-script")
> +                   inputs
>                     `("PATH" ":" prefix
>                       ,(map (lambda (dir)
>                               (string-append dir "/bin:"

I’m also skeptical here; ‘wrap-program’ needs to know the file name of
‘sh’ and instead we’re passing it the full input list.

I would instead add #:bash (or #:sh?).  The downside is that it’d be a
bit more verbose, but in terms of interfaces, I’d find it clearer:

  (wrap-program (string-append libexec "/dhclient-script")
    `("PATH" …)
    #:sh (string-append (assoc-ref inputs "bash") "/bin/sh"))

We could introduce a helper procedure to replace (string-append …) with:

  (search-input-file inputs "/bin/sh")

where:

  (define (search-input-file inputs file)
    (any (match-lambda
           ((label . directory)
            (let ((file (string-append directory "/" file)))
              (and (file-exists? file) file))))
         inputs))

WDYT?

> +           (wrap-program (string-append out "/bin/screenfetch")
> +             %build-inputs

As a rule of thumb we should refer to #:inputs and #:outputs instead of
the global variables ‘%build-inputs’ etc.

> From cdd45bc0aef8b6cb60d351a8fded18700804e8db Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Mon, 19 Apr 2021 19:54:53 +0200
> Subject: [PATCH 7/7] doc: Document 'wrap-program'.
>
> * doc/guix.texi (Wrapping Code)[wrap-program]: Copy docstring from
>   guix/build/utils.scm and use Texinfo markup.

Neat!

>  doc/guix.texi | 37 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/doc/guix.texi b/doc/guix.texi
> index a2ff13fe0f..6235ae9bf7 100644
> --- a/doc/guix.texi
> +++ b/doc/guix.texi
> @@ -8703,7 +8703,42 @@ Here is an example using the @code{which} procedure in a build phase:
>  This section documents procedures that create ‘wrappers’ around existing
>  binaries, that e.g. set environment variables required during execution.
>  
> -@c TODO document wrap-program
> +@deffn {Scheme Procedure} wrap-program @var{prog} @var{inputs} @var{vars}
> +Make a wrapper for @var{prog}.  @var{vars} should look like this:
> +
> +@lisp
> +  '(VARIABLE DELIMITER POSITION LIST-OF-DIRECTORIES)
   ^
You can remove indentation and use @var instead of capital letters.

> +@lisp
> +  (wrap-program "foo"
> +                '("PATH" ":" = ("/gnu/.../bar/bin"))
> +                '("CERT_PATH" suffix ("/gnu/.../baz/certs"
> +                                        "/qux/certs")))
   ^^
You can remove indentation here too.

> +@end lisp
> +
> +will copy @file{foo} to @file{.foo-real} and create the file @file{foo} with
> +the following contents:
> +
> +@example
> +  #!location/of/bin/bash
> +  export PATH="/gnu/.../bar/bin"
> +  export CERT_PATH="$CERT_PATH$@{CERT_PATH:+:@}/gnu/.../baz/certs:/qux/certs"
> +  exec -a $0 location/of/.foo-real "$@@"

… and here.

This one can even go to master.

Thanks!

Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling
  2021-05-18 20:51   ` [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès
@ 2021-05-18 21:25     ` Maxime Devos
  2021-05-29 14:50       ` Ludovic Courtès
  0 siblings, 1 reply; 9+ messages in thread
From: Maxime Devos @ 2021-05-18 21:25 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 47869

[-- Attachment #1: Type: text/plain, Size: 10602 bytes --]

Ludovic Courtès schreef op di 18-05-2021 om 22:51 [+0200]:
> Hi Maxime,
> 
> Maxime Devos <maximedevos@telenet.be> skribis:
> 
> > This is version two of the patch series, removing a 'pk' that
> > I added for debugging, and also fixing 'wrap-script' and 'wrap-program'.
> > To fix 'wrap-script' and 'wrap-program', I added a required 'inputs' argument.
> > All callers have been adjusted to pass it.
> > 
> > Perhaps 'patch-shebang' can be fixed and needs to be fixed, but I don't
> > have investigated that closely yet.  ('patch-shebangs' (with a #\s) works
> > properly IIUC).
> 
> Thanks for this long patch series, and sorry for the equally long delay!
> 
> Since we don’t get to change those interfaces very often, I’m going to
> nitpick somewhat because I think we’d rather get them right.
> 
> > From 42e7cf4ca6e4d6e1cd31c2807f608275a5ca759a Mon Sep 17 00:00:00 2001
> > From: Maxime Devos <maximedevos@telenet.be>
> > Date: Sun, 18 Apr 2021 12:45:13 +0200
> > Subject: [PATCH 1/7] build: Add argument to which for specifying where to
> >  search.
> > MIME-Version: 1.0
> > Content-Type: text/plain; charset=UTF-8
> > Content-Transfer-Encoding: 8bit
> > 
> > The procedure ‘which’ from (guix build utils)
> > is used for two different purposes:
> > 
> >  1. for finding the absolute file name of a binary
> >     that needs to run during the build process
> > 
> >  2. for finding the absolute file name of a binary,
> >     for the target system (as in --target=TARGET),
> >     e.g. for substituting sh->/gnu/store/.../bin/sh,
> >     python->/gnu/store/.../bin/python.
> 
> But note that only #1 is the intended purpose.

It is? Then it seems the first patch can be dropped
and replaced with something else, as you mentioned below.

> > When compiling natively (SYSTEM=TARGET modulo nix/autotools differences),
> > this is perfectly fine.
> 
> Rather “target=#f” in Guix parlance

Yes, correct.

> [...]
> 
> > +(define* (which program #:optional inputs)
> > +  "Return the complete file name for PROGRAM as found in $PATH, or #false if
> > +PROGRAM could not be found.  If INPUTS is not #false, instead look in the
> > +/bin and /sbin subdirectories of INPUTS.  INPUTS is an alist; its keys
> > +are ignored."
> 
> I find that this leads to a weird interface; ‘which’ is intended to be
> like the same-named shell command, and the notion of “input alists”
> seems out of place to me.
>
> I was thinking we could make it:
> 
> --8<---------------cut here---------------start------------->8---
> (define* (which program #:optional
>                 (path (search-path-as-string->list (getenv "PATH"))))
>   "Return the complete file name for PROGRAM as found in $PATH, or #f if
> PROGRAM could not be found."
>   (search-path path program))
> --8<---------------cut here---------------end--------------->8---
> 
> … but that doesn’t buy us much.
> 
> I think what we need is to do is find and fix misuses of ‘which’.
> 
> WDYT?

The current correct way is
 (string-append (assoc-ref inputs "the-input") "/bin/the-binary")
which can easily lead to long lines. Ideally, there would be a shorter
way to do this, such as ... the weird
interface above.
Or the "search-input-file" from below.

> 
> [...]
> 
> > +Here is an example using the @code{which} procedure in a build phase:
> > +
> > +@lisp
> > +(lambda* (#:key outputs inputs #:allow-other-keys)
> > +  (let ((growpart (string-append (assoc-ref outputs "out")
> > +                                          "/bin/growpart")))
> > +     (wrap-program growpart
> > +                   `("PATH" ":" prefix (,(dirname (which "sfdisk" inputs))
> > +                                        ,(dirname (which "readlink" inputs)))))))
> 
> That looks weird to me.

The "dirname" & "which" look weird to me to! I grabbed that from
some package definition. I guess a different example is needed.

> The “correct” way we do it right now is like
> this:
> 
>         (lambda* (#:key outputs inputs #:allow-other-keys)
>           (let ((out (assoc-ref outputs "out"))
>                 (curl (assoc-ref inputs "curl")))
>             (wrap-program (string-append out "/bin/akku")
>               `("LD_LIBRARY_PATH" ":" prefix (,(string-append curl "/lib"))))
>             #t))
> 
> Here, when cross-compiling, (assoc-ref inputs "curl") returns the target
> cURL.

This is something that can be fixed on 'core-updates', right?
At least when fixing the package definitions doesn't cause to
many rebuilds.

> > From e78d2d8651d5f56afa7d57be78c5cccccebb117a Mon Sep 17 00:00:00 2001
> > From: Maxime Devos <maximedevos@telenet.be>
> > Date: Sun, 18 Apr 2021 20:44:28 +0200
> > Subject: [PATCH 3/7] build: utils: Make inputs of 'wrap-script' explicit.
> > 
> > Previously, 'wrap-script' used (which "guile") to determine where to locate
> > the guile interpreter.  But this is incorrect when cross-compiling.  When
> > cross-compiling, this would locate the (native) guile interpreter that is
> > in the PATH, while a guile interpreter for the target is required.
> > 
> > Remove the optional #:guile argument which is only used in tests and replace
> > it with a required 'inputs' argument and adjust all callers.  Write a new
> > test verifying a guile for the target is located, instead of a native guile.
> 
> I think the #:guile argument was a fine interface: clear and
> to-the-point.  The problem IMO is just that it’s not use where it
> should.  :-)

It should be used practically everywhere, no? So making it optional doesn't
make much sense to me when we want to support cross-compilation.

> 
> [...]
> 
> > --- a/gnu/packages/audio.scm
> > +++ b/gnu/packages/audio.scm
> > @@ -4712,9 +4712,9 @@ as is the case with audio plugins.")
> >                 (chmod (string-append out "/share/carla/carla") #o555)
> >                 #t)))
> >           (add-after 'install 'wrap-executables
> > -           (lambda* (#:key outputs #:allow-other-keys)
> > +           (lambda* (#:key inputs outputs #:allow-other-keys)
> >               (let ((out (assoc-ref outputs "out")))
> > -               (wrap-script (string-append out "/bin/carla")
> > +               (wrap-script (string-append out "/bin/carla") inputs
> >                              `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
> 
> This would become:
> 
>   (wrap-script (string-append out "/bin/carla")
>                `(…)
>                #:guile (assoc-ref inputs "guile"))
>
> WDYT?

Ok, this looks a good interface to me, though I think
'wrap-script' will need to be modified. IIRC, #:guile
must be the full file name of the guile binary and not
simply /gnu/store/[...]-guile-$VERSION.

> > From 8b843f0dd8803120718747b480983bd5888b1617 Mon Sep 17 00:00:00 2001
> > From: Maxime Devos <maximedevos@telenet.be>
> > Date: Mon, 19 Apr 2021 16:56:00 +0200
> > Subject: [PATCH 6/7] build: utils: wrap-program: look up bash in inputs, not
> >  in PATH
> > 
> > 'wrap-program' is almost always used for creating wrappers for the
> > target system.  It is only rarely (once) used for creating wrappers for
> > the native system.  However, 'wrap-program' always creates wrappers for
> > the native system and provides no option for creating wrappers for the
> > target system instead.
> 
> [...]
> 
> > -                 (wrap-program
> > -                     (string-append libexec "/dhclient-script")
> > +                 (wrap-program (string-append libexec "/dhclient-script")
> > +                   inputs
> >                     `("PATH" ":" prefix
> >                       ,(map (lambda (dir)
> >                               (string-append dir "/bin:"
> 
> I’m also skeptical here; ‘wrap-program’ needs to know the file name of
> ‘sh’ and instead we’re passing it the full input list.
> 
> I would instead add #:bash (or #:sh?).  The downside is that it’d be a
> bit more verbose, but in terms of interfaces, I’d find it clearer:
> 
>   (wrap-program (string-append libexec "/dhclient-script")
>     `("PATH" …)
>     #:sh (string-append (assoc-ref inputs "bash") "/bin/sh"))

LGTM, though rather verbose.

> We could introduce a helper procedure to replace (string-append …) with:
> 
>   (search-input-file inputs "/bin/sh")
> where:
> 
>   (define (search-input-file inputs file)
>     (any (match-lambda
>            ((label . directory)
>             (let ((file (string-append directory "/" file)))
>               (and (file-exists? file) file))))
>          inputs))
> 
> WDYT?

That should help with the verbosity. The previous code becomes

  (wrap-program (string-append libexec "/dhclient-script")
     `("PATH" …)
     #:sh (search-input-file inputs "bin/sh"))

which isn't overly verbose.

This procedure 'search-input-file' would return #f if the input
was not found, right? I would rather it raises an exception instead.
There have been some bugs where "#f" was silently written into some file,
which is unlikely to work well.

For the few cases were the input binary is truly optional,
we can define a 'search-optional-input-file' procedure.

> 
> 
> > +           (wrap-program (string-append out "/bin/screenfetch")
> > +             %build-inputs
> 
> As a rule of thumb we should refer to #:inputs and #:outputs instead of
> the global variables ‘%build-inputs’ etc.

Agreed, that's what I thought as well, but that seems like a separate
(stylistic) bug to fix.  IIRC, the surrounding code used %build-inputs
instead of #:inputs.

> [...]
> > diff --git a/doc/guix.texi b/doc/guix.texi
> > index a2ff13fe0f..6235ae9bf7 100644
> > --- a/doc/guix.texi
> > +++ b/doc/guix.texi
> > @@ -8703,7 +8703,42 @@ Here is an example using the @code{which} procedure in a build phase:
> >  This section documents procedures that create ‘wrappers’ around existing
> >  binaries, that e.g. set environment variables required during execution.
> >  
> > -@c TODO document wrap-program
> > +@deffn {Scheme Procedure} wrap-program @var{prog} @var{inputs} @var{vars}
> > +Make a wrapper for @var{prog}.  @var{vars} should look like this:
> > +
> > +@lisp
> > +  '(VARIABLE DELIMITER POSITION LIST-OF-DIRECTORIES)
>    ^
> You can remove indentation and use @var instead of capital letters.

@var can be used inside @lisp? Didn't know that.

> [...]
>
> This one can even go to master.

Yep.

Greetings,
Maxime.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling
  2021-05-18 21:25     ` Maxime Devos
@ 2021-05-29 14:50       ` Ludovic Courtès
  0 siblings, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2021-05-29 14:50 UTC (permalink / raw)
  To: Maxime Devos; +Cc: 47869

Hi Maxime,

Maxime Devos <maximedevos@telenet.be> skribis:

> Ludovic Courtès schreef op di 18-05-2021 om 22:51 [+0200]:

[...]

>> The “correct” way we do it right now is like
>> this:
>> 
>>         (lambda* (#:key outputs inputs #:allow-other-keys)
>>           (let ((out (assoc-ref outputs "out"))
>>                 (curl (assoc-ref inputs "curl")))
>>             (wrap-program (string-append out "/bin/akku")
>>               `("LD_LIBRARY_PATH" ":" prefix (,(string-append curl "/lib"))))
>>             #t))
>> 
>> Here, when cross-compiling, (assoc-ref inputs "curl") returns the target
>> cURL.
>
> This is something that can be fixed on 'core-updates', right?

Yes, it’s a good time for this!  For now, we can even afford world
rebuilds on ‘core-updates’.

>> > From e78d2d8651d5f56afa7d57be78c5cccccebb117a Mon Sep 17 00:00:00 2001
>> > From: Maxime Devos <maximedevos@telenet.be>
>> > Date: Sun, 18 Apr 2021 20:44:28 +0200
>> > Subject: [PATCH 3/7] build: utils: Make inputs of 'wrap-script' explicit.
>> > 
>> > Previously, 'wrap-script' used (which "guile") to determine where to locate
>> > the guile interpreter.  But this is incorrect when cross-compiling.  When
>> > cross-compiling, this would locate the (native) guile interpreter that is
>> > in the PATH, while a guile interpreter for the target is required.
>> > 
>> > Remove the optional #:guile argument which is only used in tests and replace
>> > it with a required 'inputs' argument and adjust all callers.  Write a new
>> > test verifying a guile for the target is located, instead of a native guile.
>> 
>> I think the #:guile argument was a fine interface: clear and
>> to-the-point.  The problem IMO is just that it’s not use where it
>> should.  :-)
>
> It should be used practically everywhere, no? So making it optional doesn't
> make much sense to me when we want to support cross-compilation.

Yes, and I agree that’s a difficulty.

>> >           (add-after 'install 'wrap-executables
>> > -           (lambda* (#:key outputs #:allow-other-keys)
>> > +           (lambda* (#:key inputs outputs #:allow-other-keys)
>> >               (let ((out (assoc-ref outputs "out")))
>> > -               (wrap-script (string-append out "/bin/carla")
>> > +               (wrap-script (string-append out "/bin/carla") inputs
>> >                              `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
>> 
>> This would become:
>> 
>>   (wrap-script (string-append out "/bin/carla")
>>                `(…)
>>                #:guile (assoc-ref inputs "guile"))
>>
>> WDYT?
>
> Ok, this looks a good interface to me, though I think
> 'wrap-script' will need to be modified. IIRC, #:guile
> must be the full file name of the guile binary and not
> simply /gnu/store/[...]-guile-$VERSION.

Good point.  I think one could write:

  (wrap-script … #:guile (search-input-file inputs "/bin/guile"))

which is more reasonable.

> That should help with the verbosity. The previous code becomes
>
>   (wrap-program (string-append libexec "/dhclient-script")
>      `("PATH" …)
>      #:sh (search-input-file inputs "bin/sh"))
>
> which isn't overly verbose.
>
> This procedure 'search-input-file' would return #f if the input
> was not found, right? I would rather it raises an exception instead.
> There have been some bugs where "#f" was silently written into some file,
> which is unlikely to work well.

Agreed, let’s have ‘search-input-file’ raise an exception if the file
isn’t found.

> For the few cases were the input binary is truly optional,
> we can define a 'search-optional-input-file' procedure.

Let’s ignore that until the problem shows up.

>> > -@c TODO document wrap-program
>> > +@deffn {Scheme Procedure} wrap-program @var{prog} @var{inputs} @var{vars}
>> > +Make a wrapper for @var{prog}.  @var{vars} should look like this:
>> > +
>> > +@lisp
>> > +  '(VARIABLE DELIMITER POSITION LIST-OF-DIRECTORIES)
>>    ^
>> You can remove indentation and use @var instead of capital letters.
>
> @var can be used inside @lisp? Didn't know that.

Yes.

Sorry for the delay, and thanks again!

Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#47869] [PATCH v3 core-updates] various cross-compilation fixes in guix/build/utils.scm
  2021-04-19 19:04 ` [bug#47869] [PATCH v2 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
  2021-05-18 20:51   ` [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès
@ 2021-06-01 19:53   ` Maxime Devos
  2021-06-01 21:01     ` [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès
  2021-06-02  7:56   ` [bug#47869] [PATCH v4 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
  2 siblings, 1 reply; 9+ messages in thread
From: Maxime Devos @ 2021-06-01 19:53 UTC (permalink / raw)
  To: 47869


[-- Attachment #1.1: Type: text/plain, Size: 2400 bytes --]

Hi guix,

This is version three of the patch series,
which (no pun intended) incorporates feedback
from Ludovic Courtès.

This version adds a 'search-input-file' procedure
to (guix build utils). It is used like:

  (wrap-script something #:guile
    (search-input-file inputs "bin/guile")
    [...])

Explicitely setting #:guile instead of defaulting
to (which "guile") is required for cross-compilation,
to make sure the guile eventually used is compiled for
the correct architecture.

This patch series also extends 'wrap-program' with
a #:sh keyword argument, which has the same purpose
as #:guile for 'wrap-script'.

Some differences to v2:

  * The #:sh and #:guile arguments are optional.
    The default value should be good when compiling natively,
    but not when cross-compiling.

    Eventually, we may look into making them required,
    but let's pun for later.

  * I left 'wrap-qt-program' alone for now.

  * I left documenting 'wrap-program' and 'wrap-script' for later.

  * I didn't adjust all uses of wrap-program to set #:sh,
    only a few.

For testing wrap-program:
Write to "a.sh":

  #!/stuff/etcetera
  echo "hello world!"

From ./pre-inst-env guix repl, do:

  (use-modules (guix build utils))
  (wrap-program "a.sh" #:sh "/bin/sh" '("PATH" = ("stuff")))

Now look at "a.sh":

  #!/bin/sh
  export PATH="stuff"
  exec -a "$0" "[current working directory]/.a.sh-real" "$@"

There are some tests in tests/build-utils.scm for 'search-input-file'.

I also ran "make && ./pre-inst-env guix build hello wireguard-tools".
(Not sure about which packages I tested actually.) This successfully
built "hello" (and all its dependencies, this can take a lot of time!).

Building wireguard-tools failed at first. It turned out I made a mistake
in 'wrap-program': the following ...

  (define vars/filtered
    (match vars
      ((#:sh . vars) vars)
      (vars vars)))

... should have been ...

 (define vars/filtered
    (match vars
      ((#:sh _ . vars) vars)
      (vars vars)))

That has been corrected. I tested the corrected "wrap-program" in a REPL
as above, but haven't tried building wireguard-tools again (that would
entail doing the whole bootstrapping process again).

This patch series is on top of commit 9ba35475ede5eb61bfeead096bc6b73f123ac891
on core-updates.

Greetings,
Maxime.

[-- Attachment #1.2: 0001-build-Allow-overriding-the-shell-interpreter-in-wrap.patch --]
[-- Type: text/x-patch, Size: 3141 bytes --]

From 02d2b52458fae1c391e79f89a89696f3b07fdb2b Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 18:22:31 +0200
Subject: [PATCH 01/18] =?UTF-8?q?build:=20Allow=20overriding=20the=20shell?=
 =?UTF-8?q?=20interpreter=20in=20=E2=80=98wrap-program=E2=80=99.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, when creating new wrappers, 'wrap-program' would search
for an interpreter to use in PATH. However, this is incorrect when
cross-compiling. Allow overriding the shell interpreter to use,
via an optional keyword argument #:sh.

In time, when all users of 'wrap-program' have been corrected,
this keyword argument can be made mandatory.

* guix/build/utils.scm (wrap-program): Introduce a #:sh keyword
  argument, defaulting to (which "sh"). Use this keyword argument.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/utils.scm | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index dbfc0a9142..c6731b37ae 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -7,6 +7,7 @@
 ;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -1234,7 +1235,7 @@ known as `nuke-refs' in Nixpkgs."
          (and (string-prefix? "." base)
               (string-suffix? "-real" base)))))
 
-(define* (wrap-program prog #:rest vars)
+(define* (wrap-program prog #:key (sh (which "bash")) #:rest vars)
   "Make a wrapper for PROG.  VARS should look like this:
 
   '(VARIABLE DELIMITER POSITION LIST-OF-DIRECTORIES)
@@ -1261,7 +1262,12 @@ programs that expect particular shared libraries to be in $LD_LIBRARY_PATH, or
 modules in $GUILE_LOAD_PATH, etc.
 
 If PROG has previously been wrapped by 'wrap-program', the wrapper is extended
-with definitions for VARS."
+with definitions for VARS. If it is not, SH will be used as interpreter."
+  (define vars/filtered
+    (match vars
+      ((#:sh _ . vars) vars)
+      (vars vars)))
+
   (define wrapped-file
     (string-append (dirname prog) "/." (basename prog) "-real"))
 
@@ -1315,7 +1321,7 @@ with definitions for VARS."
         (for-each (lambda (var)
                     (display (export-variable var) port)
                     (newline port))
-                  vars)
+                  vars/filtered)
         (display last port)
         (close-port port))
 
@@ -1327,8 +1333,8 @@ with definitions for VARS."
           (lambda (port)
             (format port
                     "#!~a~%~a~%exec -a \"$0\" \"~a\" \"$@\"~%"
-                    (which "bash")
-                    (string-join (map export-variable vars) "\n")
+                    sh
+                    (string-join (map export-variable vars/filtered) "\n")
                     (canonicalize-path wrapped-file))))
 
         (chmod prog-tmp #o755)
-- 
2.31.1


[-- Attachment #1.3: 0002-build-Define-search-input-file-procedure.patch --]
[-- Type: text/x-patch, Size: 4474 bytes --]

From f598c0168bfcb75f718cc8edf990b7a560334405 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 18:36:09 +0200
Subject: [PATCH 02/18] =?UTF-8?q?build:=20Define=20=E2=80=98search-input-f?=
 =?UTF-8?q?ile=E2=80=99=20procedure.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The procedure ‘which’ from (guix build utils)
is used for two different purposes:

  1. for finding the absolute file name of a binary
     that needs to run during the build process

  2. for finding the absolute file name of a binary,
     for the target system (as in --target=TARGET),
     e.g. for substituting sh->/gnu/store/.../bin/sh,
     python->/gnu/store/.../bin/python.

When compiling natively (target=#f in Guix parlance),
this is perfectly fine.

However, when cross-compiling, there is a problem.
"which" looks in $PATH for binaries.  That's good for purpose (1),
but incorrect for (2), as the $PATH contains binaries from native-inputs
instead of inputs.

This commit defines a ‘search-input-file’ procedure. It functions
like 'which', but instead of searching in $PATH, it searches in
the 'inputs' of the build phase, which must be passed to
‘search-input-file’ as an argument. Also, the file name must
include "bin/" or "sbin/" as appropriate.

* guix/build/utils.scm (search-input-file): New procedure.
* tests/build-utils.scm
  ("search-input-file: exception if not found")
  ("search-input-file: can find if existent"): Test it.
* doc/guix.texi (File Search): Document it.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 doc/guix.texi         | 13 +++++++++++++
 guix/build/utils.scm  |  9 +++++++++
 tests/build-utils.scm | 11 +++++++++++
 3 files changed, 33 insertions(+)

diff --git a/doc/guix.texi b/doc/guix.texi
index 535e7614fd..f9d2322ea7 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8661,6 +8661,19 @@ Return the complete file name for @var{program} as found in
 @code{$PATH}, or @code{#f} if @var{program} could not be found.
 @end deffn
 
+@deffn {Scheme Procedure} search-input-file @var{inputs} @var{name}
+Return the complete file name for @var{name} as found in @var{inputs}.
+If @var{name} could not be found, an exception is raised instead.
+Here, @var{inputs} is an association list like @var{inputs} and
+@var{native-inputs} as available to build phases.
+
+This procedure can be used for telling @code{wrap-script} and
+@code{wrap-program} (currently undocumented) where the Guile
+binary or shell binary are located. In fact, that's the
+purpose for which @code{search-input-file} has been created
+in the first place.
+@end deffn
+
 @subsection Build Phases
 
 @cindex build phases
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index c6731b37ae..2ae8478ef7 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -80,6 +80,7 @@
             search-path-as-string->list
             list->search-path-as-string
             which
+            search-input-file
 
             every*
             alist-cons-before
@@ -614,6 +615,14 @@ PROGRAM could not be found."
   (search-path (search-path-as-string->list (getenv "PATH"))
                program))
 
+(define (search-input-file inputs file)
+  "Find a file named FILE among the INPUTS and return its absolute file name.
+
+FILE must be a string like \"bin/sh\". If FILE is not found, an exception is
+raised."
+  (or (search-path (map cdr inputs) file)
+      (error "could not find ~a among the inputs" file)))
+
 \f
 ;;;
 ;;; Phases.
diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index 31be7ff80f..33685c6468 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2012, 2015, 2016, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -263,4 +264,14 @@ print('hello world')"))
          (lambda _
            (get-string-all (current-input-port))))))))
 
+(test-assert "search-input-file: exception if not found"
+  (not (false-if-exception
+         (search-input-file '() "does-not-exist"))))
+
+(test-equal "search-input-file: can find if existent"
+  (which "guile")
+  (search-input-file
+    `(("guile/bin" . ,(dirname (which "guile"))))
+    "guile"))
+
 (test-end)
-- 
2.31.1


[-- Attachment #1.4: 0003-glib-or-gtk-build-system-Look-up-the-interpreter-in-.patch --]
[-- Type: text/x-patch, Size: 3793 bytes --]

From 98856ca64218bd98c0d066a25ac93038a98c7ff5 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Tue, 1 Jun 2021 21:47:01 +0200
Subject: [PATCH 03/18] glib-or-gtk-build-system: Look up the interpreter in
 'inputs'.

* guix/build/glib-or-gtk-build-system.scm (wrap-all-programs): Pass
  the shell interpreter from 'inputs' to 'wrap-program' using
  'search-input-file'.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/glib-or-gtk-build-system.scm | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/guix/build/glib-or-gtk-build-system.scm b/guix/build/glib-or-gtk-build-system.scm
index ccb3138fe2..8d3c3684d3 100644
--- a/guix/build/glib-or-gtk-build-system.scm
+++ b/guix/build/glib-or-gtk-build-system.scm
@@ -2,6 +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 © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -136,6 +137,11 @@ Wrapping is not applied to outputs whose name is listed in
 GLIB-OR-GTK-WRAP-EXCLUDED-OUTPUTS.  This is useful when an output is known not
 to contain any GLib or GTK+ binaries, and where wrapping would gratuitously
 add a dependency of that output on GLib and GTK+."
+  ;; Do not require bash to be present in the package inputs
+  ;; even when there is nothing to wrap.
+  ;; Also, calculate (sh) only once to prevent some I/O.
+  (define %sh (delay (search-input-file inputs "bin/bash")))
+  (define (sh) (force %sh))
   (define handle-output
     (match-lambda
      ((output . directory)
@@ -165,36 +171,36 @@ add a dependency of that output on GLib and GTK+."
                     #f)))
           (cond
            ((and data-env-var gtk-mod-env-var gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            data-env-var
                            gtk-mod-env-var
                            gio-mod-env-var)
                       bin-list))
            ((and data-env-var gtk-mod-env-var (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            data-env-var
                            gtk-mod-env-var)
                       bin-list))
            ((and data-env-var (not gtk-mod-env-var) gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            data-env-var
                            gio-mod-env-var)
                       bin-list))
            ((and (not data-env-var) gtk-mod-env-var gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            gio-mod-env-var
                            gtk-mod-env-var)
                       bin-list))
            ((and data-env-var (not gtk-mod-env-var) (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            data-env-var)
                       bin-list))
            ((and (not data-env-var) gtk-mod-env-var (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            gtk-mod-env-var)
                       bin-list))
            ((and (not data-env-var) (not gtk-mod-env-var) gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            gio-mod-env-var)
                       bin-list))))))))
 
-- 
2.31.1


[-- Attachment #1.5: 0004-python-build-system-Look-up-the-interpreter-in-input.patch --]
[-- Type: text/x-patch, Size: 1872 bytes --]

From bc0085b79dd42e586cc5fcffa6f4972db9f42563 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Tue, 1 Jun 2021 21:48:44 +0200
Subject: [PATCH 04/18] python-build-system: Look up the interpreter in
 'inputs'.

* guix/build/python-build-system.scm (wrap): Pass the shell
  interpreter from 'inputs' to 'wrap-program' using 'search-input-file'.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/python-build-system.scm | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/guix/build/python-build-system.scm b/guix/build/python-build-system.scm
index 5b1339d14c..08871f60cd 100644
--- a/guix/build/python-build-system.scm
+++ b/guix/build/python-build-system.scm
@@ -10,6 +10,7 @@
 ;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
 ;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2021 Lars-Dominik Braun <lars@6xq.net>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -234,12 +235,18 @@ running checks after installing the package."
                          (string-append dir "/sbin"))))
                 outputs))
 
+  ;; Do not require "bash" to be present in the package inputs
+  ;; even when there is nothing to wrap.
+  ;; Also, calculate (sh) only once to prevent some I/O.
+  (define %sh (delay (search-input-file inputs "bin/bash")))
+  (define (sh) (force %sh))
+
   (let* ((var `("GUIX_PYTHONPATH" prefix
                 ,(search-path-as-string->list
                   (or (getenv "GUIX_PYTHONPATH") "")))))
     (for-each (lambda (dir)
                 (let ((files (list-of-files dir)))
-                  (for-each (cut wrap-program <> var)
+                  (for-each (cut wrap-program <> #:sh (sh) var)
                             files)))
               bindirs)))
 
-- 
2.31.1


[-- Attachment #1.6: 0005-qt-build-system-Look-up-the-interpreter-in-inputs.patch --]
[-- Type: text/x-patch, Size: 1919 bytes --]

From 0370ad982e90c3e4def9cd5245cbd6769fda2830 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:20:12 +0200
Subject: [PATCH 05/18] qt-build-system: Look up the interpreter in 'inputs'.

* guix/build/qt-build-system.scm (wrap-all-programs): Pass
  the shell interpreter from 'inputs' to 'wrap-program' using
  'search-input-file'.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/qt-build-system.scm | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/guix/build/qt-build-system.scm b/guix/build/qt-build-system.scm
index 762fd8a2ee..ec7ceb38bd 100644
--- a/guix/build/qt-build-system.scm
+++ b/guix/build/qt-build-system.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2014, 2015, 2021 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2019, 2020 Hartmut Goebel <h.goebel@crazy-compilers.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -126,6 +127,12 @@ add a dependency of that output on Qt."
            (((_ . dir) ...)
             dir)))
 
+  ;; Do not require bash to be present in the package inputs
+  ;; even when there is nothing to wrap.
+  ;; Also, calculate (sh) only once to prevent some I/O.
+  (define %sh (delay (search-input-file inputs "bin/bash")))
+  (define (sh) (force %sh))
+
   (define handle-output
     (match-lambda
      ((output . directory)
@@ -135,7 +142,7 @@ add a dependency of that output on Qt."
                              (append (list directory)
                                      input-directories))))
           (when (not (null? vars-to-wrap))
-            (for-each (cut apply wrap-program <> vars-to-wrap)
+            (for-each (cut apply wrap-program <> #:sh (sh) vars-to-wrap)
                       bin-list)))))))
 
   (for-each handle-output outputs)
-- 
2.31.1


[-- Attachment #1.7: 0006-rakudo-build-system-Look-up-the-interpreter-in-input.patch --]
[-- Type: text/x-patch, Size: 1846 bytes --]

From 92278afdc58430e8e9f6887d481964e1d73e551c Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:21:16 +0200
Subject: [PATCH 06/18] rakudo-build-system: Look up the interpreter in
 'inputs'.

* guix/build/rakudo-build-system.scm (wrap): Pass
  the shell interpreter from 'inputs' to 'wrap-program' using
  'search-input-file'.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/rakudo-build-system.scm | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/guix/build/rakudo-build-system.scm b/guix/build/rakudo-build-system.scm
index b2c090f946..5cf1cc55bc 100644
--- a/guix/build/rakudo-build-system.scm
+++ b/guix/build/rakudo-build-system.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -108,6 +109,12 @@
                         (string-append dir "/sbin"))))
                 outputs))
 
+  ;; Do not require bash to be present in the package inputs
+  ;; even when there is nothing to wrap.
+  ;; Also, calculate (sh) only once to prevent some I/O.
+  (define %sh (delay (search-input-file inputs "bin/bash")))
+  (define (sh) (force %sh))
+
   (let* ((out  (assoc-ref outputs "out"))
          (var `("PERL6LIB" "," prefix
                 ,(cons (string-append out "/share/perl6/lib,"
@@ -117,7 +124,7 @@
                         (or (getenv "PERL6LIB") "") #\,)))))
     (for-each (lambda (dir)
                 (let ((files (list-of-files dir)))
-                  (for-each (cut wrap-program <> var)
+                  (for-each (cut wrap-program <> #:sh (sh) var)
                             files)))
               bindirs)
     #t))
-- 
2.31.1


[-- Attachment #1.8: 0007-gnu-carla-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1331 bytes --]

From e8b21fba6cd6a45cbaaab6547f8906b84618a38e Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:41:22 +0200
Subject: [PATCH 07/18] gnu: carla: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/audio.scm
  (carla)[arguments]<#:phases>{wrap-executables}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/audio.scm | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/audio.scm b/gnu/packages/audio.scm
index f677d46a7f..930c111d5e 100644
--- a/gnu/packages/audio.scm
+++ b/gnu/packages/audio.scm
@@ -4711,9 +4711,10 @@ as is the case with audio plugins.")
                (chmod (string-append out "/share/carla/carla") #o555)
                #t)))
          (add-after 'install 'wrap-executables
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-script (string-append out "/bin/carla")
+                            #:guile (search-input-file inputs "bin/guile")
                             `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (inputs
-- 
2.31.1


[-- Attachment #1.9: 0008-gnu-bats-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1068 bytes --]

From 7a337fa6576ed1b797cbae5c6d26e0dd90a744fa Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:42:58 +0200
Subject: [PATCH 08/18] gnu: bats: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bash.scm
  (bats)[arguments]<#:builder>: Set #:guile argument
  of ‘wrap-script’.
---
 gnu/packages/bash.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/bash.scm b/gnu/packages/bash.scm
index 8dfbd7834e..7e98367bbb 100644
--- a/gnu/packages/bash.scm
+++ b/gnu/packages/bash.scm
@@ -402,6 +402,7 @@ capturing.")
          ;; Install phase
          (invoke "./install.sh" %output)
          (wrap-script (string-append %output "/bin/bats")
+                      #:guile (search-input-file %build-inputs "bin/guile")
                       (list "PATH" 'prefix (string-split (getenv "PATH")
                                                          #\:))))))
     (build-system trivial-build-system)
-- 
2.31.1


[-- Attachment #1.10: 0009-gnu-proteinortho-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1586 bytes --]

From 3cca28ba7694ee32f252c089d88d7e2834d1c415 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:46:22 +0200
Subject: [PATCH 09/18] gnu: proteinortho: Set #:guile argument of
 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bioinformatics.scm
  (proteinortho)[arguments]<#:phases>{wrap-programs}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/bioinformatics.scm | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 85f785955e..7d8496e692 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -5447,9 +5447,11 @@ predicts the locations of structural units in the sequences.")
          (add-after 'install 'wrap-programs
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((path (getenv "PATH"))
-                   (out (assoc-ref outputs "out")))
+                   (out (assoc-ref outputs "out"))
+                   (guile (search-input-file inputs "bin/guile")))
                (for-each (lambda (script)
-                           (wrap-script script `("PATH" ":" prefix (,path))))
+                           (wrap-script script #:guile guile
+                                        `("PATH" ":" prefix (,path))))
                          (cons (string-append out "/bin/proteinortho")
                                (find-files out "\\.(pl|py)$"))))
              #t)))))
-- 
2.31.1


[-- Attachment #1.11: 0010-gnu-prinseq-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1805 bytes --]

From a60dd8b0cd55e27f1e5d72f75cb5cbfb59acfb48 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:48:19 +0200
Subject: [PATCH 10/18] gnu: prinseq: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bioinformatics.scm
  (prinseq)[arguments]<#:phases>{install}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/bioinformatics.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 7d8496e692..37483984ec 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -7557,7 +7557,8 @@ experience substantial biological insertions and deletions.")
            (lambda* (#:key outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin"))
-                    (scripts (find-files "." "prinseq.*.pl")))
+                    (scripts (find-files "." "prinseq.*.pl"))
+                    (guile (search-input-file "bin/guile")))
                (substitute* scripts
                  (("\"perl -pe")
                   (string-append "\"" (which "perl") " -pe")))
@@ -7565,6 +7566,7 @@ experience substantial biological insertions and deletions.")
                            (chmod file #o555)
                            (install-file file bin)
                            (wrap-script (string-append bin "/" (basename file))
+                                        #:guile guile
                                         `("PERL5LIB" ":" prefix
                                           (,(getenv "PERL5LIB")))))
                          scripts)))))))
-- 
2.31.1


[-- Attachment #1.12: 0011-gnu-gess-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1607 bytes --]

From 0ef6b12b7b5645b9e17bfbe9e65ed341146eec80 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:50:07 +0200
Subject: [PATCH 11/18] gnu: gess: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bioinformatics.scm
  (gess)[arguments]<#:phases>{install}
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/bioinformatics.scm | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 37483984ec..965e26b812 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -7554,7 +7554,7 @@ experience substantial biological insertions and deletions.")
          (delete 'configure)
          (delete 'build)
          (replace 'install
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin"))
                     (scripts (find-files "." "prinseq.*.pl"))
@@ -10239,6 +10239,7 @@ matplotlib.use('Agg')
 " line)))
                ;; Make sure GESS has all modules in its path
                (wrap-script (string-append target "GESS.py")
+                 #:guile (search-input-file inputs "bin/guile")
                  `("GUIX_PYTHONPATH" ":" = (,target ,(getenv "GUIX_PYTHONPATH"))))
                (mkdir-p bin)
                (symlink (string-append target "GESS.py")
-- 
2.31.1


[-- Attachment #1.13: 0012-gnu-nanopolish-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 2081 bytes --]

From bb4599d61bebe0a9db8863542349d1558163b468 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:54:49 +0200
Subject: [PATCH 12/18] gnu: nanopolish: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bioinformatics.scm
  (nanopolish)[arguments]<#:phases>{wrap-programs}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/bioinformatics.scm | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 965e26b812..fc2fc867ac 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -13583,16 +13583,18 @@ choosing which reads pass the filter.")
                            (find-files "scripts" ".*"))
                  #t)))
            (add-after 'install 'wrap-programs
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let ((pythonpath (getenv "GUIX_PYTHONPATH"))
                      (perl5lib (getenv "PERL5LIB"))
                      (scripts (string-append (assoc-ref outputs "out")
-                                             "/share/nanopolish/scripts")))
+                                             "/share/nanopolish/scripts"))
+                     (guile (search-input-file inputs "bin/guile")))
                  (for-each (lambda (file)
                              (wrap-program file `("GUIX_PYTHONPATH" ":" prefix (,pythonpath))))
                            (find-files scripts "\\.py"))
                  (for-each (lambda (file)
-                             (wrap-script file `("PERL5LIB" ":" prefix (,perl5lib))))
+                             (wrap-script file #:guile guile
+                                          `("PERL5LIB" ":" prefix (,perl5lib))))
                            (find-files scripts "\\.pl"))))))))
       (inputs
        `(("guile" ,guile-3.0) ; for wrappers
-- 
2.31.1


[-- Attachment #1.14: 0013-gnu-sieve-connect-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1043 bytes --]

From 0e8be56ecd1c4509d1b4ccdf51ec178a0ec1baaf Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:58:53 +0200
Subject: [PATCH 13/18] gnu: sieve-connect: Set #:guile argument of
 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/mail.scm
  (sieve-connect)[arguments]<#:phases>{wrap-program}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/mail.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/mail.scm b/gnu/packages/mail.scm
index a885e2417c..7aed1aa5bd 100644
--- a/gnu/packages/mail.scm
+++ b/gnu/packages/mail.scm
@@ -2924,6 +2924,7 @@ transfer protocols.")
              (let ((out (assoc-ref outputs "out"))
                    (path (getenv "PERL5LIB")))
                (wrap-script (string-append out "/bin/sieve-connect")
+                 #:guile (search-input-file inputs "bin/guile")
                  `("PERL5LIB" ":" = (,path)))
                #t))))))
     (inputs
-- 
2.31.1


[-- Attachment #1.15: 0014-gnu-clipmenu-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1515 bytes --]

From 9f71e9330382689e6a79f19568d456e36df3087e Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:04:30 +0200
Subject: [PATCH 14/18] gnu: clipmenu: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/xdisorg.scm
  (clipmenu)[arguments]<#:phases>{wrap-script}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/xdisorg.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/xdisorg.scm b/gnu/packages/xdisorg.scm
index de2cba8e57..d339851f51 100644
--- a/gnu/packages/xdisorg.scm
+++ b/gnu/packages/xdisorg.scm
@@ -2555,10 +2555,12 @@ tools to complement clipnotify.")
                       (gawk              (assoc-ref inputs "gawk"))
                       (util-linux        (assoc-ref inputs "util-linux"))
                       (xdotool           (assoc-ref inputs "xdotool"))
-                      (xsel              (assoc-ref inputs "xsel")))
+                      (xsel              (assoc-ref inputs "xsel"))
+                      (guile             (search-input-file inputs "bin/guile")))
                  (for-each
                   (lambda (prog)
                     (wrap-script (string-append out "/bin/" prog)
+                      #:guile guile
                       `("PATH" ":" prefix
                         ,(map (lambda (dir)
                                 (string-append dir "/bin"))
-- 
2.31.1


[-- Attachment #1.16: 0015-gnu-vpnc-scripts-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1522 bytes --]

From 7ecf6502fc902959fd2a233c5f772180678e9f35 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:06:12 +0200
Subject: [PATCH 15/18] gnu: vpnc-scripts: Set #:guile argument of
 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/vpn.scm
  (vpnc-scripts)[arguments]<#:phases>{wrap-scripts}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/vpn.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index a952e3f0db..33ef87c52d 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -192,10 +192,12 @@ Only \"Universal TUN/TAP device driver support\" is needed in the kernel.")
              ;; Wrap scripts with paths to their common hard dependencies.
              ;; Optional dependencies will need to be installed by the user.
              (lambda* (#:key inputs outputs #:allow-other-keys)
-               (let ((out (assoc-ref outputs "out")))
+               (let ((out (assoc-ref outputs "out"))
+                     (guile (search-input-file inputs "bin/guile")))
                  (for-each
                   (lambda (script)
                     (wrap-script (string-append out "/etc/vpnc/" script)
+                      #:guile guile
                       `("PATH" ":" prefix
                         ,(map (lambda (name)
                                 (let ((input (assoc-ref inputs name)))
-- 
2.31.1


[-- Attachment #1.17: 0016-gnu-openconnect-sso-Set-sh-argument-of-wrap-program.patch --]
[-- Type: text/x-patch, Size: 1079 bytes --]

From 5a18f07c5d7ea73d306e3b66ff72f285f38376ac Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:09:45 +0200
Subject: [PATCH 16/18] gnu: openconnect-sso: Set #:sh argument of
 'wrap-program'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/vpn.scm
  (openconnect-sso)[arguments]<#:phases>{wrap-qt-process-path}
  Set #:sh argument of ‘wrap-program’.
---
 gnu/packages/vpn.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index 33ef87c52d..584ff0ec84 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -326,6 +326,7 @@ and probably others.")
                                        (assoc-ref inputs "qtwebengine")
                                        "/lib/qt5/libexec/QtWebEngineProcess")))
                (wrap-program bin
+                 #:sh (search-input-file inputs "bin/bash")
                  `("QTWEBENGINEPROCESS_PATH" = (,qt-process-path)))
                #t))))))
     (inputs
-- 
2.31.1


[-- Attachment #1.18: 0017-gnu-protonvpn-cli-Set-sh-argument-of-wrap-program.patch --]
[-- Type: text/x-patch, Size: 1196 bytes --]

From b180eb2b419ca8b09412ab30c0442f54ae14775f Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:11:50 +0200
Subject: [PATCH 17/18] gnu: protonvpn-cli: Set #:sh argument of
 'wrap-program'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/vpn.scm
  (protonvpn-cli)[arguments]<#:phases>{wrap-wrapper}:
  Set #:sh argument of ‘wrap-program’.
---
 gnu/packages/vpn.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index 584ff0ec84..66c103e75f 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -440,6 +440,7 @@ traversing network address translators (@dfn{NAT}s) and firewalls.")
              (let ((entrypoint (string-append (assoc-ref outputs "out")
                                               "/bin/.protonvpn-real")))
                (wrap-program entrypoint
+                            #:sh (search-input-file inputs "bin/bash")
                             `("PATH" ":" prefix
                               ,(map (lambda (name)
                                       (let ((input (assoc-ref inputs name)))
-- 
2.31.1


[-- Attachment #1.19: 0018-gnu-wireguard-tools-Set-sh-argument-of-wrap-program.patch --]
[-- Type: text/x-patch, Size: 1141 bytes --]

From c1ab0f5161254e66ae3515df60440dd4bcb46fd4 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:12:55 +0200
Subject: [PATCH 18/18] gnu: wireguard-tools: Set #:sh argument of
 'wrap-program'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/vpn.scm
  (wireguard-tools)[arguments]<#:phases>{wrap-wg-quick}:
  Set #:sh argument of ‘wrap-program’.
---
 gnu/packages/vpn.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index 66c103e75f..34715a4cc8 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -726,6 +726,7 @@ WireGuard was added to Linux 5.6.")
                    (coreutils (string-append (assoc-ref inputs "coreutils")
                                              "/bin")))
                (wrap-program (string-append out "/bin/wg-quick")
+                 #:sh (search-input-file inputs "bin/bash")
                  `("PATH" ":" prefix ,(append inputs-sbin
                                               (list coreutils))))
                #t))))))
-- 
2.31.1


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling
  2021-06-01 19:53   ` [bug#47869] [PATCH v3 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
@ 2021-06-01 21:01     ` Ludovic Courtès
  0 siblings, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2021-06-01 21:01 UTC (permalink / raw)
  To: Maxime Devos; +Cc: 47869

Hi Maxime,

Maxime Devos <maximedevos@telenet.be> skribis:

> Some differences to v2:
>
>   * The #:sh and #:guile arguments are optional.
>     The default value should be good when compiling natively,
>     but not when cross-compiling.
>
>     Eventually, we may look into making them required,
>     but let's pun for later.
>
>   * I left 'wrap-qt-program' alone for now.
>
>   * I left documenting 'wrap-program' and 'wrap-script' for later.
>
>   * I didn't adjust all uses of wrap-program to set #:sh,
>     only a few.

[...]

> This patch series is on top of commit 9ba35475ede5eb61bfeead096bc6b73f123ac891
> on core-updates.

Woow, nice!

I’ll first focus on the first few patches, those that trigger a world
rebuild.  Subsequent patches look good and are less “critical”.

> From 02d2b52458fae1c391e79f89a89696f3b07fdb2b Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Mon, 31 May 2021 18:22:31 +0200
> Subject: [PATCH 01/18] =?UTF-8?q?build:=20Allow=20overriding=20the=20shell?=
>  =?UTF-8?q?=20interpreter=20in=20=E2=80=98wrap-program=E2=80=99.?=
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> Previously, when creating new wrappers, 'wrap-program' would search
> for an interpreter to use in PATH. However, this is incorrect when
> cross-compiling. Allow overriding the shell interpreter to use,
> via an optional keyword argument #:sh.
>
> In time, when all users of 'wrap-program' have been corrected,
> this keyword argument can be made mandatory.
>
> * guix/build/utils.scm (wrap-program): Introduce a #:sh keyword
>   argument, defaulting to (which "sh"). Use this keyword argument.
>
> Partially-Fixes: <https://issues.guix.gnu.org/47869>

LGTM (will apply together with the other world-rebuild changes).

> From f598c0168bfcb75f718cc8edf990b7a560334405 Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Mon, 31 May 2021 18:36:09 +0200
> Subject: [PATCH 02/18] =?UTF-8?q?build:=20Define=20=E2=80=98search-input-f?=
>  =?UTF-8?q?ile=E2=80=99=20procedure.?=
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> The procedure ‘which’ from (guix build utils)
> is used for two different purposes:
>
>   1. for finding the absolute file name of a binary
>      that needs to run during the build process
>
>   2. for finding the absolute file name of a binary,
>      for the target system (as in --target=TARGET),
>      e.g. for substituting sh->/gnu/store/.../bin/sh,
>      python->/gnu/store/.../bin/python.
>
> When compiling natively (target=#f in Guix parlance),
> this is perfectly fine.
>
> However, when cross-compiling, there is a problem.
> "which" looks in $PATH for binaries.  That's good for purpose (1),
> but incorrect for (2), as the $PATH contains binaries from native-inputs
> instead of inputs.
>
> This commit defines a ‘search-input-file’ procedure. It functions
> like 'which', but instead of searching in $PATH, it searches in
> the 'inputs' of the build phase, which must be passed to
> ‘search-input-file’ as an argument. Also, the file name must
> include "bin/" or "sbin/" as appropriate.
>
> * guix/build/utils.scm (search-input-file): New procedure.
> * tests/build-utils.scm
>   ("search-input-file: exception if not found")
>   ("search-input-file: can find if existent"): Test it.
> * doc/guix.texi (File Search): Document it.
>
> Partially-Fixes: <https://issues.guix.gnu.org/47869>

I don’t think we need the whole story here :-) though it doesn’t hurt.
‘search-input-file’ is useful on its own IMO.

> +@deffn {Scheme Procedure} search-input-file @var{inputs} @var{name}
> +Return the complete file name for @var{name} as found in @var{inputs}.
> +If @var{name} could not be found, an exception is raised instead.
> +Here, @var{inputs} is an association list like @var{inputs} and
> +@var{native-inputs} as available to build phases.
> +
> +This procedure can be used for telling @code{wrap-script} and
> +@code{wrap-program} (currently undocumented) where the Guile
> +binary or shell binary are located. In fact, that's the
> +purpose for which @code{search-input-file} has been created
> +in the first place.
> +@end deffn

I’d remove the second paragraph: IMO it’s not the right place to
document the motivation.  However, an @lisp example would be nice.

BTW, please remember to leave two spaces after end-of-sentence periods.

> +(define (search-input-file inputs file)
> +  "Find a file named FILE among the INPUTS and return its absolute file name.
> +
> +FILE must be a string like \"bin/sh\". If FILE is not found, an exception is
> +raised."
> +  (or (search-path (map cdr inputs) file)
> +      (error "could not find ~a among the inputs" file)))

Rather:

  (match inputs
    (((_ . directories) ...)
     (or (search-path directories file)
         (raise (condition (&search-error (path directories) (file file)))))))

… so you’d need to define a new error condition type.

It’s better to make this extra effort; ‘error’ throws to 'misc-error and
cannot be meaningfully handled by callers.

> +(test-assert "search-input-file: exception if not found"
> +  (not (false-if-exception
> +         (search-input-file '() "does-not-exist"))))

Here you’d use ‘guard’ to check you got the right exception.

> From 98856ca64218bd98c0d066a25ac93038a98c7ff5 Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Tue, 1 Jun 2021 21:47:01 +0200
> Subject: [PATCH 03/18] glib-or-gtk-build-system: Look up the interpreter in
>  'inputs'.
>
> * guix/build/glib-or-gtk-build-system.scm (wrap-all-programs): Pass
>   the shell interpreter from 'inputs' to 'wrap-program' using
>   'search-input-file'.
>
> Partially-Fixes: <https://issues.guix.gnu.org/47869>

[...]

> +  ;; Do not require bash to be present in the package inputs
> +  ;; even when there is nothing to wrap.
> +  ;; Also, calculate (sh) only once to prevent some I/O.
> +  (define %sh (delay (search-input-file inputs "bin/bash")))
> +  (define (sh) (force %sh))

I’d be tempted for clarity to simply write:

  (define (sh)
    (search-input-file inputs "bin/bash"))

The extra ‘stat’ calls may be okay in practice but yeah, dunno.

> From bc0085b79dd42e586cc5fcffa6f4972db9f42563 Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Tue, 1 Jun 2021 21:48:44 +0200
> Subject: [PATCH 04/18] python-build-system: Look up the interpreter in
>  'inputs'.
>
> * guix/build/python-build-system.scm (wrap): Pass the shell
>   interpreter from 'inputs' to 'wrap-program' using 'search-input-file'.
>
> Partially-Fixes: <https://issues.guix.gnu.org/47869>

[...]

> From 0370ad982e90c3e4def9cd5245cbd6769fda2830 Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Mon, 31 May 2021 19:20:12 +0200
> Subject: [PATCH 05/18] qt-build-system: Look up the interpreter in 'inputs'.
>
> * guix/build/qt-build-system.scm (wrap-all-programs): Pass
>   the shell interpreter from 'inputs' to 'wrap-program' using
>   'search-input-file'.
>
> Partially-Fixes: <https://issues.guix.gnu.org/47869>

[...]

> From 92278afdc58430e8e9f6887d481964e1d73e551c Mon Sep 17 00:00:00 2001
> From: Maxime Devos <maximedevos@telenet.be>
> Date: Mon, 31 May 2021 19:21:16 +0200
> Subject: [PATCH 06/18] rakudo-build-system: Look up the interpreter in
>  'inputs'.
>
> * guix/build/rakudo-build-system.scm (wrap): Pass
>   the shell interpreter from 'inputs' to 'wrap-program' using
>   'search-input-file'.
>
> Partially-Fixes: <https://issues.guix.gnu.org/47869>

LGTM!

So in the end, I’m suggesting modifications to #2 and the rest LGTM.

Thank you!

Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* [bug#47869] [PATCH v4 core-updates] various cross-compilation fixes in guix/build/utils.scm
  2021-04-19 19:04 ` [bug#47869] [PATCH v2 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
  2021-05-18 20:51   ` [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès
  2021-06-01 19:53   ` [bug#47869] [PATCH v3 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
@ 2021-06-02  7:56   ` Maxime Devos
  2021-06-04 21:31     ` bug#47869: [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès
  2 siblings, 1 reply; 9+ messages in thread
From: Maxime Devos @ 2021-06-02  7:56 UTC (permalink / raw)
  To: 47869


[-- Attachment #1.1: Type: text/plain, Size: 387 bytes --]

Hi guix,

This is version 4 of the patch series.
It lets 'search-input-file' raise the new
&search-error exception instead of misc-error.

The documentation of 'search-input-file' has been
adjusted to give an example of how it can be used.

Also, there is one new test in tests/build-utils.scm
("search-input-file: can search in multiple directories").

Greetings,
Maxime.

[-- Attachment #1.2: 0001-build-Allow-overriding-the-shell-interpreter-in-wrap.patch --]
[-- Type: text/x-patch, Size: 3141 bytes --]

From 02d2b52458fae1c391e79f89a89696f3b07fdb2b Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 18:22:31 +0200
Subject: [PATCH 01/18] =?UTF-8?q?build:=20Allow=20overriding=20the=20shell?=
 =?UTF-8?q?=20interpreter=20in=20=E2=80=98wrap-program=E2=80=99.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Previously, when creating new wrappers, 'wrap-program' would search
for an interpreter to use in PATH. However, this is incorrect when
cross-compiling. Allow overriding the shell interpreter to use,
via an optional keyword argument #:sh.

In time, when all users of 'wrap-program' have been corrected,
this keyword argument can be made mandatory.

* guix/build/utils.scm (wrap-program): Introduce a #:sh keyword
  argument, defaulting to (which "sh"). Use this keyword argument.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/utils.scm | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index dbfc0a9142..c6731b37ae 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -7,6 +7,7 @@
 ;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2020, 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -1234,7 +1235,7 @@ known as `nuke-refs' in Nixpkgs."
          (and (string-prefix? "." base)
               (string-suffix? "-real" base)))))
 
-(define* (wrap-program prog #:rest vars)
+(define* (wrap-program prog #:key (sh (which "bash")) #:rest vars)
   "Make a wrapper for PROG.  VARS should look like this:
 
   '(VARIABLE DELIMITER POSITION LIST-OF-DIRECTORIES)
@@ -1261,7 +1262,12 @@ programs that expect particular shared libraries to be in $LD_LIBRARY_PATH, or
 modules in $GUILE_LOAD_PATH, etc.
 
 If PROG has previously been wrapped by 'wrap-program', the wrapper is extended
-with definitions for VARS."
+with definitions for VARS. If it is not, SH will be used as interpreter."
+  (define vars/filtered
+    (match vars
+      ((#:sh _ . vars) vars)
+      (vars vars)))
+
   (define wrapped-file
     (string-append (dirname prog) "/." (basename prog) "-real"))
 
@@ -1315,7 +1321,7 @@ with definitions for VARS."
         (for-each (lambda (var)
                     (display (export-variable var) port)
                     (newline port))
-                  vars)
+                  vars/filtered)
         (display last port)
         (close-port port))
 
@@ -1327,8 +1333,8 @@ with definitions for VARS."
           (lambda (port)
             (format port
                     "#!~a~%~a~%exec -a \"$0\" \"~a\" \"$@\"~%"
-                    (which "bash")
-                    (string-join (map export-variable vars) "\n")
+                    sh
+                    (string-join (map export-variable vars/filtered) "\n")
                     (canonicalize-path wrapped-file))))
 
         (chmod prog-tmp #o755)
-- 
2.31.1


[-- Attachment #1.3: 0002-build-Define-search-input-file-procedure.patch --]
[-- Type: text/x-patch, Size: 6023 bytes --]

From 232d0c5a8814690ecb39af86b0d30c174003c752 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 18:36:09 +0200
Subject: [PATCH 02/18] =?UTF-8?q?build:=20Define=20=E2=80=98search-input-f?=
 =?UTF-8?q?ile=E2=80=99=20procedure.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The procedure ‘which’ from (guix build utils)
is used for two different purposes:

  1. for finding the absolute file name of a binary
     that needs to run during the build process

  2. for finding the absolute file name of a binary,
     for the target system (as in --target=TARGET),
     e.g. for substituting sh->/gnu/store/.../bin/sh,
     python->/gnu/store/.../bin/python.

When compiling natively (target=#f in Guix parlance),
this is perfectly fine.

However, when cross-compiling, there is a problem.
"which" looks in $PATH for binaries.  That's good for purpose (1),
but incorrect for (2), as the $PATH contains binaries from native-inputs
instead of inputs.

This commit defines a ‘search-input-file’ procedure. It functions
like 'which', but instead of searching in $PATH, it searches in
the 'inputs' of the build phase, which must be passed to
‘search-input-file’ as an argument. Also, the file name must
include "bin/" or "sbin/" as appropriate.

* guix/build/utils.scm (search-input-file): New procedure.
* tests/build-utils.scm
  ("search-input-file: exception if not found")
  ("search-input-file: can find if existent"): Test it.
* doc/guix.texi (File Search): Document it.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
Co-Authored-By: Ludovic Courtès <ludo@gnu.org>
---
 doc/guix.texi         | 20 ++++++++++++++++++++
 guix/build/utils.scm  | 21 ++++++++++++++++++++-
 tests/build-utils.scm | 25 +++++++++++++++++++++++++
 3 files changed, 65 insertions(+), 1 deletion(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 535e7614fd..3557c977e1 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8661,6 +8661,26 @@ Return the complete file name for @var{program} as found in
 @code{$PATH}, or @code{#f} if @var{program} could not be found.
 @end deffn
 
+@deffn {Scheme Procedure} search-input-file @var{inputs} @var{name}
+Return the complete file name for @var{name} as found in @var{inputs}.
+If @var{name} could not be found, an exception is raised instead.
+Here, @var{inputs} is an association list like @var{inputs} and
+@var{native-inputs} as available to build phases.
+@end deffn
+
+Here is a (simplified) example of how @code{search-input-file} is used
+in a build phase of the @code{wireguard-tools} package:
+
+@lisp
+(add-after 'install 'wrap-wg-quick
+  (lambda* (#:key inputs outputs #:allow-other-keys)
+    (let ((coreutils (string-append (assoc-ref inputs "coreutils")
+                                    "/bin")))
+      (wrap-program (search-input-file outputs "bin/wg-quick")
+        #:sh (search-input-file inputs "bin/bash")
+        `("PATH" ":" prefix ,(list coreutils))))))
+@end lisp
+
 @subsection Build Phases
 
 @cindex build phases
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index c6731b37ae..2636da392f 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
 ;;; Copyright © 2015, 2018, 2021 Mark H Weaver <mhw@netris.org>
@@ -80,6 +80,10 @@
             search-path-as-string->list
             list->search-path-as-string
             which
+            search-input-file
+            search-error?
+            search-error-path
+            search-error-file
 
             every*
             alist-cons-before
@@ -614,6 +618,21 @@ PROGRAM could not be found."
   (search-path (search-path-as-string->list (getenv "PATH"))
                program))
 
+(define-condition-type &search-error &error
+  search-error?
+  (path         search-error-path)
+  (file         search-error-file))
+
+(define (search-input-file inputs file)
+  "Find a file named FILE among the INPUTS and return its absolute file name.
+
+FILE must be a string like \"bin/sh\". If FILE is not found, an exception is
+raised."
+  (match inputs
+    (((_ . directories) ...)
+     (or (search-path directories file)
+         (raise (condition (&search-error (path directories) (file file))))))))
+
 \f
 ;;;
 ;;; Phases.
diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index 31be7ff80f..6b131c0af8 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2012, 2015, 2016, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -263,4 +264,28 @@ print('hello world')"))
          (lambda _
            (get-string-all (current-input-port))))))))
 
+(test-equal "search-input-file: exception if not found"
+  `((path)
+    (file . "does-not-exist"))
+  (guard (e ((search-error? e)
+             `((path . ,(search-error-path e))
+               (file . ,(search-error-file e)))))
+    (search-input-file '() "does-not-exist")))
+
+(test-equal "search-input-file: can find if existent"
+  (which "guile")
+  (search-input-file
+    `(("guile/bin" . ,(dirname (which "guile"))))
+    "guile"))
+
+(test-equal "search-input-file: can search in multiple directories"
+  (which "guile")
+  (call-with-temporary-directory
+    (lambda (directory)
+      (search-input-file
+        `(("irrelevant" . ,directory)
+          ("guile/bin" . ,(dirname (which "guile"))))
+        "guile"))))
+
+
 (test-end)
-- 
2.31.1


[-- Attachment #1.4: 0003-glib-or-gtk-build-system-Look-up-the-interpreter-in-.patch --]
[-- Type: text/x-patch, Size: 3793 bytes --]

From 51aad468090519e063efcddb5aa2afdf19d8da1d Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Tue, 1 Jun 2021 21:47:01 +0200
Subject: [PATCH 03/18] glib-or-gtk-build-system: Look up the interpreter in
 'inputs'.

* guix/build/glib-or-gtk-build-system.scm (wrap-all-programs): Pass
  the shell interpreter from 'inputs' to 'wrap-program' using
  'search-input-file'.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/glib-or-gtk-build-system.scm | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/guix/build/glib-or-gtk-build-system.scm b/guix/build/glib-or-gtk-build-system.scm
index ccb3138fe2..8d3c3684d3 100644
--- a/guix/build/glib-or-gtk-build-system.scm
+++ b/guix/build/glib-or-gtk-build-system.scm
@@ -2,6 +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 © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -136,6 +137,11 @@ Wrapping is not applied to outputs whose name is listed in
 GLIB-OR-GTK-WRAP-EXCLUDED-OUTPUTS.  This is useful when an output is known not
 to contain any GLib or GTK+ binaries, and where wrapping would gratuitously
 add a dependency of that output on GLib and GTK+."
+  ;; Do not require bash to be present in the package inputs
+  ;; even when there is nothing to wrap.
+  ;; Also, calculate (sh) only once to prevent some I/O.
+  (define %sh (delay (search-input-file inputs "bin/bash")))
+  (define (sh) (force %sh))
   (define handle-output
     (match-lambda
      ((output . directory)
@@ -165,36 +171,36 @@ add a dependency of that output on GLib and GTK+."
                     #f)))
           (cond
            ((and data-env-var gtk-mod-env-var gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            data-env-var
                            gtk-mod-env-var
                            gio-mod-env-var)
                       bin-list))
            ((and data-env-var gtk-mod-env-var (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            data-env-var
                            gtk-mod-env-var)
                       bin-list))
            ((and data-env-var (not gtk-mod-env-var) gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            data-env-var
                            gio-mod-env-var)
                       bin-list))
            ((and (not data-env-var) gtk-mod-env-var gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            gio-mod-env-var
                            gtk-mod-env-var)
                       bin-list))
            ((and data-env-var (not gtk-mod-env-var) (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            data-env-var)
                       bin-list))
            ((and (not data-env-var) gtk-mod-env-var (not gio-mod-env-var))
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            gtk-mod-env-var)
                       bin-list))
            ((and (not data-env-var) (not gtk-mod-env-var) gio-mod-env-var)
-            (for-each (cut wrap-program <>
+            (for-each (cut wrap-program <> #:sh (sh)
                            gio-mod-env-var)
                       bin-list))))))))
 
-- 
2.31.1


[-- Attachment #1.5: 0004-python-build-system-Look-up-the-interpreter-in-input.patch --]
[-- Type: text/x-patch, Size: 1872 bytes --]

From 852d494e3b59f8ea0e7e4fd7ef5f4f4e8fff06c6 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Tue, 1 Jun 2021 21:48:44 +0200
Subject: [PATCH 04/18] python-build-system: Look up the interpreter in
 'inputs'.

* guix/build/python-build-system.scm (wrap): Pass the shell
  interpreter from 'inputs' to 'wrap-program' using 'search-input-file'.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/python-build-system.scm | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/guix/build/python-build-system.scm b/guix/build/python-build-system.scm
index 5b1339d14c..08871f60cd 100644
--- a/guix/build/python-build-system.scm
+++ b/guix/build/python-build-system.scm
@@ -10,6 +10,7 @@
 ;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
 ;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2021 Lars-Dominik Braun <lars@6xq.net>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -234,12 +235,18 @@ running checks after installing the package."
                          (string-append dir "/sbin"))))
                 outputs))
 
+  ;; Do not require "bash" to be present in the package inputs
+  ;; even when there is nothing to wrap.
+  ;; Also, calculate (sh) only once to prevent some I/O.
+  (define %sh (delay (search-input-file inputs "bin/bash")))
+  (define (sh) (force %sh))
+
   (let* ((var `("GUIX_PYTHONPATH" prefix
                 ,(search-path-as-string->list
                   (or (getenv "GUIX_PYTHONPATH") "")))))
     (for-each (lambda (dir)
                 (let ((files (list-of-files dir)))
-                  (for-each (cut wrap-program <> var)
+                  (for-each (cut wrap-program <> #:sh (sh) var)
                             files)))
               bindirs)))
 
-- 
2.31.1


[-- Attachment #1.6: 0005-qt-build-system-Look-up-the-interpreter-in-inputs.patch --]
[-- Type: text/x-patch, Size: 1919 bytes --]

From 0fd271eb0a955eb693ce86d4312f60b74f875908 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:20:12 +0200
Subject: [PATCH 05/18] qt-build-system: Look up the interpreter in 'inputs'.

* guix/build/qt-build-system.scm (wrap-all-programs): Pass
  the shell interpreter from 'inputs' to 'wrap-program' using
  'search-input-file'.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/qt-build-system.scm | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/guix/build/qt-build-system.scm b/guix/build/qt-build-system.scm
index 762fd8a2ee..ec7ceb38bd 100644
--- a/guix/build/qt-build-system.scm
+++ b/guix/build/qt-build-system.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2014, 2015, 2021 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2018 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2019, 2020 Hartmut Goebel <h.goebel@crazy-compilers.com>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -126,6 +127,12 @@ add a dependency of that output on Qt."
            (((_ . dir) ...)
             dir)))
 
+  ;; Do not require bash to be present in the package inputs
+  ;; even when there is nothing to wrap.
+  ;; Also, calculate (sh) only once to prevent some I/O.
+  (define %sh (delay (search-input-file inputs "bin/bash")))
+  (define (sh) (force %sh))
+
   (define handle-output
     (match-lambda
      ((output . directory)
@@ -135,7 +142,7 @@ add a dependency of that output on Qt."
                              (append (list directory)
                                      input-directories))))
           (when (not (null? vars-to-wrap))
-            (for-each (cut apply wrap-program <> vars-to-wrap)
+            (for-each (cut apply wrap-program <> #:sh (sh) vars-to-wrap)
                       bin-list)))))))
 
   (for-each handle-output outputs)
-- 
2.31.1


[-- Attachment #1.7: 0006-rakudo-build-system-Look-up-the-interpreter-in-input.patch --]
[-- Type: text/x-patch, Size: 1846 bytes --]

From f7fb5c8a4e65965c7f7ce15a81782a89d1f3ec80 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:21:16 +0200
Subject: [PATCH 06/18] rakudo-build-system: Look up the interpreter in
 'inputs'.

* guix/build/rakudo-build-system.scm (wrap): Pass
  the shell interpreter from 'inputs' to 'wrap-program' using
  'search-input-file'.

Partially-Fixes: <https://issues.guix.gnu.org/47869>
---
 guix/build/rakudo-build-system.scm | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/guix/build/rakudo-build-system.scm b/guix/build/rakudo-build-system.scm
index b2c090f946..5cf1cc55bc 100644
--- a/guix/build/rakudo-build-system.scm
+++ b/guix/build/rakudo-build-system.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2021 Maxime Devos <maximedevos@telenet.be>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -108,6 +109,12 @@
                         (string-append dir "/sbin"))))
                 outputs))
 
+  ;; Do not require bash to be present in the package inputs
+  ;; even when there is nothing to wrap.
+  ;; Also, calculate (sh) only once to prevent some I/O.
+  (define %sh (delay (search-input-file inputs "bin/bash")))
+  (define (sh) (force %sh))
+
   (let* ((out  (assoc-ref outputs "out"))
          (var `("PERL6LIB" "," prefix
                 ,(cons (string-append out "/share/perl6/lib,"
@@ -117,7 +124,7 @@
                         (or (getenv "PERL6LIB") "") #\,)))))
     (for-each (lambda (dir)
                 (let ((files (list-of-files dir)))
-                  (for-each (cut wrap-program <> var)
+                  (for-each (cut wrap-program <> #:sh (sh) var)
                             files)))
               bindirs)
     #t))
-- 
2.31.1


[-- Attachment #1.8: 0007-gnu-carla-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1331 bytes --]

From 45d3f442dbf855619f19d4d6591585279bf1e846 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:41:22 +0200
Subject: [PATCH 07/18] gnu: carla: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/audio.scm
  (carla)[arguments]<#:phases>{wrap-executables}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/audio.scm | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/audio.scm b/gnu/packages/audio.scm
index f677d46a7f..930c111d5e 100644
--- a/gnu/packages/audio.scm
+++ b/gnu/packages/audio.scm
@@ -4711,9 +4711,10 @@ as is the case with audio plugins.")
                (chmod (string-append out "/share/carla/carla") #o555)
                #t)))
          (add-after 'install 'wrap-executables
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((out (assoc-ref outputs "out")))
                (wrap-script (string-append out "/bin/carla")
+                            #:guile (search-input-file inputs "bin/guile")
                             `("GUIX_PYTHONPATH" ":" prefix (,(getenv "GUIX_PYTHONPATH"))))
                #t))))))
     (inputs
-- 
2.31.1


[-- Attachment #1.9: 0008-gnu-bats-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1068 bytes --]

From 045b440056a699f872cf258568612734b617cb36 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:42:58 +0200
Subject: [PATCH 08/18] gnu: bats: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bash.scm
  (bats)[arguments]<#:builder>: Set #:guile argument
  of ‘wrap-script’.
---
 gnu/packages/bash.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/bash.scm b/gnu/packages/bash.scm
index 8dfbd7834e..7e98367bbb 100644
--- a/gnu/packages/bash.scm
+++ b/gnu/packages/bash.scm
@@ -402,6 +402,7 @@ capturing.")
          ;; Install phase
          (invoke "./install.sh" %output)
          (wrap-script (string-append %output "/bin/bats")
+                      #:guile (search-input-file %build-inputs "bin/guile")
                       (list "PATH" 'prefix (string-split (getenv "PATH")
                                                          #\:))))))
     (build-system trivial-build-system)
-- 
2.31.1


[-- Attachment #1.10: 0009-gnu-proteinortho-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1586 bytes --]

From 6d2cf56697d1bbced16a7ce4ef34304ddbbf73a7 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:46:22 +0200
Subject: [PATCH 09/18] gnu: proteinortho: Set #:guile argument of
 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bioinformatics.scm
  (proteinortho)[arguments]<#:phases>{wrap-programs}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/bioinformatics.scm | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 85f785955e..7d8496e692 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -5447,9 +5447,11 @@ predicts the locations of structural units in the sequences.")
          (add-after 'install 'wrap-programs
            (lambda* (#:key inputs outputs #:allow-other-keys)
              (let ((path (getenv "PATH"))
-                   (out (assoc-ref outputs "out")))
+                   (out (assoc-ref outputs "out"))
+                   (guile (search-input-file inputs "bin/guile")))
                (for-each (lambda (script)
-                           (wrap-script script `("PATH" ":" prefix (,path))))
+                           (wrap-script script #:guile guile
+                                        `("PATH" ":" prefix (,path))))
                          (cons (string-append out "/bin/proteinortho")
                                (find-files out "\\.(pl|py)$"))))
              #t)))))
-- 
2.31.1


[-- Attachment #1.11: 0010-gnu-prinseq-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1805 bytes --]

From 8363e0e350ee482cb4d14743371c933f5e9d8163 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:48:19 +0200
Subject: [PATCH 10/18] gnu: prinseq: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bioinformatics.scm
  (prinseq)[arguments]<#:phases>{install}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/bioinformatics.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 7d8496e692..37483984ec 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -7557,7 +7557,8 @@ experience substantial biological insertions and deletions.")
            (lambda* (#:key outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin"))
-                    (scripts (find-files "." "prinseq.*.pl")))
+                    (scripts (find-files "." "prinseq.*.pl"))
+                    (guile (search-input-file "bin/guile")))
                (substitute* scripts
                  (("\"perl -pe")
                   (string-append "\"" (which "perl") " -pe")))
@@ -7565,6 +7566,7 @@ experience substantial biological insertions and deletions.")
                            (chmod file #o555)
                            (install-file file bin)
                            (wrap-script (string-append bin "/" (basename file))
+                                        #:guile guile
                                         `("PERL5LIB" ":" prefix
                                           (,(getenv "PERL5LIB")))))
                          scripts)))))))
-- 
2.31.1


[-- Attachment #1.12: 0011-gnu-gess-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1607 bytes --]

From 398d1ef1a0d547b23a4972ecc619b2c70d908aa9 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:50:07 +0200
Subject: [PATCH 11/18] gnu: gess: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bioinformatics.scm
  (gess)[arguments]<#:phases>{install}
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/bioinformatics.scm | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 37483984ec..965e26b812 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -7554,7 +7554,7 @@ experience substantial biological insertions and deletions.")
          (delete 'configure)
          (delete 'build)
          (replace 'install
-           (lambda* (#:key outputs #:allow-other-keys)
+           (lambda* (#:key inputs outputs #:allow-other-keys)
              (let* ((out (assoc-ref outputs "out"))
                     (bin (string-append out "/bin"))
                     (scripts (find-files "." "prinseq.*.pl"))
@@ -10239,6 +10239,7 @@ matplotlib.use('Agg')
 " line)))
                ;; Make sure GESS has all modules in its path
                (wrap-script (string-append target "GESS.py")
+                 #:guile (search-input-file inputs "bin/guile")
                  `("GUIX_PYTHONPATH" ":" = (,target ,(getenv "GUIX_PYTHONPATH"))))
                (mkdir-p bin)
                (symlink (string-append target "GESS.py")
-- 
2.31.1


[-- Attachment #1.13: 0012-gnu-nanopolish-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 2081 bytes --]

From afa806033297984b129a8c430a8e6f0e89693368 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:54:49 +0200
Subject: [PATCH 12/18] gnu: nanopolish: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/bioinformatics.scm
  (nanopolish)[arguments]<#:phases>{wrap-programs}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/bioinformatics.scm | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 965e26b812..fc2fc867ac 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -13583,16 +13583,18 @@ choosing which reads pass the filter.")
                            (find-files "scripts" ".*"))
                  #t)))
            (add-after 'install 'wrap-programs
-             (lambda* (#:key outputs #:allow-other-keys)
+             (lambda* (#:key inputs outputs #:allow-other-keys)
                (let ((pythonpath (getenv "GUIX_PYTHONPATH"))
                      (perl5lib (getenv "PERL5LIB"))
                      (scripts (string-append (assoc-ref outputs "out")
-                                             "/share/nanopolish/scripts")))
+                                             "/share/nanopolish/scripts"))
+                     (guile (search-input-file inputs "bin/guile")))
                  (for-each (lambda (file)
                              (wrap-program file `("GUIX_PYTHONPATH" ":" prefix (,pythonpath))))
                            (find-files scripts "\\.py"))
                  (for-each (lambda (file)
-                             (wrap-script file `("PERL5LIB" ":" prefix (,perl5lib))))
+                             (wrap-script file #:guile guile
+                                          `("PERL5LIB" ":" prefix (,perl5lib))))
                            (find-files scripts "\\.pl"))))))))
       (inputs
        `(("guile" ,guile-3.0) ; for wrappers
-- 
2.31.1


[-- Attachment #1.14: 0013-gnu-sieve-connect-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1043 bytes --]

From 12671858d0b145b7c40440621c628b624f2df7fd Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 19:58:53 +0200
Subject: [PATCH 13/18] gnu: sieve-connect: Set #:guile argument of
 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/mail.scm
  (sieve-connect)[arguments]<#:phases>{wrap-program}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/mail.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/mail.scm b/gnu/packages/mail.scm
index a885e2417c..7aed1aa5bd 100644
--- a/gnu/packages/mail.scm
+++ b/gnu/packages/mail.scm
@@ -2924,6 +2924,7 @@ transfer protocols.")
              (let ((out (assoc-ref outputs "out"))
                    (path (getenv "PERL5LIB")))
                (wrap-script (string-append out "/bin/sieve-connect")
+                 #:guile (search-input-file inputs "bin/guile")
                  `("PERL5LIB" ":" = (,path)))
                #t))))))
     (inputs
-- 
2.31.1


[-- Attachment #1.15: 0014-gnu-clipmenu-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1515 bytes --]

From 39d88a8d1cd801d119056efac7b93ca2883caf2c Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:04:30 +0200
Subject: [PATCH 14/18] gnu: clipmenu: Set #:guile argument of 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/xdisorg.scm
  (clipmenu)[arguments]<#:phases>{wrap-script}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/xdisorg.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/xdisorg.scm b/gnu/packages/xdisorg.scm
index de2cba8e57..d339851f51 100644
--- a/gnu/packages/xdisorg.scm
+++ b/gnu/packages/xdisorg.scm
@@ -2555,10 +2555,12 @@ tools to complement clipnotify.")
                       (gawk              (assoc-ref inputs "gawk"))
                       (util-linux        (assoc-ref inputs "util-linux"))
                       (xdotool           (assoc-ref inputs "xdotool"))
-                      (xsel              (assoc-ref inputs "xsel")))
+                      (xsel              (assoc-ref inputs "xsel"))
+                      (guile             (search-input-file inputs "bin/guile")))
                  (for-each
                   (lambda (prog)
                     (wrap-script (string-append out "/bin/" prog)
+                      #:guile guile
                       `("PATH" ":" prefix
                         ,(map (lambda (dir)
                                 (string-append dir "/bin"))
-- 
2.31.1


[-- Attachment #1.16: 0015-gnu-vpnc-scripts-Set-guile-argument-of-wrap-script.patch --]
[-- Type: text/x-patch, Size: 1522 bytes --]

From cc868239ba629f2046cdb0e27e294ac11bc8cb30 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:06:12 +0200
Subject: [PATCH 15/18] gnu: vpnc-scripts: Set #:guile argument of
 'wrap-script'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/vpn.scm
  (vpnc-scripts)[arguments]<#:phases>{wrap-scripts}:
  Set #:guile argument of ‘wrap-script’.
---
 gnu/packages/vpn.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index a952e3f0db..33ef87c52d 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -192,10 +192,12 @@ Only \"Universal TUN/TAP device driver support\" is needed in the kernel.")
              ;; Wrap scripts with paths to their common hard dependencies.
              ;; Optional dependencies will need to be installed by the user.
              (lambda* (#:key inputs outputs #:allow-other-keys)
-               (let ((out (assoc-ref outputs "out")))
+               (let ((out (assoc-ref outputs "out"))
+                     (guile (search-input-file inputs "bin/guile")))
                  (for-each
                   (lambda (script)
                     (wrap-script (string-append out "/etc/vpnc/" script)
+                      #:guile guile
                       `("PATH" ":" prefix
                         ,(map (lambda (name)
                                 (let ((input (assoc-ref inputs name)))
-- 
2.31.1


[-- Attachment #1.17: 0016-gnu-openconnect-sso-Set-sh-argument-of-wrap-program.patch --]
[-- Type: text/x-patch, Size: 1079 bytes --]

From 97746bc3bee9bf8c8a74c8d278567a819a14265c Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:09:45 +0200
Subject: [PATCH 16/18] gnu: openconnect-sso: Set #:sh argument of
 'wrap-program'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/vpn.scm
  (openconnect-sso)[arguments]<#:phases>{wrap-qt-process-path}
  Set #:sh argument of ‘wrap-program’.
---
 gnu/packages/vpn.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index 33ef87c52d..584ff0ec84 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -326,6 +326,7 @@ and probably others.")
                                        (assoc-ref inputs "qtwebengine")
                                        "/lib/qt5/libexec/QtWebEngineProcess")))
                (wrap-program bin
+                 #:sh (search-input-file inputs "bin/bash")
                  `("QTWEBENGINEPROCESS_PATH" = (,qt-process-path)))
                #t))))))
     (inputs
-- 
2.31.1


[-- Attachment #1.18: 0017-gnu-protonvpn-cli-Set-sh-argument-of-wrap-program.patch --]
[-- Type: text/x-patch, Size: 1196 bytes --]

From 429de9acb1e79e621b6d4da18cde816eef63ada8 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:11:50 +0200
Subject: [PATCH 17/18] gnu: protonvpn-cli: Set #:sh argument of
 'wrap-program'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/vpn.scm
  (protonvpn-cli)[arguments]<#:phases>{wrap-wrapper}:
  Set #:sh argument of ‘wrap-program’.
---
 gnu/packages/vpn.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index 584ff0ec84..66c103e75f 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -440,6 +440,7 @@ traversing network address translators (@dfn{NAT}s) and firewalls.")
              (let ((entrypoint (string-append (assoc-ref outputs "out")
                                               "/bin/.protonvpn-real")))
                (wrap-program entrypoint
+                            #:sh (search-input-file inputs "bin/bash")
                             `("PATH" ":" prefix
                               ,(map (lambda (name)
                                       (let ((input (assoc-ref inputs name)))
-- 
2.31.1


[-- Attachment #1.19: 0018-gnu-wireguard-tools-Set-sh-argument-of-wrap-program.patch --]
[-- Type: text/x-patch, Size: 1141 bytes --]

From 00a73e18e1b62ec525a44cbe890843f1c93b9d16 Mon Sep 17 00:00:00 2001
From: Maxime Devos <maximedevos@telenet.be>
Date: Mon, 31 May 2021 20:12:55 +0200
Subject: [PATCH 18/18] gnu: wireguard-tools: Set #:sh argument of
 'wrap-program'.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* gnu/packages/vpn.scm
  (wireguard-tools)[arguments]<#:phases>{wrap-wg-quick}:
  Set #:sh argument of ‘wrap-program’.
---
 gnu/packages/vpn.scm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gnu/packages/vpn.scm b/gnu/packages/vpn.scm
index 66c103e75f..34715a4cc8 100644
--- a/gnu/packages/vpn.scm
+++ b/gnu/packages/vpn.scm
@@ -726,6 +726,7 @@ WireGuard was added to Linux 5.6.")
                    (coreutils (string-append (assoc-ref inputs "coreutils")
                                              "/bin")))
                (wrap-program (string-append out "/bin/wg-quick")
+                 #:sh (search-input-file inputs "bin/bash")
                  `("PATH" ":" prefix ,(append inputs-sbin
                                               (list coreutils))))
                #t))))))
-- 
2.31.1


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 260 bytes --]

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* bug#47869: [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling
  2021-06-02  7:56   ` [bug#47869] [PATCH v4 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
@ 2021-06-04 21:31     ` Ludovic Courtès
  0 siblings, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2021-06-04 21:31 UTC (permalink / raw)
  To: Maxime Devos; +Cc: 47869-done

Hi Maxime,

Maxime Devos <maximedevos@telenet.be> skribis:

> This is version 4 of the patch series.
> It lets 'search-input-file' raise the new
> &search-error exception instead of misc-error.
>
> The documentation of 'search-input-file' has been
> adjusted to give an example of how it can be used.
>
> Also, there is one new test in tests/build-utils.scm
> ("search-input-file: can search in multiple directories").

I pushed the whole series as d1827d5c636adb395153a4ed6064629ed5b7664b:

  d1827d5c63 * gnu: wireguard-tools: Set #:sh argument of 'wrap-program'.
  96a2ae40fb * gnu: protonvpn-cli: Set #:sh argument of 'wrap-program'.
  b74085ce36 * gnu: openconnect-sso: Set #:sh argument of 'wrap-program'.
  3bbb0ec888 * gnu: vpnc-scripts: Set #:guile argument of 'wrap-script'.
  a4e38cc216 * gnu: clipmenu: Set #:guile argument of 'wrap-script'.
  0758ee8002 * gnu: sieve-connect: Set #:guile argument of 'wrap-script'.
  b2459387b9 * gnu: nanopolish: Set #:guile argument of 'wrap-script'.
  2d092a2afa * gnu: gess: Set #:guile argument of 'wrap-script'.
  c4989f7569 * gnu: prinseq: Set #:guile argument of 'wrap-script'.
  fadbac0ecc * gnu: proteinortho: Set #:guile argument of 'wrap-script'.
  b202fdf131 * gnu: bats: Set #:guile argument of 'wrap-script'.
  0a843e3643 * gnu: carla: Set #:guile argument of 'wrap-script'.
  a62d17dc05 * rakudo-build-system: Look up the interpreter in 'inputs'.
  2ac898d7f8 * qt-build-system: Look up the interpreter in 'inputs'.
  5b24cbee31 * python-build-system: Look up the interpreter in 'inputs'.
  1dbc3b2b0c * glib-or-gtk-build-system: Look up the interpreter in 'inputs'.
  5378edeab4 * utils: Define ‘search-input-file’ procedure.
  8b0899963f * utils: Allow overriding the shell interpreter in ‘wrap-program’.

Thank you!

Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-06-04 21:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-18 11:20 [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Maxime Devos
2021-04-19 19:04 ` [bug#47869] [PATCH v2 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
2021-05-18 20:51   ` [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès
2021-05-18 21:25     ` Maxime Devos
2021-05-29 14:50       ` Ludovic Courtès
2021-06-01 19:53   ` [bug#47869] [PATCH v3 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
2021-06-01 21:01     ` [bug#47869] [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès
2021-06-02  7:56   ` [bug#47869] [PATCH v4 core-updates] various cross-compilation fixes in guix/build/utils.scm Maxime Devos
2021-06-04 21:31     ` bug#47869: [PATCH core-updates] ‘which’ looks in PATH, incorrect when cross-compiling Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).