Skip to content
Snippets Groups Projects
guix.texi 1.1 MiB
Newer Older
  • Learn to ignore specific revisions
  • @cindex channel authorizations
    @node Specifying Channel Authorizations
    @section Specifying Channel Authorizations
    
    @anchor{channel-authorizations}
    As we saw above, Guix ensures the source code it pulls from channels
    comes from authorized developers.  As a channel author, you need to
    specify the list of authorized developers in the
    @file{.guix-authorizations} file in the channel's Git repository.  The
    authentication rule is simple: each commit must be signed by a key
    listed in the @file{.guix-authorizations} file of its parent
    commit(s)@footnote{Git commits form a @dfn{directed acyclic graph}
    (DAG).  Each commit can have zero or more parents; ``regular'' commits
    have one parent and merge commits have two parent commits.  Read
    @uref{https://eagain.net/articles/git-for-computer-scientists/, @i{Git
    for Computer Scientists}} for a great overview.}  The
    @file{.guix-authorizations} file looks like this:
    
    @lisp
    ;; Example '.guix-authorizations' file.
    
    (authorizations
     (version 0)               ;current file format version
    
     (("AD17 A21E F8AE D8F1 CC02  DBD9 F8AE D8F1 765C 61E3"
       (name "alice"))
      ("2A39 3FFF 68F4 EF7A 3D29  12AF 68F4 EF7A 22FB B2D5"
       (name "bob"))
      ("CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"
       (name "charlie"))))
    @end lisp
    
    Each fingerprint is followed by optional key/value pairs, as in the
    example above.  Currently these key/value pairs are ignored.
    
    This authentication rule creates a chicken-and-egg issue: how do we
    authenticate the first commit?  Related to that: how do we deal with
    channels whose repository history contains unsigned commits and lack
    @file{.guix-authorizations}?  And how do we fork existing channels?
    
    @cindex channel introduction
    Channel introductions answer these questions by describing the first
    commit of a channel that should be authenticated.  The first time a
    channel is fetched with @command{guix pull} or @command{guix
    time-machine}, the command looks up the introductory commit and verifies
    that it is signed by the specified OpenPGP key.  From then on, it
    authenticates commits according to the rule above.
    
    Additionally, your channel must provide all the OpenPGP keys that were
    ever mentioned in @file{.guix-authorizations}, stored as @file{.key}
    files, which can be either binary or ``ASCII-armored''.  By default,
    those @file{.key} files are searched for in the branch named
    @code{keyring} but you can specify a different branch name in
    @code{.guix-channel} like so:
    
    @lisp
    (channel
      (version 0)
      (keyring-reference "my-keyring-branch"))
    @end lisp
    
    To summarize, as the author of a channel, there are three things you have
    to do to allow users to authenticate your code:
    
    @enumerate
    @item
    Export the OpenPGP keys of past and present committers with @command{gpg
    --export} and store them in @file{.key} files, by default in a branch
    named @code{keyring} (we recommend making it an @dfn{orphan branch}).
    
    @item
    Introduce an initial @file{.guix-authorizations} in the channel's
    repository.  Do that in a signed commit (@pxref{Commit Access}, for
    information on how to sign Git commits.)
    
    @item
    Advertise the channel introduction, for instance on your channel's web
    page.  The channel introduction, as we saw above, is the commit/key
    pair---i.e., the commit that introduced @file{.guix-authorizations}, and
    the fingerprint of the OpenPGP used to sign it.
    @end enumerate
    
    Before pushing to your public Git repository, you can run @command{guix
    git-authenticate} to verify that you did sign all the commits you are
    about to push with an authorized key:
    
    @example
    guix git authenticate @var{commit} @var{signer}
    @end example
    
    @noindent
    where @var{commit} and @var{signer} are your channel introduction.
    @xref{Invoking guix git authenticate}, for details.
    
    Publishing a signed channel requires discipline: any mistake, such as an
    unsigned commit or a commit signed by an unauthorized key, will prevent
    users from pulling from your channel---well, that's the whole point of
    authentication!  Pay attention to merges in particular: merge commits
    are considered authentic if and only if they are signed by a key present
    in the @file{.guix-authorizations} file of @emph{both} branches.
    
    @cindex news, for channels
    @node Writing Channel News
    @section Writing Channel News
    
    Channel authors may occasionally want to communicate to their users
    information about important changes in the channel.  You'd send them all
    an email, but that's not convenient.
    
    Instead, channels can provide a @dfn{news file}; when the channel users
    run @command{guix pull}, that news file is automatically read and
    @command{guix pull --news} can display the announcements that correspond
    to the new commits that have been pulled, if any.
    
    To do that, channel authors must first declare the name of the news file
    in their @file{.guix-channel} file:
    
    @lisp
    (channel
      (version 0)
      (news-file "etc/news.txt"))
    @end lisp
    
    The news file itself, @file{etc/news.txt} in this example, must look
    something like this:
    
    @lisp
    (channel-news
      (version 0)
      (entry (tag "the-bug-fix")
             (title (en "Fixed terrible bug")
                    (fr "Oh la la"))
             (body (en "@@emph@{Good news@}!  It's fixed!")
                   (eo "Certe ĝi pli bone funkcias nun!")))
      (entry (commit "bdcabe815cd28144a2d2b4bc3c5057b051fa9906")
             (title (en "Added a great package")
                    (ca "Què vol dir guix?"))
             (body (en "Don't miss the @@code@{hello@} package!"))))
    @end lisp
    
    While the news file is using the Scheme syntax, avoid naming it with a
    @file{.scm} extension or else it will get picked up when building the
    channel and yield an error since it is not a valid module.
    Alternatively, you can move the channel module to a subdirectory and
    store the news file in another directory.
    
    The file consists of a list of @dfn{news entries}.  Each entry is
    associated with a commit or tag: it describes changes made in this
    commit, possibly in preceding commits as well.  Users see entries only
    the first time they obtain the commit the entry refers to.
    
    The @code{title} field should be a one-line summary while @code{body}
    can be arbitrarily long, and both can contain Texinfo markup
    (@pxref{Overview,,, texinfo, GNU Texinfo}).  Both the title and body are
    a list of language tag/message tuples, which allows @command{guix pull}
    to display news in the language that corresponds to the user's locale.
    
    If you want to translate news using a gettext-based workflow, you can
    extract translatable strings with @command{xgettext} (@pxref{xgettext
    Invocation,,, gettext, GNU Gettext Utilities}).  For example, assuming
    you write news entries in English first, the command below creates a PO
    file containing the strings to translate:
    
    xgettext -o news.po -l scheme -ken etc/news.txt
    
    To sum up, yes, you could use your channel as a blog.  But beware, this
    is @emph{not quite} what your users might expect.
    
    @c *********************************************************************
    
    @node Development
    @chapter Development
    
    @cindex software development
    If you are a software developer, Guix provides tools that you should find
    helpful---independently of the language you're developing in.  This is what
    this chapter is about.
    
    The @command{guix environment} command provides a convenient way to set up
    @dfn{development environments} containing all the dependencies and tools
    necessary to work on the software package of your choice.  The @command{guix
    pack} command allows you to create @dfn{application bundles} that can be
    easily distributed to users who do not run Guix.
    
    * Invoking guix environment::   Setting up development environments.
    * Invoking guix pack::          Creating software bundles.
    * The GCC toolchain::           Working with languages supported by GCC.
    * Invoking guix git authenticate:: Authenticating Git repositories.
    
    @node Invoking guix environment
    @section Invoking @command{guix environment}
    
    @cindex reproducible build environments
    @cindex development environments
    @cindex @command{guix environment}
    @cindex environment, package build environment
    The purpose of @command{guix environment} is to assist hackers in
    creating reproducible development environments without polluting their
    package profile.  The @command{guix environment} tool takes one or more
    packages, builds all of their inputs, and creates a shell
    environment to use them.
    
    The general syntax is:
    
    @example
    guix environment @var{options} @var{package}@dots{}
    @end example
    
    The following example spawns a new shell set up for the development of
    GNU@tie{}Guile:
    
    @example
    guix environment guile
    @end example
    
    If the needed dependencies are not built yet, @command{guix environment}
    
    automatically builds them.  The environment of the new shell is an
    augmented version of the environment that @command{guix environment} was
    run in.  It contains the necessary search paths for building the given
    package added to the existing environment variables.  To create
    a ``pure'' environment, in which the original environment variables have
    been unset, use the @option{--pure} option@footnote{Users sometimes
    wrongfully augment environment variables such as @env{PATH} in their
    @file{~/.bashrc} file.  As a consequence, when @command{guix
    environment} launches it, Bash may read @file{~/.bashrc}, thereby
    introducing ``impurities'' in these environment variables.  It is an
    error to define such environment variables in @file{.bashrc}; instead,
    they should be defined in @file{.bash_profile}, which is sourced only by
    log-in shells.  @xref{Bash Startup Files,,, bash, The GNU Bash Reference
    Manual}, for details on Bash start-up files.}.
    
    @vindex GUIX_ENVIRONMENT
    
    @command{guix environment} defines the @env{GUIX_ENVIRONMENT}
    
    variable in the shell it spawns; its value is the file name of the
    profile of this environment.  This allows users to, say, define a
    specific prompt for development environments in their @file{.bashrc}
    (@pxref{Bash Startup Files,,, bash, The GNU Bash Reference Manual}):
    
    @example
    if [ -n "$GUIX_ENVIRONMENT" ]
    then
        export PS1="\u@@\h \w [dev]\$ "
    fi
    @end example
    
    @noindent
    ...@: or to browse the profile:
    
    @example
    $ ls "$GUIX_ENVIRONMENT/bin"
    @end example
    
    Additionally, more than one package may be specified, in which case the
    union of the inputs for the given packages are used.  For example, the
    command below spawns a shell where all of the dependencies of both Guile
    and Emacs are available:
    
    guix environment guile emacs
    @end example
    
    Sometimes an interactive shell session is not desired.  An arbitrary
    command may be invoked by placing the @code{--} token to separate the
    command from the rest of the arguments:
    
    @example
    guix environment guile -- make -j4
    
    In other situations, it is more convenient to specify the list of
    packages needed in the environment.  For example, the following command
    runs @command{python} from an environment containing Python@tie{}2.7 and
    NumPy:
    
    @example
    guix environment --ad-hoc python2-numpy python-2.7 -- python
    @end example
    
    Furthermore, one might want the dependencies of a package and also some
    additional packages that are not build-time or runtime dependencies, but
    are useful when developing nonetheless.  Because of this, the
    
    @option{--ad-hoc} flag is positional.  Packages appearing before
    @option{--ad-hoc} are interpreted as packages whose dependencies will be
    
    added to the environment.  Packages appearing after are interpreted as
    packages that will be added to the environment directly.  For example,
    the following command creates a Guix development environment that
    additionally includes Git and strace:
    
    guix environment --pure guix --ad-hoc git strace
    
    @end example
    
    Sometimes it is desirable to isolate the environment as much as
    possible, for maximal purity and reproducibility.  In particular, when
    using Guix on a host distro that is not Guix System, it is desirable to
    prevent access to @file{/usr/bin} and other system-wide resources from
    the development environment.  For example, the following command spawns
    a Guile REPL in a ``container'' where only the store and the current
    working directory are mounted:
    
    @example
    guix environment --ad-hoc --container guile -- guile
    @end example
    
    @quotation Note
    
    The @option{--container} option requires Linux-libre 3.19 or newer.
    
    @end quotation
    
    @cindex certificates
    Another typical use case for containers is to run security-sensitive
    applications such as a web browser.  To run Eolie, we must expose and
    share some files and directories; we include @code{nss-certs} and expose
    
    @file{/etc/ssl/certs/} for HTTPS authentication; finally we preserve the
    
    the @env{DISPLAY} environment variable since containerized graphical
    
    applications won't display without it.
    
    @example
    guix environment --preserve='^DISPLAY$' --container --network \
      --expose=/etc/machine-id \
      --expose=/etc/ssl/certs/ \
      --share=$HOME/.local/share/eolie/=$HOME/.local/share/eolie/ \
      --ad-hoc eolie nss-certs dbus --  eolie
    @end example
    
    
    The available options are summarized below.
    
    @table @code
    @item --root=@var{file}
    @itemx -r @var{file}
    @cindex persistent environment
    @cindex garbage collector root, for environments
    Make @var{file} a symlink to the profile for this environment, and
    register it as a garbage collector root.
    
    This is useful if you want to protect your environment from garbage
    collection, to make it ``persistent''.
    
    When this option is omitted, the environment is protected from garbage
    collection only for the duration of the @command{guix environment}
    session.  This means that next time you recreate the same environment,
    you could have to rebuild or re-download packages.  @xref{Invoking guix
    gc}, for more on GC roots.
    
    @item --expression=@var{expr}
    @itemx -e @var{expr}
    Create an environment for the package or list of packages that
    @var{expr} evaluates to.
    
    For example, running:
    
    @example
    guix environment -e '(@@ (gnu packages maths) petsc-openmpi)'
    @end example
    
    starts a shell with the environment for this specific variant of the
    PETSc package.
    
    @example
    guix environment --ad-hoc -e '(@@ (gnu) %base-packages)'
    @end example
    
    starts a shell with all the base system packages available.
    
    The above commands only use the default output of the given packages.
    To select other outputs, two element tuples can be specified:
    
    @example
    guix environment --ad-hoc -e '(list (@@ (gnu packages bash) bash) "include")'
    @end example
    
    @item --load=@var{file}
    @itemx -l @var{file}
    Create an environment for the package or list of packages that the code
    within @var{file} evaluates to.
    
    As an example, @var{file} might contain a definition like this
    (@pxref{Defining Packages}):
    
    @verbatiminclude environment-gdb.scm
    
    @item --manifest=@var{file}
    @itemx -m @var{file}
    Create an environment for the packages contained in the manifest object
    
    returned by the Scheme code in @var{file}.  This option can be repeated
    several times, in which case the manifests are concatenated.
    
    This is similar to the same-named option in @command{guix package}
    (@pxref{profile-manifest, @option{--manifest}}) and uses the same
    manifest files.
    
    @item --ad-hoc
    Include all specified packages in the resulting environment, as if an
    @i{ad hoc} package were defined with them as inputs.  This option is
    useful for quickly creating an environment without having to write a
    package expression to contain the desired inputs.
    
    For instance, the command:
    
    guix environment --ad-hoc guile guile-sdl -- guile
    
    runs @command{guile} in an environment where Guile and Guile-SDL are
    available.
    
    Note that this example implicitly asks for the default output of
    @code{guile} and @code{guile-sdl}, but it is possible to ask for a
    specific output---e.g., @code{glib:bin} asks for the @code{bin} output
    of @code{glib} (@pxref{Packages with Multiple Outputs}).
    
    This option may be composed with the default behavior of @command{guix
    
    environment}.  Packages appearing before @option{--ad-hoc} are
    interpreted as packages whose dependencies will be added to the
    environment, the default behavior.  Packages appearing after are
    interpreted as packages that will be added to the environment directly.
    
    @item --pure
    
    Unset existing environment variables when building the new environment, except
    
    zimoun's avatar
    zimoun committed
    those specified with @option{--preserve} (see below).  This has the effect of
    
    creating an environment in which search paths only contain package inputs.
    
    
    @item --preserve=@var{regexp}
    @itemx -E @var{regexp}
    When used alongside @option{--pure}, preserve the environment variables
    
    matching @var{regexp}---in other words, put them on a ``white list'' of
    
    environment variables that must be preserved.  This option can be repeated
    several times.
    
    guix environment --pure --preserve=^SLURM --ad-hoc openmpi @dots{} \
    
      -- mpirun @dots{}
    @end example
    
    This example runs @command{mpirun} in a context where the only environment
    
    variables defined are @env{PATH}, environment variables whose name starts
    with @samp{SLURM}, as well as the usual ``precious'' variables (@env{HOME},
    
    zimoun's avatar
    zimoun committed
    @env{USER}, etc.).
    
    @item --search-paths
    Display the environment variable definitions that make up the
    environment.
    
    @item --system=@var{system}
    @itemx -s @var{system}
    Attempt to build for @var{system}---e.g., @code{i686-linux}.
    
    @item --container
    @itemx -C
    @cindex container
    Run @var{command} within an isolated container.  The current working
    directory outside the container is mapped inside the container.
    
    Additionally, unless overridden with @option{--user}, a dummy home
    
    directory is created that matches the current user's home directory, and
    
    @file{/etc/passwd} is configured accordingly.
    
    The spawned process runs as the current user outside the container.  Inside
    the container, it has the same UID and GID as the current user, unless
    
    zimoun's avatar
    zimoun committed
    @option{--user} is passed (see below).
    
    @item --network
    @itemx -N
    For containers, share the network namespace with the host system.
    Containers created without this flag only have access to the loopback
    device.
    
    @item --link-profile
    @itemx -P
    
    For containers, link the environment profile to @file{~/.guix-profile}
    
    within the container and set @code{GUIX_ENVIRONMENT} to that.
    This is equivalent to making @file{~/.guix-profile} a symlink to the
    actual profile within the container.
    
    Linking will fail and abort the environment if the directory already
    exists, which will certainly be the case if @command{guix environment}
    was invoked in the user's home directory.
    
    Certain packages are configured to look in @file{~/.guix-profile} for
    configuration files and data;@footnote{For example, the
    @code{fontconfig} package inspects @file{~/.guix-profile/share/fonts}
    for additional fonts.}  @option{--link-profile} allows these programs to
    behave as expected within the environment.
    
    @item --user=@var{user}
    @itemx -u @var{user}
    For containers, use the username @var{user} in place of the current
    user.  The generated @file{/etc/passwd} entry within the container will
    
    contain the name @var{user}, the home directory will be
    @file{/home/@var{user}}, and no user GECOS data will be copied.  Furthermore,
    the UID and GID inside the container are 1000.  @var{user}
    
    need not exist on the system.
    
    Additionally, any shared or exposed path (see @option{--share} and
    @option{--expose} respectively) whose target is within the current user's
    
    home directory will be remapped relative to @file{/home/USER}; this
    includes the automatic mapping of the current working directory.
    
    # will expose paths as /home/foo/wd, /home/foo/test, and /home/foo/target
    cd $HOME/wd
    guix environment --container --user=foo \
         --expose=$HOME/test \
         --expose=/tmp/target=$HOME/target
    
    While this will limit the leaking of user identity through home paths
    and each of the user fields, this is only one useful component of a
    broader privacy/anonymity solution---not one in and of itself.
    
    @item --no-cwd
    For containers, the default behavior is to share the current working
    directory with the isolated container and immediately change to that
    
    directory within the container.  If this is undesirable,
    @option{--no-cwd} will cause the current working directory to @emph{not}
    be automatically shared and will change to the user's home directory
    within the container instead.  See also @option{--user}.
    
    @item --expose=@var{source}[=@var{target}]
    
    @itemx --share=@var{source}[=@var{target}]
    
    For containers, @option{--expose} (resp. @option{--share}) exposes the
    file system @var{source} from the host system as the read-only
    
    (resp. writable) file system @var{target} within the container.  If
    
    @var{target} is not specified, @var{source} is used as the target mount
    point in the container.
    
    The example below spawns a Guile REPL in a container in which the user's
    home directory is accessible read-only via the @file{/exchange}
    directory:
    
    @example
    guix environment --container --expose=$HOME=/exchange --ad-hoc guile -- guile
    @end example
    
    @command{guix environment}
    also supports all of the common build options that @command{guix
    build} supports (@pxref{Common Build Options}) as well as package
    transformation options (@pxref{Package Transformation Options}).
    
    @node Invoking guix pack
    @section Invoking @command{guix pack}
    
    Occasionally you want to pass software to people who are not (yet!)
    lucky enough to be using Guix.  You'd tell them to run @command{guix
    package -i @var{something}}, but that's not possible in this case.  This
    is where @command{guix pack} comes in.
    
    @quotation Note
    If you are looking for ways to exchange binaries among machines that
    already run Guix, @pxref{Invoking guix copy}, @ref{Invoking guix
    publish}, and @ref{Invoking guix archive}.
    @end quotation
    
    @cindex pack
    @cindex bundle
    @cindex application bundle
    @cindex software bundle
    The @command{guix pack} command creates a shrink-wrapped @dfn{pack} or
    @dfn{software bundle}: it creates a tarball or some other archive
    containing the binaries of the software you're interested in, and all
    its dependencies.  The resulting archive can be used on any machine that
    does not have Guix, and people can run the exact same binaries as those
    you have with Guix.  The pack itself is created in a bit-reproducible
    fashion, so anyone can verify that it really contains the build results
    that you pretend to be shipping.
    
    For example, to create a bundle containing Guile, Emacs, Geiser, and all
    their dependencies, you can run:
    
    @example
    $ guix pack guile emacs geiser
    @dots{}
    /gnu/store/@dots{}-pack.tar.gz
    @end example
    
    The result here is a tarball containing a @file{/gnu/store} directory
    with all the relevant packages.  The resulting tarball contains a
    @dfn{profile} with the three packages of interest; the profile is the
    same as would be created by @command{guix package -i}.  It is this
    mechanism that is used to create Guix's own standalone binary tarball
    (@pxref{Binary Installation}).
    
    Users of this pack would have to run
    @file{/gnu/store/@dots{}-profile/bin/guile} to run Guile, which you may
    find inconvenient.  To work around it, you can create, say, a
    @file{/opt/gnu/bin} symlink to the profile:
    
    @example
    guix pack -S /opt/gnu/bin=bin guile emacs geiser
    @end example
    
    @noindent
    That way, users can happily type @file{/opt/gnu/bin/guile} and enjoy.
    
    @cindex relocatable binaries, with @command{guix pack}
    What if the recipient of your pack does not have root privileges on
    their machine, and thus cannot unpack it in the root file system?  In
    
    that case, you will want to use the @option{--relocatable} option (see
    
    below).  This option produces @dfn{relocatable binaries}, meaning they
    they can be placed anywhere in the file system hierarchy: in the example
    above, users can unpack your tarball in their home directory and
    directly run @file{./opt/gnu/bin/guile}.
    
    @cindex Docker, build an image with guix pack
    Alternatively, you can produce a pack in the Docker image format using
    the following command:
    
    guix pack -f docker -S /bin=bin guile guile-readline
    
    @end example
    
    @noindent
    The result is a tarball that can be passed to the @command{docker load}
    
    command, followed by @code{docker run}:
    
    @example
    docker load < @var{file}
    docker run -ti guile-guile-readline /bin/guile
    @end example
    
    @noindent
    where @var{file} is the image returned by @var{guix pack}, and
    @code{guile-guile-readline} is its ``image tag''.  See the
    
    @uref{https://docs.docker.com/engine/reference/commandline/load/, Docker
    documentation} for more information.
    
    @cindex Singularity, build an image with guix pack
    @cindex SquashFS, build an image with guix pack
    Yet another option is to produce a SquashFS image with the following
    command:
    
    guix pack -f squashfs bash guile emacs geiser
    
    @noindent
    The result is a SquashFS file system image that can either be mounted or
    directly be used as a file system container image with the
    
    @uref{https://www.sylabs.io/docs/, Singularity container execution
    
    environment}, using commands like @command{singularity shell} or
    @command{singularity exec}.
    
    Several command-line options allow you to customize your pack:
    
    @table @code
    @item --format=@var{format}
    @itemx -f @var{format}
    Produce a pack in the given @var{format}.
    
    The available formats are:
    
    @table @code
    @item tarball
    This is the default format.  It produces a tarball containing all the
    specified binaries and symlinks.
    
    @item docker
    This produces a tarball that follows the
    @uref{https://github.com/docker/docker/blob/master/image/spec/v1.2.md,
    
    Docker Image Specification}.  The ``repository name'' as it appears in
    the output of the @command{docker images} command is computed from
    package names passed on the command line or in the manifest file.
    
    @item squashfs
    This produces a SquashFS image containing all the specified binaries and
    symlinks, as well as empty mount points for virtual file systems like
    procfs.
    
    
    @quotation Note
    Singularity @emph{requires} you to provide @file{/bin/sh} in the image.
    For that reason, @command{guix pack -f squashfs} always implies @code{-S
    /bin=bin}.  Thus, your @command{guix pack} invocation must always start
    with something like:
    
    @example
    guix pack -f squashfs bash @dots{}
    @end example
    
    If you forget the @code{bash} (or similar) package, @command{singularity
    run} and @command{singularity exec} will fail with an unhelpful ``no
    such file or directory'' message.
    @end quotation
    
    @cindex relocatable binaries
    
    @item --relocatable
    @itemx -R
    Produce @dfn{relocatable binaries}---i.e., binaries that can be placed
    
    anywhere in the file system hierarchy and run from there.
    
    When this option is passed once, the resulting binaries require support for
    @dfn{user namespaces} in the kernel Linux; when passed
    @emph{twice}@footnote{Here's a trick to memorize it: @code{-RR}, which adds
    PRoot support, can be thought of as the abbreviation of ``Really
    
    Relocatable''.  Neat, isn't it?}, relocatable binaries fall to back to
    other techniques if user namespaces are unavailable, and essentially
    work anywhere---see below for the implications.
    
    
    For example, if you create a pack containing Bash with:
    
    guix pack -RR -S /mybin=bin bash
    
    @end example
    
    @noindent
    ...@: you can copy that pack to a machine that lacks Guix, and from your
    home directory as a normal user, run:
    
    @example
    tar xf pack.tar.gz
    ./mybin/sh
    @end example
    
    @noindent
    In that shell, if you type @code{ls /gnu/store}, you'll notice that
    @file{/gnu/store} shows up and contains all the dependencies of
    @code{bash}, even though the machine actually lacks @file{/gnu/store}
    altogether!  That is probably the simplest way to deploy Guix-built
    software on a non-Guix machine.
    
    @quotation Note
    By default, relocatable binaries rely on the @dfn{user namespace} feature of
    the kernel Linux, which allows unprivileged users to mount or change root.
    Old versions of Linux did not support it, and some GNU/Linux distributions
    turn it off.
    
    To produce relocatable binaries that work even in the absence of user
    namespaces, pass @option{--relocatable} or @option{-R} @emph{twice}.  In that
    
    case, binaries will try user namespace support and fall back to another
    @dfn{execution engine} if user namespaces are not supported.  The
    following execution engines are supported:
    
    @table @code
    @item default
    Try user namespaces and fall back to PRoot if user namespaces are not
    supported (see below).
    
    
    @item performance
    Try user namespaces and fall back to Fakechroot if user namespaces are
    not supported (see below).
    
    
    @item userns
    Run the program through user namespaces and abort if they are not
    supported.
    
    @item proot
    Run through PRoot.  The @uref{https://proot-me.github.io/, PRoot} program
    provides the necessary
    
    support for file system virtualization.  It achieves that by using the
    @code{ptrace} system call on the running program.  This approach has the
    advantage to work without requiring special kernel support, but it incurs
    run-time overhead every time a system call is made.
    
    
    @item fakechroot
    Run through Fakechroot.  @uref{https://github.com/dex4er/fakechroot/,
    Fakechroot} virtualizes file system accesses by intercepting calls to C
    library functions such as @code{open}, @code{stat}, @code{exec}, and so
    on.  Unlike PRoot, it incurs very little overhead.  However, it does not
    always work: for example, some file system accesses made from within the
    C library are not intercepted, and file system accesses made @i{via}
    direct syscalls are not intercepted either, leading to erratic behavior.
    
    @end table
    
    @vindex GUIX_EXECUTION_ENGINE
    When running a wrapped program, you can explicitly request one of the
    execution engines listed above by setting the
    @code{GUIX_EXECUTION_ENGINE} environment variable accordingly.
    
    @cindex entry point, for Docker images
    @item --entry-point=@var{command}
    Use @var{command} as the @dfn{entry point} of the resulting pack, if the pack
    format supports it---currently @code{docker} and @code{squashfs} (Singularity)
    support it.  @var{command} must be relative to the profile contained in the
    pack.
    
    The entry point specifies the command that tools like @code{docker run} or
    @code{singularity run} automatically start by default.  For example, you can
    do:
    
    @example
    guix pack -f docker --entry-point=bin/guile guile
    @end example
    
    The resulting pack can easily be loaded and @code{docker run} with no extra
    arguments will spawn @code{bin/guile}:
    
    @example
    docker load -i pack.tar.gz
    docker run @var{image-id}
    @end example
    
    
    @item --expression=@var{expr}
    @itemx -e @var{expr}
    Consider the package @var{expr} evaluates to.
    
    This has the same purpose as the same-named option in @command{guix
    
    build} (@pxref{Additional Build Options, @option{--expression} in
    
    @command{guix build}}).
    
    @item --manifest=@var{file}
    @itemx -m @var{file}
    Use the packages contained in the manifest object returned by the Scheme
    
    code in @var{file}.  This option can be repeated several times, in which
    case the manifests are concatenated.
    
    This has a similar purpose as the same-named option in @command{guix
    package} (@pxref{profile-manifest, @option{--manifest}}) and uses the
    same manifest files.  It allows you to define a collection of packages
    once and use it both for creating profiles and for creating archives
    for use on machines that do not have Guix installed.  Note that you can
    specify @emph{either} a manifest file @emph{or} a list of packages,
    but not both.
    
    @item --system=@var{system}
    @itemx -s @var{system}
    Attempt to build for @var{system}---e.g., @code{i686-linux}---instead of
    the system type of the build host.
    
    @item --target=@var{triplet}
    @cindex cross-compilation
    Cross-build for @var{triplet}, which must be a valid GNU triplet, such
    
    as @code{"aarch64-linux-gnu"} (@pxref{Specifying target triplets, GNU
    
    configuration triplets,, autoconf, Autoconf}).
    
    @item --compression=@var{tool}
    @itemx -C @var{tool}
    Compress the resulting tarball using @var{tool}---one of @code{gzip},
    
    @code{zstd}, @code{bzip2}, @code{xz}, @code{lzip}, or @code{none} for no
    compression.
    
    @item --symlink=@var{spec}
    @itemx -S @var{spec}
    Add the symlinks specified by @var{spec} to the pack.  This option can
    appear several times.
    
    @var{spec} has the form @code{@var{source}=@var{target}}, where
    @var{source} is the symlink that will be created and @var{target} is the
    symlink target.
    
    For instance, @code{-S /opt/gnu/bin=bin} creates a @file{/opt/gnu/bin}
    symlink pointing to the @file{bin} sub-directory of the profile.
    
    @item --save-provenance
    Save provenance information for the packages passed on the command line.
    Provenance information includes the URL and commit of the channels in use
    (@pxref{Channels}).
    
    Provenance information is saved in the
    @file{/gnu/store/@dots{}-profile/manifest} file in the pack, along with the
    usual package metadata---the name and version of each package, their
    propagated inputs, and so on.  It is useful information to the recipient of
    the pack, who then knows how the pack was (supposedly) obtained.
    
    This option is not enabled by default because, like timestamps, provenance
    information contributes nothing to the build process.  In other words, there
    is an infinity of channel URLs and commit IDs that can lead to the same pack.
    Recording such ``silent'' metadata in the output thus potentially breaks the
    source-to-binary bitwise reproducibility property.
    
    
    Ludovic Courtès's avatar
    Ludovic Courtès committed
    @item --root=@var{file}
    @itemx -r @var{file}
    @cindex garbage collector root, for packs
    Make @var{file} a symlink to the resulting pack, and register it as a garbage
    collector root.
    
    
    @item --localstatedir
    @itemx --profile-name=@var{name}
    Include the ``local state directory'', @file{/var/guix}, in the resulting
    pack, and notably the @file{/var/guix/profiles/per-user/root/@var{name}}
    profile---by default @var{name} is @code{guix-profile}, which corresponds to
    @file{~root/.guix-profile}.
    
    @file{/var/guix} contains the store database (@pxref{The Store}) as well
    as garbage-collector roots (@pxref{Invoking guix gc}).  Providing it in
    the pack means that the store is ``complete'' and manageable by Guix;
    not providing it pack means that the store is ``dead'': items cannot be
    added to it or removed from it after extraction of the pack.
    
    One use case for this is the Guix self-contained binary tarball
    (@pxref{Binary Installation}).
    
    @item --derivation
    @itemx -d
    Print the name of the derivation that builds the pack.
    
    
    @item --bootstrap
    Use the bootstrap binaries to build the pack.  This option is only
    useful to Guix developers.
    
    In addition, @command{guix pack} supports all the common build options
    (@pxref{Common Build Options}) and all the package transformation
    options (@pxref{Package Transformation Options}).
    
    
    @node The GCC toolchain
    @section The GCC toolchain
    
    
    @cindex GCC
    @cindex ld-wrapper
    @cindex linker wrapper
    @cindex toolchain, for C development
    
    @cindex toolchain, for Fortran development
    
    
    If you need a complete toolchain for compiling and linking C or C++
    source code, use the @code{gcc-toolchain} package.  This package
    provides a complete GCC toolchain for C/C++ development, including GCC
    itself, the GNU C Library (headers and binaries, plus debugging symbols
    in the @code{debug} output), Binutils, and a linker wrapper.
    
    The wrapper's purpose is to inspect the @code{-L} and @code{-l} switches
    passed to the linker, add corresponding @code{-rpath} arguments, and
    invoke the actual linker with this new set of arguments.  You can instruct the
    wrapper to refuse to link against libraries not in the store by setting the
    
    @env{GUIX_LD_WRAPPER_ALLOW_IMPURITIES} environment variable to @code{no}.
    
    The package @code{gfortran-toolchain} provides a complete GCC toolchain
    for Fortran development.  For other languages, please use
    @samp{guix search gcc toolchain} (@pxref{guix-search,, Invoking guix package}).
    
    
    @node Invoking guix git authenticate
    @section Invoking @command{guix git authenticate}
    
    The @command{guix git authenticate} command authenticates a Git checkout
    following the same rule as for channels (@pxref{channel-authentication,
    channel authentication}).  That is, starting from a given commit, it
    ensures that all subsequent commits are signed by an OpenPGP key whose
    fingerprint appears in the @file{.guix-authorizations} file of its
    parent commit(s).
    
    You will find this command useful if you maintain a channel.  But in
    fact, this authentication mechanism is useful in a broader context, so
    you might want to use it for Git repositories that have nothing to do
    with Guix.
    
    The general syntax is:
    
    @example
    guix git authenticate @var{commit} @var{signer} [@var{options}@dots{}]
    @end example
    
    By default, this command authenticates the Git checkout in the current
    directory; it outputs nothing and exits with exit code zero on success
    and non-zero on failure.  @var{commit} above denotes the first commit
    where authentication takes place, and @var{signer} is the OpenPGP
    fingerprint of public key used to sign @var{commit}.  Together, they
    form a ``channel introduction'' (@pxref{channel-authentication, channel
    introduction}).  The options below allow you to fine-tune the process.
    
    @table @code
    @item --repository=@var{directory}
    @itemx -r @var{directory}
    Open the Git repository in @var{directory} instead of the current
    directory.
    
    @item --keyring=@var{reference}
    @itemx -k @var{reference}
    Load OpenPGP keyring from @var{reference}, the reference of a branch
    such as @code{origin/keyring} or @code{my-keyring}.  The branch must
    contain OpenPGP public keys in @file{.key} files, either in binary form
    or ``ASCII-armored''.  By default the keyring is loaded from the branch
    named @code{keyring}.
    
    @item --stats
    Display commit signing statistics upon completion.
    
    @item --cache-key=@var{key}
    Previously-authenticated commits are cached in a file under
    @file{~/.cache/guix/authentication}.  This option forces the cache to be
    stored in file @var{key} in that directory.
    
    @item --historical-authorizations=@var{file}
    By default, any commit whose parent commit(s) lack the
    @file{.guix-authorizations} file is considered inauthentic.  In
    contrast, this option considers the authorizations in @var{file} for any
    commit that lacks @file{.guix-authorizations}.  The format of @var{file}
    is the same as that of @file{.guix-authorizations}
    (@pxref{channel-authorizations, @file{.guix-authorizations} format}).
    @end table
    
    
    
    @c *********************************************************************
    @node Programming Interface
    @chapter Programming Interface
    
    GNU Guix provides several Scheme programming interfaces (APIs) to
    define, build, and query packages.  The first interface allows users to
    write high-level package definitions.  These definitions refer to
    familiar packaging concepts, such as the name and version of a package,
    its build system, and its dependencies.  These definitions can then be