The high-level interface to package definitions is implemented in the
(guix packages) and
(guix build-system) modules. As an
example, the package definition, or recipe, for the GNU Hello
package looks like this:
(define-module (gnu packages hello) #:use-module (guix packages) #:use-module (guix download) #:use-module (guix build-system gnu) #:use-module (guix licenses) #:use-module (gnu packages gawk)) (define-public hello (package (name "hello") (version "2.10") (source (origin (method url-fetch) (uri (string-append "mirror://gnu/hello/hello-" version ".tar.gz")) (sha256 (base32 "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i")))) (build-system gnu-build-system) (arguments '(#:configure-flags '("--enable-silent-rules"))) (inputs `(("gawk" ,gawk))) (synopsis "Hello, GNU world: An example GNU package") (description "Guess what GNU Hello prints!") (home-page "https://www.gnu.org/software/hello/") (license gpl3+)))
Without being a Scheme expert, the reader may have guessed the meaning
of the various fields here. This expression binds the variable
hello to a
<package> object, which is essentially a record
(see Scheme records in GNU Guile Reference Manual).
This package object can be inspected using procedures found in the
(guix packages) module; for instance,
With luck, you may be able to import part or all of the definition of
the package you are interested in from another repository, using the
guix import command (see Invoking guix import).
In the example above, hello is defined in a module of its own,
(gnu packages hello). Technically, this is not strictly
necessary, but it is convenient to do so: all the packages defined in
(gnu packages …) are automatically known to
the command-line tools (see Package Modules).
There are a few points worth noting in the above package definition:
sourcefield of the package is an
<origin>object (see origin Reference, for the complete reference). Here, the
(guix download)is used, meaning that the source is a file to be downloaded over FTP or HTTP.
mirror://gnu prefix instructs
url-fetch to use one of
the GNU mirrors defined in
sha256 field specifies the expected SHA256 hash of the file
being downloaded. It is mandatory, and allows Guix to check the
integrity of the file. The
(base32 …) form introduces the
base32 representation of the hash. You can obtain this information with
guix download (see Invoking guix download) and
hash (see Invoking guix hash).
When needed, the
origin form can also have a
listing patches to be applied, and a
snippet field giving a
Scheme expression to modify the source code.
build-systemfield specifies the procedure to build the package (see Build Systems). Here, gnu-build-system represents the familiar GNU Build System, where packages may be configured, built, and installed with the usual
./configure && make && make check && make installcommand sequence.
argumentsfield specifies options for the build system (see Build Systems). Here it is interpreted by gnu-build-system as a request run configure with the --enable-silent-rules flag.
What about these quote (
') characters? They are Scheme syntax to
introduce a literal list;
' is synonymous with
See quoting in GNU Guile Reference Manual,
for details. Here the value of the
arguments field is a list of
arguments passed to the build system down the road, as with
apply in GNU Guile Reference
The hash-colon (
#:) sequence defines a Scheme keyword
(see Keywords in GNU Guile Reference Manual), and
#:configure-flags is a keyword used to pass a keyword argument
to the build system (see Coding With Keywords in GNU Guile
inputsfield specifies inputs to the build process—i.e., build-time or run-time dependencies of the package. Here, we define an input called
"gawk"whose value is that of the gawk variable; gawk is itself bound to a
` (a backquote, synonymous with
us to introduce a literal list in the
inputs field, while
, (a comma, synonymous with
unquote) allows us to insert a
value in that list (see unquote in GNU Guile
Note that GCC, Coreutils, Bash, and other essential tools do not need to be specified as inputs here. Instead, gnu-build-system takes care of ensuring that they are present (see Build Systems).
However, any other dependencies need to be specified in the
inputs field. Any dependency not specified here will simply be
unavailable to the build process, possibly leading to a build failure.
See package Reference, for a full description of possible fields.
Once a package definition is in place, the
package may actually be built using the
guix build command-line
tool (see Invoking guix build), troubleshooting any build failures
you encounter (see Debugging Build Failures). You can easily jump back to the
package definition using the
guix edit command
(see Invoking guix edit).
See Packaging Guidelines, for
more information on how to test package definitions, and
Invoking guix lint, for information on how to check a definition
for style conformance.
Lastly, see Channels, for information
on how to extend the distribution by adding your own package definitions
in a “channel”.
Finally, updating the package definition to a new upstream version
can be partly automated by the
guix refresh command
(see Invoking guix refresh).
Behind the scenes, a derivation corresponding to the
object is first computed by the
That derivation is stored in a .drv file under /gnu/store.
The build actions it prescribes may then be realized by using the
build-derivations procedure (see The Store).
<derivation> object of package for system
package must be a valid
<package> object, and system
must be a string denoting the target system type—e.g.,
"x86_64-linux" for an x86_64 Linux-based GNU system. store
must be a connection to the daemon, which operates on the store
(see The Store).
Similarly, it is possible to compute a derivation that cross-builds a package for some other system:
<derivation> object of package cross-built from
system to target.
target must be a valid GNU triplet denoting the target hardware
and operating system, such as
(see Specifying Target Triplets in Autoconf).
Packages can be manipulated in arbitrary ways. An example of a useful transformation is input rewriting, whereby the dependency tree of a package is rewritten by replacing specific inputs by others:
Return a procedure that, when passed a package, replaces its direct and indirect dependencies (but not its implicit inputs) according to replacements. replacements is a list of package pairs; the first element of each pair is the package to replace, and the second one is the replacement.
Optionally, rewrite-name is a one-argument procedure that takes the name of a package and returns its new name after rewrite.
Consider this example:
(define libressl-instead-of-openssl ;; This is a procedure to replace OPENSSL by LIBRESSL, ;; recursively. (package-input-rewriting `((,openssl . ,libressl)))) (define git-with-libressl (libressl-instead-of-openssl git))
Here we first define a rewriting procedure that replaces openssl with libressl. Then we use it to define a variant of the git package that uses libressl instead of openssl. This is exactly what the --with-input command-line option does (see --with-input).
The following variant of
package-input-rewriting can match packages to
be replaced by name rather than by identity.
Return a procedure that, given a package, applies the given replacements to
all the package graph (excluding implicit inputs). replacements is a list of
spec/procedures pair; each spec is a package specification such as
"guile@2", and each procedure takes a matching package and returns a
replacement for that package.
The example above could be rewritten this way:
(define libressl-instead-of-openssl ;; Replace all the packages called "openssl" with LibreSSL. (package-input-rewriting/spec `(("openssl" . ,(const libressl)))))
The key difference here is that, this time, packages are matched by spec and
not by identity. In other words, any package in the graph that is called
openssl will be replaced.
A more generic procedure to rewrite a package dependency graph is
package-mapping: it supports arbitrary changes to nodes in the
Return a procedure that, given a package, applies proc to all the packages depended on and returns the resulting package. The procedure stops recursion when cut? returns true for a given package.
|• package Reference||The package data type.|
|• origin Reference||The origin data type.|