aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludovic.courtes@inria.fr>2022-05-10 16:39:18 +0200
committerLudovic Courtès <ludo@gnu.org>2022-05-13 17:04:22 +0200
commitc99c3d11cdb05a2efc0950f0a50bfcb3fbbba2c7 (patch)
tree8d958d50370b89fb13f3dd4cc7fc19ecf106598c
parent7f7cc042083a759f9b136761f8f9f95ed87563ed (diff)
downloadguix-c99c3d11cdb05a2efc0950f0a50bfcb3fbbba2c7.tar
guix-c99c3d11cdb05a2efc0950f0a50bfcb3fbbba2c7.tar.gz
doc: Add "Writing Manifests" node.
* doc/guix.texi (Invoking guix package): Remove explanation of 'specifications->manifest' and 'package->development-manifest'. Link to "Writing Manifests". (Inferiors): Likewise. (Invoking guix shell): Add anchor and link to 'package->development-manifest'. (Invoking guix pack): Likewise. (Writing Manifests): New section. (Using TeX and LaTeX): Link to "Writing Manifests".
-rw-r--r--doc/guix.texi347
1 files changed, 320 insertions, 27 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index c168a66072..30cd56fcf3 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -279,6 +279,7 @@ Programming Interface
* Package Modules:: Packages from the programmer's viewpoint.
* Defining Packages:: Defining new packages.
* Defining Package Variants:: Customizing packages.
+* Writing Manifests:: The bill of materials of your environment.
* Build Systems:: Specifying how packages are built.
* Build Phases:: Phases of the build process of a package.
* Build Utilities:: Helpers for your package definitions and more.
@@ -3378,7 +3379,6 @@ commands. The advantage is that @var{file} can be put under version
control, copied to different machines to reproduce the same profile, and
so on.
-@c FIXME: Add reference to (guix profile) documentation when available.
@var{file} must return a @dfn{manifest} object, which is roughly a list
of packages:
@@ -3393,30 +3393,7 @@ of packages:
(list guile-2.0 "debug")))
@end lisp
-@findex specifications->manifest
-In this example we have to know which modules define the @code{emacs}
-and @code{guile-2.0} variables to provide the right
-@code{use-package-modules} line, which can be cumbersome. We can
-instead provide regular package specifications and let
-@code{specifications->manifest} look up the corresponding package
-objects, like this:
-
-@lisp
-(specifications->manifest
- '("emacs" "guile@@2.2" "guile@@2.2:debug"))
-@end lisp
-
-@findex package->development-manifest
-You might also want to create a manifest for all the dependencies of a
-package, rather than the package itself:
-
-@lisp
-(package->development-manifest (specification->package "emacs"))
-@end lisp
-
-The example above gives you all the software required to develop Emacs,
-similar to what @command{guix environment emacs} provides.
-
+@xref{Writing Manifests}, for information on how to write a manifest.
@xref{export-manifest, @option{--export-manifest}}, to learn how to
obtain a manifest file from an existing profile.
@@ -4711,7 +4688,7 @@ 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
+use by @code{guix package --manifest} (@pxref{Writing Manifests}); 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:
@@ -5783,6 +5760,7 @@ former is sourced only by log-in shells. @xref{Bash Startup Files,,,
bash, The GNU Bash Reference Manual}, for details on Bash start-up
files.
+@anchor{shell-development-option}
@item --development
@itemx -D
Cause @command{guix shell} to include in the environment the
@@ -5824,6 +5802,10 @@ To select other outputs, two element tuples can be specified:
guix shell -e '(list (@@ (gnu packages bash) bash) "include")'
@end example
+@xref{package-development-manifest,
+@code{package->development-manifest}}, for information on how to write a
+manifest for the development environment of a package.
+
@item --file=@var{file}
@itemx -f @var{file}
Create an environment containing the package or list of packages that
@@ -5843,6 +5825,7 @@ running:
guix shell -D -f gdb-devel.scm
@end example
+@anchor{shell-manifest}
@item --manifest=@var{file}
@itemx -m @var{file}
Create an environment for the packages contained in the manifest object
@@ -5853,6 +5836,7 @@ This is similar to the same-named option in @command{guix package}
(@pxref{profile-manifest, @option{--manifest}}) and uses the same
manifest files.
+@xref{Writing Manifests}, for information on how to write a manifest.
See @option{--export-manifest} below on how to obtain a first manifest.
@cindex manifest, exporting
@@ -6737,6 +6721,7 @@ This has the same purpose as the same-named option in @command{guix
build} (@pxref{Additional Build Options, @option{--expression} in
@command{guix build}}).
+@anchor{pack-manifest}
@item --manifest=@var{file}
@itemx -m @var{file}
Use the packages contained in the manifest object returned by the Scheme
@@ -6751,6 +6736,7 @@ 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.
+@xref{Writing Manifests}, for information on how to write a manifest.
@xref{shell-export-manifest, @command{guix shell --export-manifest}},
for information on how to ``convert'' command-line options into a
manifest.
@@ -6957,6 +6943,7 @@ package definitions.
* Package Modules:: Packages from the programmer's viewpoint.
* Defining Packages:: Defining new packages.
* Defining Package Variants:: Customizing packages.
+* Writing Manifests:: The bill of materials of your environment.
* Build Systems:: Specifying how packages are built.
* Build Phases:: Phases of the build process of a package.
* Build Utilities:: Helpers for your package definitions and more.
@@ -7962,6 +7949,312 @@ when @var{cut?} returns true for a given package. When @var{deep?} is true, @va
applied to implicit inputs as well.
@end deffn
+@node Writing Manifests
+@section Writing Manifests
+
+@cindex manifest
+@cindex bill of materials (manifests)
+@command{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 @dfn{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 @file{manifest.scm}, and then pass that file to the
+@option{-m} (or @option{--manifest}) option that many @command{guix}
+commands support. For example, here's what a manifest for a simple
+package set might look like:
+
+@lisp
+;; Manifest for three packages.
+(specifications->manifest '("gcc-toolchain" "make" "git"))
+@end lisp
+
+Once you have that manifest, you can pass it, for example, to
+@command{guix package} to install just those three packages to your
+profile (@pxref{profile-manifest, @option{-m} option of @command{guix
+package}}):
+
+@example
+guix package -m manifest.scm
+@end example
+
+@noindent
+... or you can pass it to @command{guix shell} (@pxref{shell-manifest,
+@command{-m} option of @command{guix shell}}) to spawn an ephemeral
+environment:
+
+@example
+guix shell -m manifest.scm
+@end example
+
+@noindent
+... or you can pass it to @command{guix pack} in pretty much the same
+way (@pxref{pack-manifest, @option{-m} option of @command{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, @command{guix package}
+can generate a manifest for you (@pxref{export-manifest, @command{guix
+package --export-manifest}}):
+
+@example
+# Write to 'manifest.scm' a manifest corresponding to the
+# default profile, ~/.guix-profile.
+guix package --export-manifest > manifest.scm
+@end example
+
+Or maybe you'll want to ``translate'' command-line arguments into a
+manifest. In that case, @command{guix shell} can help
+(@pxref{shell-export-manifest, @command{guix shell --export-manifest}}):
+
+@example
+# Write a manifest for the packages specified on the command line.
+guix shell --export-manifest gcc-toolchain make git > manifest.scm
+@end example
+
+In both cases, the @option{--export-manifest} option tries hard to
+generate a faithful manifest; in particular, it takes package
+transformation options into account (@pxref{Package Transformation
+Options}).
+
+@quotation Note
+Manifests are @emph{symbolic}: they refer to packages of the channels
+@emph{currently in use} (@pxref{Channels}). In the example above,
+@code{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 @command{guix
+describe}. @xref{Replicating Guix}, for more information.
+@end quotation
+
+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
+(@pxref{Defining Package Variants}), you can write a manifest along
+these lines:
+
+@lisp
+(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))
+@end lisp
+
+Note that in this example, the manifest directly refers to the
+@code{gdb} and @code{git} variables, which are bound to a @code{package}
+object (@pxref{package Reference}), instead of calling
+@code{specifications->manifest} to look up packages by name as we did
+before. The @code{use-modules} form at the top lets us access the core
+package interface (@pxref{Defining Packages}) and the modules that
+define @code{gdb} and @code{git} (@pxref{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 @code{(guix profiles)} module, which is automatically available
+to code passed to @option{-m}. The reference follows.
+
+@deftp {Data Type} manifest
+Data type representing a manifest.
+
+It currently has one field:
+
+@table @code
+@item entries
+This must be a list of @code{manifest-entry} records---see below.
+@end table
+@end deftp
+
+@deftp {Data Type} manifest-entry
+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 (@pxref{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 @code{package->manifest-entry}, described
+below. In some unusual cases though, you might want to create manifest
+entries for things that are @emph{not} packages, as in this example:
+
+@lisp
+;; 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")))))))
+@end lisp
+
+The available fields are the following:
+
+@table @asis
+@item @code{name}
+@itemx @code{version}
+Name and version string for this entry.
+
+@item @code{item}
+A package or other file-like object (@pxref{G-Expressions, file-like
+objects}).
+
+@item @code{output} (default: @code{"out"})
+Output of @code{item} to use, in case @code{item} has multiple outputs
+(@pxref{Packages with Multiple Outputs}).
+
+@item @code{dependencies} (default: @code{'()})
+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 (@pxref{package Reference,
+@code{propagated-inputs}}) end up having a corresponding manifest entry
+in among the dependencies of the package's own manifest entry.
+
+@item @code{search-paths} (default: @code{'()})
+The list of search path specifications honored by this entry
+(@pxref{Search Paths}).
+
+@item @code{properties} (default: @code{'()})
+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 (@pxref{Package Transformation
+Options}).
+
+@item @code{parent} (default: @code{(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 @code{dependencies} field.
+@end table
+@end deftp
+
+@deffn {Scheme Procedure} concatenate-manifests @var{lst}
+Concatenate the manifests listed in @var{lst} and return the resulting
+manifest.
+@end deffn
+
+@c TODO: <manifest-pattern>, manifest-lookup, manifest-remove, etc.
+
+@deffn {Scheme Procedure} package->manifest-entry @var{package} @
+ [@var{output}] [#:properties]
+Return a manifest entry for the @var{output} of package @var{package},
+where @var{output} defaults to @code{"out"}, and with the given
+@var{properties}. By default @var{properties} is the empty list or, if
+one or more package transformations were applied to @var{package}, it is
+an association list representing those transformations, suitable as an
+argument to @code{options->transformation} (@pxref{Defining Package
+Variants, @code{options->transformation}}).
+
+The code snippet below builds a manifest with an entry for the default
+output and the @code{send-email} output of the @code{git} package:
+
+@lisp
+(use-modules (gnu packages version-control))
+
+(manifest (list (package->manifest-entry git)
+ (package->manifest-entry git "send-email")))
+@end lisp
+@end deffn
+
+@deffn {Scheme Procedure} packages->manifest @var{packages}
+Return a list of manifest entries, one for each item listed in
+@var{packages}. Elements of @var{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:
+
+@lisp
+(use-modules (gnu packages version-control))
+
+(packages->manifest (list git `(,git "send-email")))
+@end lisp
+@end deffn
+
+@anchor{package-development-manifest}
+@deffn {Scheme Procedure} package->development-manifest @var{package} @
+ [@var{system}] [#:target]
+Return a manifest for the @dfn{development inputs} of @var{package} for
+@var{system}, optionally when cross-compiling to @var{target}.
+Development inputs include both explicit and implicit inputs of
+@var{package}.
+
+Like the @option{-D} option of @command{guix shell}
+(@pxref{shell-development-option, @command{guix shell -D}}), the
+resulting manifest describes the environment in which one can develop
+@var{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:
+
+@lisp
+(use-modules (gnu packages inkscape) ;for 'inkscape'
+ (gnu packages version-control)) ;for 'git'
+
+(concatenate-manifests
+ (list (package->development-manifest inkscape)
+ (packages->manifest (list git))))
+@end lisp
+
+In this example, the development manifest that
+@code{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
+@command{guix show inkscape} lists.
+@end deffn
+
+@c TODO: Move (gnu packages) interface to a section of its own.
+
+Last, the @code{(gnu packages)} module provides higher-level facilities
+to build manifests. In particular, it lets you look up packages by
+name---see below.
+
+@deffn {Scheme Procedure} specifications->manifest @var{specs}
+Given @var{specs}, a list of specifications such as @code{"emacs@@25.2"}
+or @code{"guile:debug"}, return a manifest. Specs have the format that
+command-line tools such as @command{guix install} and @command{guix
+package} understand (@pxref{Invoking guix package}).
+
+As an example, it lets you rewrite the Git manifest that we saw earlier
+like this:
+
+@lisp
+(specifications->manifest '("git" "git:send-email"))
+@end lisp
+
+Notice that we do not need to worry about @code{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.
+@end deffn
+
+@c TODO: specifications->package, etc.
+
@node Build Systems
@section Build Systems
@@ -39388,7 +39681,7 @@ You can then pass it to any command with the @option{-m} option:
guix shell -m manifest.scm -- pdflatex doc.tex
@end example
-@xref{Invoking guix package, @option{--manifest}}, for more on
+@xref{Writing Manifests}, for more on
manifests. In the future, we plan to provide packages for @TeX{} Live
@dfn{collections}---``meta-packages'' such as @code{fontsrecommended},
@code{humanities}, or @code{langarabic} that provide the set of packages