diff options
author | Ludovic Courtès <ludovic.courtes@inria.fr> | 2022-05-10 16:39:18 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2022-05-13 17:04:22 +0200 |
commit | c99c3d11cdb05a2efc0950f0a50bfcb3fbbba2c7 (patch) | |
tree | 8d958d50370b89fb13f3dd4cc7fc19ecf106598c | |
parent | 7f7cc042083a759f9b136761f8f9f95ed87563ed (diff) | |
download | guix-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.texi | 347 |
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 |