summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2022-02-16 15:37:04 +0100
committerLudovic Courtès <ludo@gnu.org>2022-02-16 16:49:26 +0100
commitde65fd92d5724ace1cbc49f20ad49bffdc64d09d (patch)
tree5582563cc5f968b2f22bd871371980baa2fccc01
parentca155a20aea25003b03ef5e0420c77e416d5f425 (diff)
doc: Document 'wrap-program' and 'wrap-script'.
* doc/guix.texi (Build Utilities)[Wrappers]: New subsection.
-rw-r--r--doc/guix.texi84
1 files changed, 84 insertions, 0 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 039b418038..c8bb484d94 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -9506,6 +9506,90 @@ executable files to be installed:
@c TODO: Add more examples.
+@subsection Wrappers
+
+@cindex program wrappers
+@cindex wrapping programs
+It is not unusual for a command to require certain environment variables
+to be set for proper functioning, typically search paths (@pxref{Search
+Paths}). Failing to do that, the command might fail to find files or
+other commands it relies on, or it might pick the ``wrong''
+ones---depending on the environment in which it runs. Examples include:
+
+@itemize
+@item
+a shell script that assumes all the commands it uses are in @env{PATH};
+
+@item
+a Guile program that assumes all its modules are in @env{GUILE_LOAD_PATH}
+and @env{GUILE_LOAD_COMPILED_PATH};
+
+@item
+a Qt application that expects to find certain plugins in
+@env{QT_PLUGIN_PATH}.
+@end itemize
+
+For a package writer, the goal is to make sure commands always work the
+same rather than depend on some external settings. One way to achieve
+that is to @dfn{wrap} commands in a thin script that sets those
+environment variables, thereby ensuring that those run-time dependencies
+are always found. The wrapper would be used to set @env{PATH},
+@env{GUILE_LOAD_PATH}, or @env{QT_PLUGIN_PATH} in the examples above.
+
+To ease that task, the @code{(guix build utils)} module provides a
+couple of helpers to wrap commands.
+
+@deffn {Scheme Procedure} wrap-program @var{program} @
+ [#:sh @var{sh}] [#:rest @var{variables}]
+Make a wrapper for @var{program}. @var{variables} should look like this:
+
+@example
+'(@var{variable} @var{delimiter} @var{position} @var{list-of-directories})
+@end example
+
+where @var{delimiter} is optional. @code{:} will be used if
+@var{delimiter} is not given.
+
+For example, this call:
+
+@example
+(wrap-program "foo"
+ '("PATH" ":" = ("/gnu/.../bar/bin"))
+ '("CERT_PATH" suffix ("/gnu/.../baz/certs"
+ "/qux/certs")))
+@end example
+
+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
+
+If @var{program} has previously been wrapped by @code{wrap-program}, the
+wrapper is extended with definitions for @var{variables}. If it is not,
+@var{sh} will be used as the interpreter.
+@end deffn
+
+@deffn {Scheme Procedure} wrap-script @var{program} @
+ [#:guile @var{guile}] [#:rest @var{variables}]
+Wrap the script @var{program} such that @var{variables} are set first.
+The format of @var{variables} 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{program} 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
+
@node Search Paths
@section Search Paths