Next: Build Systems, Previous: Defining Package Variants, Up: Programming Interface [Contents][Index]
guix
commands let you specify package lists on the command
line. This is convenient, but as the command line becomes longer and
less trivial, it quickly becomes more convenient to have that package
list in what we call a manifest. A manifest is some sort of a
“bill of materials” that defines a package set. You would typically
come up with a code snippet that builds the manifest, store it in a
file, say manifest.scm, and then pass that file to the
-m (or --manifest) option that many guix
commands support. For example, here’s what a manifest for a simple
package set might look like:
;; Manifest for three packages. (specifications->manifest '("gcc-toolchain" "make" "git"))
Once you have that manifest, you can pass it, for example, to
guix package
to install just those three packages to your
profile (see -m option of guix
package
):
guix package -m manifest.scm
... or you can pass it to guix shell
(see -m
option of guix shell
) to spawn an ephemeral
environment:
guix shell -m manifest.scm
... or you can pass it to guix pack
in pretty much the same
way (see -m option of guix pack
).
You can store the manifest under version control, share it with others
so they can easily get set up, etc.
But how do you write your first manifest? To get started, maybe you’ll
want to write a manifest that mirrors what you already have in a
profile. Rather than start from a blank page, guix package
can generate a manifest for you (see guix
package --export-manifest
):
# Write to 'manifest.scm' a manifest corresponding to the # default profile, ~/.guix-profile. guix package --export-manifest > manifest.scm
Or maybe you’ll want to “translate” command-line arguments into a
manifest. In that case, guix shell
can help
(see guix shell --export-manifest
):
# Write a manifest for the packages specified on the command line. guix shell --export-manifest gcc-toolchain make git > manifest.scm
In both cases, the --export-manifest option tries hard to generate a faithful manifest; in particular, it takes package transformation options into account (see Package Transformation Options).
Note: Manifests are symbolic: they refer to packages of the channels currently in use (see Channels). In the example above,
gcc-toolchain
might refer to version 11 today, but it might refer to version 13 two years from now.If you want to “pin” your software environment to specific package versions and variants, you need an additional piece of information: the list of channel revisions in use, as returned by
guix describe
. See Replicating Guix, for more information.
Once you’ve obtained your first manifest, perhaps you’ll want to customize it. Since your manifest is code, you now have access to all the Guix programming interfaces!
Let’s assume you want a manifest to deploy a custom variant of GDB, the GNU Debugger, that does not depend on Guile, together with another package. Building on the example seen in the previous section (see Defining Package Variants), you can write a manifest along these lines:
(use-modules (guix packages) (gnu packages gdb) ;for 'gdb' (gnu packages version-control)) ;for 'git' ;; Define a variant of GDB without a dependency on Guile. (define gdb-sans-guile (package (inherit gdb) (inputs (modify-inputs (package-inputs gdb) (delete "guile"))))) ;; Return a manifest containing that one package plus Git. (packages->manifest (list gdb-sans-guile git))
Note that in this example, the manifest directly refers to the
gdb
and git
variables, which are bound to a package
object (see package
Reference), instead of calling
specifications->manifest
to look up packages by name as we did
before. The use-modules
form at the top lets us access the core
package interface (see Defining Packages) and the modules that
define gdb
and git
(see Package Modules). Seamlessly,
we’re weaving all this together—the possibilities are endless, unleash
your creativity!
The data type for manifests as well as supporting procedures are defined
in the (guix profiles)
module, which is automatically available
to code passed to -m. The reference follows.
Data type representing a manifest.
It currently has one field:
entries
This must be a list of manifest-entry
records—see below.
Data type representing a manifest entry. A manifest entry contains essential metadata: a name and version string, the object (usually a package) for that entry, the desired output (see Packages with Multiple Outputs), and a number of optional pieces of information detailed below.
Most of the time, you won’t build a manifest entry directly; instead,
you will pass a package to package->manifest-entry
, described
below. In some unusual cases though, you might want to create manifest
entries for things that are not packages, as in this example:
;; Manually build a single manifest entry for a non-package object. (let ((hello (program-file "hello" #~(display "Hi!")))) (manifest-entry (name "foo") (version "42") (item (computed-file "hello-directory" #~(let ((bin (string-append #$output "/bin"))) (mkdir #$output) (mkdir bin) (symlink #$hello (string-append bin "/hello")))))))
The available fields are the following:
name
version
Name and version string for this entry.
item
A package or other file-like object (see file-like objects).
output
(default: "out"
)Output of item
to use, in case item
has multiple outputs
(see Packages with Multiple Outputs).
dependencies
(default: '()
)List of manifest entries this entry depends on. When building a profile, dependencies are added to the profile.
Typically, the propagated inputs of a package (see propagated-inputs
) end up having a corresponding manifest entry
in among the dependencies of the package’s own manifest entry.
search-paths
(default: '()
)The list of search path specifications honored by this entry (see Search Paths).
properties
(default: '()
)List of symbol/value pairs. When building a profile, those properties get serialized.
This can be used to piggyback additional metadata—e.g., the transformations applied to a package (see Package Transformation Options).
parent
(default: (delay #f)
)A promise pointing to the “parent” manifest entry.
This is used as a hint to provide context when reporting an error
related to a manifest entry coming from a dependencies
field.
Concatenate the manifests listed in lst and return the resulting manifest.
Return a manifest entry for the output of package package,
where output defaults to "out"
, and with the given
properties. By default properties is the empty list or, if
one or more package transformations were applied to package, it is
an association list representing those transformations, suitable as an
argument to options->transformation
(see options->transformation
).
The code snippet below builds a manifest with an entry for the default
output and the send-email
output of the git
package:
(use-modules (gnu packages version-control)) (manifest (list (package->manifest-entry git) (package->manifest-entry git "send-email")))
Return a list of manifest entries, one for each item listed in packages. Elements of packages can be either package objects or package/string tuples denoting a specific output of a package.
Using this procedure, the manifest above may be rewritten more concisely:
(use-modules (gnu packages version-control)) (packages->manifest (list git `(,git "send-email")))
Return a manifest for the development inputs of package for system, optionally when cross-compiling to target. Development inputs include both explicit and implicit inputs of package.
Like the -D option of guix shell
(see guix shell -D
), the
resulting manifest describes the environment in which one can develop
package. For example, suppose you’re willing to set up a
development environment for Inkscape, with the addition of Git for
version control; you can describe that “bill of materials” with the
following manifest:
(use-modules (gnu packages inkscape) ;for 'inkscape' (gnu packages version-control)) ;for 'git' (concatenate-manifests (list (package->development-manifest inkscape) (packages->manifest (list git))))
In this example, the development manifest that
package->development-manifest
returns includes the compiler
(GCC), the many supporting libraries (Boost, GLib, GTK, etc.), and a
couple of additional development tools—these are the dependencies
guix show inkscape
lists.
Last, the (gnu packages)
module provides higher-level facilities
to build manifests. In particular, it lets you look up packages by
name—see below.
Given specs, a list of specifications such as "emacs@25.2"
or "guile:debug"
, return a manifest. Specs have the format that
command-line tools such as guix install
and guix
package
understand (see Invoking guix package
).
As an example, it lets you rewrite the Git manifest that we saw earlier like this:
(specifications->manifest '("git" "git:send-email"))
Notice that we do not need to worry about use-modules
, importing
the right set of modules, and referring to the right variables.
Instead, we directly refer to packages in the same way as on the command
line, which can often be more convenient.
Next: Build Systems, Previous: Defining Package Variants, Up: Programming Interface [Contents][Index]