Skip to content
Snippets Groups Projects
guix.texi 1.04 MiB
Newer Older
  • Learn to ignore specific revisions
  •    (make-channel-introduction
        "6f0d8cc0d88abb59c324b2990bfee2876016bb86"
        (openpgp-fingerprint
         "CABB A931 C0FF EEC6 900D  0CFB 090B 1199 3D9A EBB5"))))
    @end lisp
    
    The specification above shows the name and URL of the channel.  The call
    to @code{make-channel-introduction} above specifies that authentication
    of this channel starts at commit @code{6f0d8cc@dots{}}, which is signed
    by the OpenPGP key with fingerprint @code{CABB A931@dots{}}.
    
    For the main channel, called @code{guix}, you automatically get that
    information from your Guix installation.  For other channels, include
    the channel introduction provided by the channel authors in your
    @file{channels.scm} file.  Make sure you retrieve the channel
    introduction from a trusted source since that is the root of your trust.
    
    If you're curious about the authentication mechanics, read on!
    
    @subsection Using a Custom Guix Channel
    
    The channel called @code{guix} specifies where Guix itself---its command-line
    tools as well as its package collection---should be downloaded.  For instance,
    suppose you want to update from your own copy of the Guix repository at
    @code{example.org}, and specifically the @code{super-hacks} branch, you can
    write in @code{~/.config/guix/channels.scm} this specification:
    
    @lisp
    ;; Tell 'guix pull' to use my own repo.
    (list (channel
            (name 'guix)
            (url "https://example.org/my-guix.git")
            (branch "super-hacks")))
    @end lisp
    
    From there on, @command{guix pull} will fetch code from the @code{super-hacks}
    branch of the repository at @code{example.org}.
    
    @subsection Specifying Additional Channels
    
    @cindex extending the package collection (channels)
    @cindex personal packages (channels)
    @cindex channels, for personal packages
    You can also specify @emph{additional channels} to pull from.  Let's say you
    have a bunch of custom package variants or personal packages that you think
    would make little sense to contribute to the Guix project, but would like to
    have these packages transparently available to you at the command line.  You
    would first write modules containing those package definitions (@pxref{Package
    Modules}), maintain them in a Git repository, and then you and anyone else can
    use it as an additional channel to get packages from.  Neat, no?
    
    @c What follows stems from discussions at
    @c <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=22629#134> as well as
    @c earlier discussions on guix-devel@gnu.org.
    @quotation Warning
    Before you, dear user, shout---``woow this is @emph{soooo coool}!''---and
    publish your personal channel to the world, we would like to share a few words
    of caution:
    
    @itemize
    @item
    Before publishing a channel, please consider contributing your package
    definitions to Guix proper (@pxref{Contributing}).  Guix as a project is open
    to free software of all sorts, and packages in Guix proper are readily
    available to all Guix users and benefit from the project's quality assurance
    process.
    
    @item
    When you maintain package definitions outside Guix, we, Guix developers,
    consider that @emph{the compatibility burden is on you}.  Remember that
    package modules and package definitions are just Scheme code that uses various
    programming interfaces (APIs).  We want to remain free to change these APIs to
    keep improving Guix, possibly in ways that break your channel.  We never
    change APIs gratuitously, but we will @emph{not} commit to freezing APIs
    either.
    
    @item
    Corollary: if you're using an external channel and that channel breaks, please
    @emph{report the issue to the channel authors}, not to the Guix project.
    @end itemize
    
    You've been warned!  Having said this, we believe external channels are a
    practical way to exert your freedom to augment Guix' package collection and to
    share your improvements, which are basic tenets of
    @uref{https://www.gnu.org/philosophy/free-sw.html, free software}.  Please
    email us at @email{guix-devel@@gnu.org} if you'd like to discuss this.
    @end quotation
    
    To use a channel, write @code{~/.config/guix/channels.scm} to instruct
    @command{guix pull} to pull from it @emph{in addition} to the default Guix
    
    @vindex %default-channels
    @lisp
    ;; Add my personal packages to those Guix provides.
    (cons (channel
            (name 'my-personal-packages)
            (url "https://example.org/personal-packages.git"))
          %default-channels)
    @end lisp
    
    @noindent
    Note that the snippet above is (as always!)@: Scheme code; we use @code{cons} to
    add a channel the list of channels that the variable @code{%default-channels}
    is bound to (@pxref{Pairs, @code{cons} and lists,, guile, GNU Guile Reference
    Manual}).  With this file in place, @command{guix pull} builds not only Guix
    but also the package modules from your own repository.  The result in
    @file{~/.config/guix/current} is the union of Guix with your own package
    modules:
    
    $ guix pull --list-generations
    @dots{}
    Generation 19	Aug 27 2018 16:20:48
      guix d894ab8
        repository URL: https://git.savannah.gnu.org/git/guix.git
        branch: master
        commit: d894ab8e9bfabcefa6c49d9ba2e834dd5a73a300
      my-personal-packages dd3df5e
        repository URL: https://example.org/personal-packages.git
        branch: master
        commit: dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb
      11 new packages: my-gimp, my-emacs-with-cool-features, @dots{}
      4 packages upgraded: emacs-racket-mode@@0.0.2-2.1b78827, @dots{}
    
    @noindent
    The output of @command{guix pull} above shows that Generation@tie{}19 includes
    both Guix and packages from the @code{my-personal-packages} channel.  Among
    the new and upgraded packages that are listed, some like @code{my-gimp} and
    @code{my-emacs-with-cool-features} might come from
    @code{my-personal-packages}, while others come from the Guix default channel.
    
    To create a channel, create a Git repository containing your own package
    modules and make it available.  The repository can contain anything, but a
    useful channel will contain Guile modules that export packages.  Once you
    start using a channel, Guix will behave as if the root directory of that
    channel's Git repository has been added to the Guile load path (@pxref{Load
    Paths,,, guile, GNU Guile Reference Manual}).  For example, if your channel
    contains a file at @file{my-packages/my-tools.scm} that defines a Guile
    module, then the module will be available under the name @code{(my-packages
    my-tools)}, and you will be able to use it like any other module
    (@pxref{Modules,,, guile, GNU Guile Reference Manual}).
    
    
    @cindex dependencies, channels
    @cindex meta-data, channels
    @subsection Declaring Channel Dependencies
    
    Channel authors may decide to augment a package collection provided by other
    channels.  They can declare their channel to be dependent on other channels in
    a meta-data file @file{.guix-channel}, which is to be placed in the root of
    the channel repository.
    
    The meta-data file should contain a simple S-expression like this:
    
    @lisp
    (channel
     (version 0)
     (dependencies
      (channel
       (name some-collection)
       (url "https://example.org/first-collection.git"))
      (channel
       (name some-other-collection)
       (url "https://example.org/second-collection.git")
       (branch "testing"))))
    @end lisp
    
    In the above example this channel is declared to depend on two other channels,
    which will both be fetched automatically.  The modules provided by the channel
    will be compiled in an environment where the modules of all these declared
    channels are available.
    
    For the sake of reliability and maintainability, you should avoid dependencies
    on channels that you don't control, and you should aim to keep the number of
    dependencies to a minimum.
    
    @cindex subdirectory, channels
    @subsection Package Modules in a Sub-directory
    
    As a channel author, you may want to keep your channel modules in a
    sub-directory.  If your modules are in the sub-directory @file{guix}, you must
    add a meta-data file @file{.guix-channel} that contains:
    
    @lisp
    (channel
      (version 0)
      (directory "guix"))
    @end lisp
    
    
    @cindex channel authorizations
    @subsection Specifying 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.
    
    To summarize, as the author of a channel, there are two things you have
    to do to allow users to authenticate your code:
    
    @enumerate
    @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
    
    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 primary URL, channels
    @subsection Primary URL
    
    Channel authors can indicate the primary URL of their channel's Git
    repository in the @file{.guix-channel} file, like so:
    
    @lisp
    (channel
      (version 0)
      (url "https://example.org/guix.git"))
    @end lisp
    
    This allows @command{guix pull} to determine whether it is pulling code
    from a mirror of the channel; when that is the case, it warns the user
    that the mirror might be stale and displays the primary URL.  That way,
    users cannot be tricked into fetching code from a stale mirror that does
    not receive security updates.
    
    This feature only makes sense for authenticated repositories, such as
    the official @code{guix} channel, for which @command{guix pull} ensures
    the code it fetches is authentic.
    
    
    @cindex news, for channels
    @subsection 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
    
    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:
    
    @example
    xgettext -o news.po -l scheme -ken etc/news.scm
    @end example
    
    To sum up, yes, you could use your channel as a blog.  But beware, this
    is @emph{not quite} what your users might expect.
    
    
    @cindex pinning, channels
    @cindex replicating Guix
    @cindex reproducibility, of Guix
    The @command{guix pull --list-generations} output above shows precisely which
    commits were used to build this instance of Guix.  We can thus replicate it,
    say, on another machine, by providing a channel specification in
    @file{~/.config/guix/channels.scm} that is ``pinned'' to these commits:
    
    @lisp
    ;; Deploy specific commits of my channels of interest.
    (list (channel
           (name 'guix)
           (url "https://git.savannah.gnu.org/git/guix.git")
           (commit "d894ab8e9bfabcefa6c49d9ba2e834dd5a73a300"))
          (channel
           (name 'my-personal-packages)
           (url "https://example.org/personal-packages.git")
    
           (commit "dd3df5e2c8818760a8fc0bd699e55d3b69fef2bb")))
    
    The @command{guix describe --format=channels} command can even generate this
    
    Konrad Hinsen's avatar
    Konrad Hinsen committed
    list of channels directly (@pxref{Invoking guix describe}).  The resulting
    file can be used with the -C options of @command{guix pull}
    (@pxref{Invoking guix pull}) or @command{guix time-machine}
    (@pxref{Invoking guix time-machine}).
    
    At this point the two machines run the @emph{exact same Guix}, with access to
    the @emph{exact same packages}.  The output of @command{guix build gimp} on
    one machine will be exactly the same, bit for bit, as the output of the same
    command on the other machine.  It also means both machines have access to all
    the source code of Guix and, transitively, to all the source code of every
    package it defines.
    
    This gives you super powers, allowing you to track the provenance of binary
    artifacts with very fine grain, and to reproduce software environments at
    will---some sort of ``meta reproducibility'' capabilities, if you will.
    @xref{Inferiors}, for another way to take advantage of these super powers.
    
    Konrad Hinsen's avatar
    Konrad Hinsen committed
    @node Invoking guix time-machine
    @section Invoking @command{guix time-machine}
    
    @cindex @command{guix time-machine}
    @cindex pinning, channels
    @cindex replicating Guix
    @cindex reproducibility, of Guix
    
    The @command{guix time-machine} command provides access to other
    revisions of Guix, for example to install older versions of packages,
    or to reproduce a computation in an identical environment.  The revision
    of Guix to be used is defined by a commit or by a channel
    description file created by @command{guix describe}
    (@pxref{Invoking guix describe}).
    
    The general syntax is:
    
    @example
    guix time-machine @var{options}@dots{} -- @var{command} @var {arg}@dots{}
    @end example
    
    where @var{command} and @var{arg}@dots{} are passed unmodified to the
    
    Naga Malleswari's avatar
    Naga Malleswari committed
    @command{guix} command of the specified revision.  The @var{options} that define
    
    Konrad Hinsen's avatar
    Konrad Hinsen committed
    this revision are the same as for @command{guix pull} (@pxref{Invoking guix pull}):
    
    @table @code
    @item --url=@var{url}
    @itemx --commit=@var{commit}
    @itemx --branch=@var{branch}
    Use the @code{guix} channel from the specified @var{url}, at the
    given @var{commit} (a valid Git commit ID represented as a hexadecimal
    string), or @var{branch}.
    
    @item --channels=@var{file}
    @itemx -C @var{file}
    Read the list of channels from @var{file}.  @var{file} must contain
    Scheme code that evaluates to a list of channel objects.
    @xref{Channels} for more information.
    @end table
    
    As for @command{guix pull}, the absence of any options means that the
    the latest commit on the master branch will be used. The command
    
    @example
    guix time-machine -- build hello
    @end example
    
    will thus build the package @code{hello} as defined in the master branch,
    
    Eric Bavier's avatar
    Eric Bavier committed
    which is in general a newer revision of Guix than you have installed.
    
    Konrad Hinsen's avatar
    Konrad Hinsen committed
    Time travel works in both directions!
    
    
    Note that @command{guix time-machine} can trigger builds of channels and
    their dependencies, and these are controlled by the standard build
    options (@pxref{Common Build Options}).
    
    
    @c TODO: Remove this once we're more confident about API stability.
    @quotation Note
    The functionality described here is a ``technology preview'' as of version
    @value{VERSION}.  As such, the interface is subject to change.
    @end quotation
    
    @cindex inferiors
    @cindex composition of Guix revisions
    Sometimes you might need to mix packages from the revision of Guix you're
    currently running with packages available in a different revision of Guix.
    Guix @dfn{inferiors} allow you to achieve that by composing different Guix
    revisions in arbitrary ways.
    
    @cindex inferior packages
    Technically, an ``inferior'' is essentially a separate Guix process connected
    to your main Guix process through a REPL (@pxref{Invoking guix repl}).  The
    @code{(guix inferior)} module allows you to create inferiors and to
    communicate with them.  It also provides a high-level interface to browse and
    manipulate the packages that an inferior provides---@dfn{inferior packages}.
    
    When combined with channels (@pxref{Channels}), inferiors provide a simple way
    to interact with a separate revision of Guix.  For example, let's assume you
    want to install in your profile the current @code{guile} package, along with
    the @code{guile-json} as it existed in an older revision of Guix---perhaps
    because the newer @code{guile-json} has an incompatible API and you want to
    run your code against the old API@.  To do that, you could write a manifest for
    use by @code{guix package --manifest} (@pxref{Invoking guix package}); in that
    manifest, you would create an inferior for that old Guix revision you care
    about, and you would look up the @code{guile-json} package in the inferior:
    
    @lisp
    (use-modules (guix inferior) (guix channels)
                 (srfi srfi-1))   ;for 'first'
    
    (define channels
      ;; This is the old revision from which we want to
      ;; extract guile-json.
      (list (channel
             (name 'guix)
             (url "https://git.savannah.gnu.org/git/guix.git")
             (commit
              "65956ad3526ba09e1f7a40722c96c6ef7c0936fe"))))
    
    (define inferior
      ;; An inferior representing the above revision.
      (inferior-for-channels channels))
    
    ;; Now create a manifest with the current "guile" package
    ;; and the old "guile-json" package.
    (packages->manifest
     (list (first (lookup-inferior-packages inferior "guile-json"))
           (specification->package "guile")))
    @end lisp
    
    On its first run, @command{guix package --manifest} might have to build the
    channel you specified before it can create the inferior; subsequent runs will
    be much faster because the Guix revision will be cached.
    
    The @code{(guix inferior)} module provides the following procedures to open an
    inferior:
    
    @deffn {Scheme Procedure} inferior-for-channels @var{channels} @
       [#:cache-directory] [#:ttl]
    Return an inferior for @var{channels}, a list of channels.  Use the cache at
    @var{cache-directory}, where entries can be reclaimed after @var{ttl} seconds.
    This procedure opens a new connection to the build daemon.
    
    As a side effect, this procedure may build or substitute binaries for
    @var{channels}, which can take time.
    @end deffn
    
    @deffn {Scheme Procedure} open-inferior @var{directory} @
      [#:command "bin/guix"]
    Open the inferior Guix in @var{directory}, running
    @code{@var{directory}/@var{command} repl} or equivalent.  Return @code{#f} if
    the inferior could not be launched.
    @end deffn
    
    @cindex inferior packages
    The procedures listed below allow you to obtain and manipulate inferior
    packages.
    
    @deffn {Scheme Procedure} inferior-packages @var{inferior}
    Return the list of packages known to @var{inferior}.
    @end deffn
    
    @deffn {Scheme Procedure} lookup-inferior-packages @var{inferior} @var{name} @
       [@var{version}]
    Return the sorted list of inferior packages matching @var{name} in
    @var{inferior}, with highest version numbers first.  If @var{version} is true,
    return only packages with a version number prefixed by @var{version}.
    @end deffn
    
    @deffn {Scheme Procedure} inferior-package? @var{obj}
    Return true if @var{obj} is an inferior package.
    @end deffn
    
    @deffn {Scheme Procedure} inferior-package-name @var{package}
    @deffnx {Scheme Procedure} inferior-package-version @var{package}
    @deffnx {Scheme Procedure} inferior-package-synopsis @var{package}
    @deffnx {Scheme Procedure} inferior-package-description @var{package}
    @deffnx {Scheme Procedure} inferior-package-home-page @var{package}
    @deffnx {Scheme Procedure} inferior-package-location @var{package}
    @deffnx {Scheme Procedure} inferior-package-inputs @var{package}
    @deffnx {Scheme Procedure} inferior-package-native-inputs @var{package}
    @deffnx {Scheme Procedure} inferior-package-propagated-inputs @var{package}
    @deffnx {Scheme Procedure} inferior-package-transitive-propagated-inputs @var{package}
    @deffnx {Scheme Procedure} inferior-package-native-search-paths @var{package}
    @deffnx {Scheme Procedure} inferior-package-transitive-native-search-paths @var{package}
    @deffnx {Scheme Procedure} inferior-package-search-paths @var{package}
    These procedures are the counterpart of package record accessors
    (@pxref{package Reference}).  Most of them work by querying the inferior
    @var{package} comes from, so the inferior must still be live when you call
    these procedures.
    @end deffn
    
    Inferior packages can be used transparently like any other package or
    file-like object in G-expressions (@pxref{G-Expressions}).  They are also
    transparently handled by the @code{packages->manifest} procedure, which is
    commonly use in manifests (@pxref{Invoking guix package, the
    @option{--manifest} option of @command{guix package}}).  Thus you can insert
    an inferior package pretty much anywhere you would insert a regular package:
    in manifests, in the @code{packages} field of your @code{operating-system}
    declaration, and so on.
    
    @node Invoking guix describe
    @section Invoking @command{guix describe}
    
    @cindex reproducibility
    @cindex replicating Guix
    Often you may want to answer questions like: ``Which revision of Guix am I
    using?'' or ``Which channels am I using?''  This is useful information in many
    situations: if you want to @emph{replicate} an environment on a different
    machine or user account, if you want to report a bug or to determine what
    change in the channels you are using caused it, or if you want to record your
    system state for reproducibility purposes.  The @command{guix describe}
    command answers these questions.
    
    When run from a @command{guix pull}ed @command{guix}, @command{guix describe}
    displays the channel(s) that it was built from, including their repository URL
    and commit IDs (@pxref{Channels}):
    
    @example
    $ guix describe
    Generation 10	Sep 03 2018 17:32:44	(current)
      guix e0fa68c
        repository URL: https://git.savannah.gnu.org/git/guix.git
        branch: master
        commit: e0fa68c7718fffd33d81af415279d6ddb518f727
    @end example
    
    If you're familiar with the Git version control system, this is similar in
    spirit to @command{git describe}; the output is also similar to that of
    @command{guix pull --list-generations}, but limited to the current generation
    (@pxref{Invoking guix pull, the @option{--list-generations} option}).  Because
    the Git commit ID shown above unambiguously refers to a snapshot of Guix, this
    information is all it takes to describe the revision of Guix you're using, and
    also to replicate it.
    
    To make it easier to replicate Guix, @command{guix describe} can also be asked
    to return a list of channels instead of the human-readable description above:
    
    @example
    $ guix describe -f channels
    (list (channel
            (name 'guix)
            (url "https://git.savannah.gnu.org/git/guix.git")
            (commit
    
              "e0fa68c7718fffd33d81af415279d6ddb518f727")
            (introduction
              (make-channel-introduction
                "9edb3f66fd807b096b48283debdcddccfea34bad"
                (openpgp-fingerprint
                  "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA")))))
    
    @noindent
    You can save this to a file and feed it to @command{guix pull -C} on some
    other machine or at a later point in time, which will instantiate @emph{this
    exact Guix revision} (@pxref{Invoking guix pull, the @option{-C} option}).
    From there on, since you're able to deploy the same revision of Guix, you can
    just as well @emph{replicate a complete software environment}.  We humbly
    think that this is @emph{awesome}, and we hope you'll like it too!
    
    The details of the options supported by @command{guix describe} are as
    follows:
    
    @table @code
    @item --format=@var{format}
    @itemx -f @var{format}
    Produce output in the specified @var{format}, one of:
    
    @table @code
    @item human
    produce human-readable output;
    @item channels
    produce a list of channel specifications that can be passed to @command{guix
    pull -C} or installed as @file{~/.config/guix/channels.scm} (@pxref{Invoking
    guix pull});
    
    @item channels-sans-intro
    like @code{channels}, but omit the @code{introduction} field; use it to
    produce a channel specification suitable for Guix version 1.1.0 or
    earlier---the @code{introduction} field has to do with channel
    authentication (@pxref{Channels, Channel Authentication}) and is not
    supported by these older versions;
    
    @item json
    @cindex JSON
    produce a list of channel specifications in JSON format;
    @item recutils
    produce a list of channel specifications in Recutils format.
    @end table
    
    @item --list-formats
    Display available formats for @option{--format} option.
    
    
    @item --profile=@var{profile}
    @itemx -p @var{profile}
    Display information about @var{profile}.
    @end table
    
    @node Invoking guix archive
    @section Invoking @command{guix archive}
    
    @cindex @command{guix archive}
    @cindex archive
    The @command{guix archive} command allows users to @dfn{export} files
    from the store into a single archive, and to later @dfn{import} them on
    a machine that runs Guix.
    In particular, it allows store files to be transferred from one machine
    to the store on another machine.
    
    @quotation Note
    If you're looking for a way to produce archives in a format suitable for
    tools other than Guix, @pxref{Invoking guix pack}.
    @end quotation
    
    @cindex exporting store items
    To export store files as an archive to standard output, run:
    
    @example
    guix archive --export @var{options} @var{specifications}...
    @end example
    
    @var{specifications} may be either store file names or package
    specifications, as for @command{guix package} (@pxref{Invoking guix
    package}).  For instance, the following command creates an archive
    containing the @code{gui} output of the @code{git} package and the main
    output of @code{emacs}:
    
    @example
    guix archive --export git:gui /gnu/store/...-emacs-24.3 > great.nar
    @end example
    
    If the specified packages are not built yet, @command{guix archive}
    automatically builds them.  The build process may be controlled with the
    common build options (@pxref{Common Build Options}).
    
    To transfer the @code{emacs} package to a machine connected over SSH,
    one would run:
    
    @example
    guix archive --export -r emacs | ssh the-machine guix archive --import
    @end example
    
    @noindent
    Similarly, a complete user profile may be transferred from one machine
    to another like this:
    
    @example
    guix archive --export -r $(readlink -f ~/.guix-profile) | \
    
    Diego Nicola Barbato's avatar
    Diego Nicola Barbato committed
      ssh the-machine guix archive --import
    
    @noindent
    However, note that, in both examples, all of @code{emacs} and the
    profile as well as all of their dependencies are transferred (due to
    
    @option{-r}), regardless of what is already available in the store on
    the target machine.  The @option{--missing} option can help figure out
    which items are missing from the target store.  The @command{guix copy}
    
    command simplifies and optimizes this whole process, so this is probably
    what you should use in this case (@pxref{Invoking guix copy}).
    
    @cindex nar, archive format
    @cindex normalized archive (nar)
    Archives are stored in the ``normalized archive'' or ``nar'' format, which is
    comparable in spirit to `tar', but with differences
    that make it more appropriate for our purposes.  First, rather than
    recording all Unix metadata for each file, the nar format only mentions
    the file type (regular, directory, or symbolic link); Unix permissions
    and owner/group are dismissed.  Second, the order in which directory
    entries are stored always follows the order of file names according to
    the C locale collation order.  This makes archive production fully
    deterministic.
    
    When exporting, the daemon digitally signs the contents of the archive,
    and that digital signature is appended.  When importing, the daemon
    verifies the signature and rejects the import in case of an invalid
    signature or if the signing key is not authorized.
    @c FIXME: Add xref to daemon doc about signatures.
    
    zimoun's avatar
    zimoun committed
    Export the specified store files or packages (see below).  Write the
    
    resulting archive to the standard output.
    
    Dependencies are @emph{not} included in the output, unless
    
    @option{--recursive} is passed.
    
    When combined with @option{--export}, this instructs @command{guix archive}
    to include dependencies of the given items in the archive.  Thus, the
    resulting archive is self-contained: it contains the closure of the
    exported store items.
    
    @item --import
    Read an archive from the standard input, and import the files listed
    therein into the store.  Abort if the archive has an invalid digital
    signature, or if it is signed by a public key not among the authorized
    
    zimoun's avatar
    zimoun committed
    keys (see @option{--authorize} below).
    
    @item --missing
    Read a list of store file names from the standard input, one per line,
    and write on the standard output the subset of these files missing from
    the store.
    
    @item --generate-key[=@var{parameters}]
    @cindex signing, archives
    Generate a new key pair for the daemon.  This is a prerequisite before
    
    archives can be exported with @option{--export}.  Note that this
    operation usually takes time, because it needs to gather enough entropy
    to generate the key pair.
    
    The generated key pair is typically stored under @file{/etc/guix}, in
    @file{signing-key.pub} (public key) and @file{signing-key.sec} (private
    
    zimoun's avatar
    zimoun committed
    key, which must be kept secret).  When @var{parameters} is omitted,
    
    an ECDSA key using the Ed25519 curve is generated, or, for Libgcrypt
    versions before 1.6.0, it is a 4096-bit RSA key.
    Alternatively, @var{parameters} can specify
    @code{genkey} parameters suitable for Libgcrypt (@pxref{General
    public-key related Functions, @code{gcry_pk_genkey},, gcrypt, The
    Libgcrypt Reference Manual}).
    
    @item --authorize
    @cindex authorizing, archives
    Authorize imports signed by the public key passed on standard input.
    The public key must be in ``s-expression advanced format''---i.e., the
    same format as the @file{signing-key.pub} file.
    
    The list of authorized keys is kept in the human-editable file
    @file{/etc/guix/acl}.  The file contains
    
    Marius Bakke's avatar
    Marius Bakke committed
    @url{https://people.csail.mit.edu/rivest/Sexp.txt, ``advanced-format
    
    s-expressions''} and is structured as an access-control list in the
    
    Marius Bakke's avatar
    Marius Bakke committed
    @url{https://theworld.com/~cme/spki.txt, Simple Public-Key Infrastructure
    
    @item --extract=@var{directory}
    @itemx -x @var{directory}
    Read a single-item archive as served by substitute servers
    (@pxref{Substitutes}) and extract it to @var{directory}.  This is a
    low-level operation needed in only very narrow use cases; see below.
    
    For example, the following command extracts the substitute for Emacs
    served by @code{@value{SUBSTITUTE-SERVER}} to @file{/tmp/emacs}:
    
      https://@value{SUBSTITUTE-SERVER}/nar/gzip/@dots{}-emacs-24.5 \
      | gunzip | guix archive -x /tmp/emacs
    
    Single-item archives are different from multiple-item archives produced
    by @command{guix archive --export}; they contain a single store item,
    and they do @emph{not} embed a signature.  Thus this operation does
    @emph{no} signature verification and its output should be considered
    unsafe.
    
    The primary purpose of this operation is to facilitate inspection of
    
    archive contents coming from possibly untrusted substitute servers
    (@pxref{Invoking guix challenge}).
    
    @item --list
    @itemx -t
    Read a single-item archive as served by substitute servers
    (@pxref{Substitutes}) and print the list of files it contains, as in
    this example:
    
    @example
    $ wget -O - \
      https://@value{SUBSTITUTE-SERVER}/nar/lzip/@dots{}-emacs-26.3 \
      | lzip -d | guix archive -t
    @end example
    
    
    @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.
    
    @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