Skip to content
Snippets Groups Projects
guix-cookbook.texi 103 KiB
Newer Older
Ricardo Wurmus's avatar
Ricardo Wurmus committed
\input texinfo
@c -*-texinfo-*-

@c %**start of header
@setfilename guix-cookbook.info
@documentencoding UTF-8
@settitle GNU Guix Cookbook
@c %**end of header

@copying
Copyright @copyright{} 2019 Ricardo Wurmus@*
Copyright @copyright{} 2019 Efraim Flashner@*
Copyright @copyright{} 2019 Pierre Neidhardt@*
Copyright @copyright{} 2020 Oleg Pykhalov@*
Copyright @copyright{} 2020 Matthew Brooks@*
Copyright @copyright{} 2020 Marcin Karpezo@*
Copyright @copyright{} 2020 Brice Waegeneire@*
Copyright @copyright{} 2020 André Batista@*
Copyright @copyright{} 2020 Christopher Lemmer Webber
Ricardo Wurmus's avatar
Ricardo Wurmus committed

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  A
copy of the license is included in the section entitled ``GNU Free
Documentation License''.
@end copying

@dircategory System administration
@direntry
* Guix cookbook: (guix-cookbook).    Tutorials and examples for GNU Guix.
@end direntry

@titlepage
@title GNU Guix Cookbook
@subtitle Tutorials and examples for using the GNU Guix Functional Package Manager
@author The GNU Guix Developers

@page
@vskip 0pt plus 1filll

@insertcopying
@end titlepage

@contents

@c *********************************************************************
@node Top
@top GNU Guix Cookbook

This document presents tutorials and detailed examples for GNU@tie{}Guix, a
functional package management tool written for the GNU system.  Please
@pxref{Top,,, guix, GNU Guix reference manual} for details about the system,
its API, and related concepts.

@c TRANSLATORS: You can replace the following paragraph with information on
@c how to join your own translation team and how to report issues with the
@c translation.
If you would like to translate this document in your native language, consider
joining
@uref{https://translate.fedoraproject.org/projects/guix/documentation-cookbook,
Weblate}.
Ricardo Wurmus's avatar
Ricardo Wurmus committed

@menu
* Scheme tutorials::            Meet your new favorite language!
* Packaging::                   Packaging tutorials
* System Configuration::        Customizing the GNU System
* Advanced package management:: Power to the users!
* Environment management::      Control environment
Ricardo Wurmus's avatar
Ricardo Wurmus committed

* Acknowledgments::             Thanks!
* GNU Free Documentation License::  The license of this document.
* Concept Index::               Concepts.

@detailmenu
 --- The Detailed Node Listing ---

Scheme tutorials

* A Scheme Crash Course::       Learn the basics of Scheme

Packaging

* Packaging Tutorial::          Let's add a package to Guix!

System Configuration

* Customizing the Kernel::      Creating and using a custom Linux kernel


@end detailmenu
@end menu

@c *********************************************************************
@node Scheme tutorials
@chapter Scheme tutorials

GNU@tie{}Guix is written in the general purpose programming language Scheme,
and many of its features can be accessed and manipulated programmatically.
You can use Scheme to generate package definitions, to modify them, to build
them, to deploy whole operating systems, etc.

Knowing the basics of how to program in Scheme will unlock many of the
advanced features Guix provides --- and you don't even need to be an
experienced programmer to use them!

Let's get started!

@node A Scheme Crash Course
@section A Scheme Crash Course

@cindex Scheme, crash course

Guix uses the Guile implementation of Scheme.  To start playing with the
language, install it with @code{guix install guile} and start a
@dfn{REPL}---short for @uref{https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop,
@dfn{read-eval-print loop}}---by running @code{guile} from the command line.
Ricardo Wurmus's avatar
Ricardo Wurmus committed

Alternatively you can also run @code{guix environment --ad-hoc guile -- guile}
if you'd rather not have Guile installed in your user profile.

In the following examples, lines show what you would type at the REPL;
lines starting with ``@result{}'' show evaluation results, while lines
starting with ``@print{}'' show things that get printed.  @xref{Using Guile
Interactively,,, guile, GNU Guile Reference Manual}, for more details on the
Ricardo Wurmus's avatar
Ricardo Wurmus committed
REPL.

@itemize
@item
Scheme syntax boils down to a tree of expressions (or @emph{s-expression} in
Lisp lingo).  An expression can be a literal such as numbers and strings, or a
compound which is a parenthesized list of compounds and literals.  @code{#true}
and @code{#false} (abbreviated @code{#t} and @code{#f}) stand for the
Booleans ``true'' and ``false'', respectively.
Ricardo Wurmus's avatar
Ricardo Wurmus committed

Examples of valid expressions:

Ricardo Wurmus's avatar
Ricardo Wurmus committed
"Hello World!"
@result{} 17

(display (string-append "Hello " "Guix" "\n"))
@print{} Hello Guix!
@result{} #<unspecified>
Ricardo Wurmus's avatar
Ricardo Wurmus committed

@item
This last example is a function call nested in another function call.  When a
parenthesized expression is evaluated, the first term is the function and the
rest are the arguments passed to the function.  Every function returns the
last evaluated expression as its return value.

@item
Anonymous functions are declared with the @code{lambda} term:

(lambda (x) (* x x))
@result{} #<procedure 120e348 at <unknown port>:24:0 (x)>
Ricardo Wurmus's avatar
Ricardo Wurmus committed

The above procedure returns the square of its argument.  Since everything is
an expression, the @code{lambda} expression returns an anonymous procedure,
which can in turn be applied to an argument:

((lambda (x) (* x x)) 3)
@result{} 9
Ricardo Wurmus's avatar
Ricardo Wurmus committed

@item
Anything can be assigned a global name with @code{define}:

(define a 3)
(define square (lambda (x) (* x x)))
(square a)
@result{} 9
Ricardo Wurmus's avatar
Ricardo Wurmus committed

@item
Procedures can be defined more concisely with the following syntax:

Ricardo Wurmus's avatar
Ricardo Wurmus committed
(define (square x) (* x x))
Ricardo Wurmus's avatar
Ricardo Wurmus committed

@item
A list structure can be created with the @code{list} procedure:

(list 2 a 5 7)
@result{} (2 3 5 7)
The @dfn{quote} disables evaluation of a parenthesized expression: the
first term is not called over the other terms (@pxref{Expression Syntax,
quote,, guile, GNU Guile Reference Manual}).  Thus it effectively
returns a list of terms.
'(display (string-append "Hello " "Guix" "\n"))
@result{} (display (string-append "Hello " "Guix" "\n"))

'(2 a 5 7)
@result{} (2 a 5 7)
The @dfn{quasiquote} disables evaluation of a parenthesized expression
until @dfn{unquote} (a comma) re-enables it.  Thus it provides us with
fine-grained control over what is evaluated and what is not.
`(2 a 5 7 (2 ,a 5 ,(+ a 4)))
@result{} (2 a 5 7 (2 3 5 7))
Ricardo Wurmus's avatar
Ricardo Wurmus committed

Note that the above result is a list of mixed elements: numbers, symbols (here
@code{a}) and the last element is a list itself.

@item
Multiple variables can be named locally with @code{let} (@pxref{Local
Bindings,,, guile, GNU Guile Reference Manual}):
(define x 10)
(let ((x 2)
      (y 3))
  (list x y))
@result{} (2 3)

x
@result{} 10

y
@error{} In procedure module-lookup: Unbound variable: y
Ricardo Wurmus's avatar
Ricardo Wurmus committed

Use @code{let*} to allow later variable declarations to refer to earlier
definitions.

(let* ((x 2)
       (y (* x 3)))
  (list x y))
@result{} (2 6)
@dfn{Keywords} are typically used to identify the named parameters of a
procedure.  They are prefixed by @code{#:} (hash, colon) followed by
alphanumeric characters: @code{#:like-this}.
@xref{Keywords,,, guile, GNU Guile Reference Manual}.
Ricardo Wurmus's avatar
Ricardo Wurmus committed

@item
The percentage @code{%} is typically used for read-only global variables in
the build stage.  Note that it is merely a convention, like @code{_} in C.
Scheme treats @code{%} exactly the same as any other letter.

@item
Modules are created with @code{define-module} (@pxref{Creating Guile
Modules,,, guile, GNU Guile Reference Manual}).  For instance
Ricardo Wurmus's avatar
Ricardo Wurmus committed
(define-module (guix build-system ruby)
  #:use-module (guix store)
  #:export (ruby-build
            ruby-build-system))
Ricardo Wurmus's avatar
Ricardo Wurmus committed

defines the module @code{guix build-system ruby} which must be located in
@file{guix/build-system/ruby.scm} somewhere in the Guile load path.  It
depends on the @code{(guix store)} module and it exports two variables,
@code{ruby-build} and @code{ruby-build-system}.
@end itemize

For a more detailed introduction, check out
@uref{http://www.troubleshooters.com/codecorn/scheme_guile/hello.htm, Scheme
at a Glance}, by Steve Litt.

One of the reference Scheme books is the seminal ``Structure and
Interpretation of Computer Programs'', by Harold Abelson and Gerald Jay
Sussman, with Julie Sussman.  You'll find a
@uref{https://mitpress.mit.edu/sites/default/files/sicp/index.html, free copy
online}, together with
@uref{https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/,
videos of the lectures by the authors}.  The book is available in Texinfo
format as the @code{sicp} Guix package.  Go ahead, run @code{guix install
sicp} and start reading with @code{info sicp} (@pxref{,,, sicp, Structure and Interpretation of Computer Programs}).
Ricardo Wurmus's avatar
Ricardo Wurmus committed
An @uref{https://sarabander.github.io/sicp/, unofficial ebook is also
available}.

You'll find more books, tutorials and other resources at
@url{https://schemers.org/}.


@c *********************************************************************
@node Packaging
@chapter Packaging

@cindex packaging

This chapter is dedicated to teaching you how to add packages to the
collection of packages that come with GNU Guix.  This involves writing package
definitions in Guile Scheme, organizing them in package modules, and building
them.

@menu
* Packaging Tutorial::         A tutorial on how to add packages to Guix.
@end menu

@node Packaging Tutorial
@section Packaging Tutorial

GNU Guix stands out as the @emph{hackable} package manager, mostly because it
uses @uref{https://www.gnu.org/software/guile/, GNU Guile}, a powerful
high-level programming language, one of the
@uref{https://en.wikipedia.org/wiki/Scheme_%28programming_language%29, Scheme}
dialects from the
@uref{https://en.wikipedia.org/wiki/Lisp_%28programming_language%29, Lisp family}.

Package definitions are also written in Scheme, which empowers Guix in some
very unique ways, unlike most other package managers that use shell scripts or
simple languages.

@itemize
@item
Use functions, structures, macros and all of Scheme expressiveness for your
package definitions.

@item
Inheritance makes it easy to customize a package by inheriting from it and
modifying only what is needed.
Ricardo Wurmus's avatar
Ricardo Wurmus committed
@item
Batch processing: the whole package collection can be parsed, filtered and
processed.  Building a headless server with all graphical interfaces stripped
out?  It's possible.  Want to rebuild everything from source using specific
compiler optimization flags?  Pass the @code{#:make-flags "..."} argument to
the list of packages.  It wouldn't be a stretch to think
@uref{https://wiki.gentoo.org/wiki/USE_flag, Gentoo USE flags} here, but this
goes even further: the changes don't have to be thought out beforehand by the
packager, they can be @emph{programmed} by the user!
@end itemize

The following tutorial covers all the basics around package creation with Guix.
It does not assume much knowledge of the Guix system nor of the Lisp language.
The reader is only expected to be familiar with the command line and to have some
basic programming knowledge.

@node A ``Hello World'' package
@subsection A ``Hello World'' package
The ``Defining Packages'' section of the manual introduces the basics of Guix
Ricardo Wurmus's avatar
Ricardo Wurmus committed
packaging (@pxref{Defining Packages,,, guix, GNU Guix Reference Manual}).  In
the following section, we will partly go over those basics again.

GNU@tie{}Hello is a dummy project that serves as an idiomatic example for
Ricardo Wurmus's avatar
Ricardo Wurmus committed
packaging.  It uses the GNU build system (@code{./configure && make && make
install}).  Guix already provides a package definition which is a perfect
example to start with.  You can look up its declaration with @code{guix edit
hello} from the command line.  Let's see how it looks:

Ricardo Wurmus's avatar
Ricardo Wurmus committed
(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)
    (synopsis "Hello, GNU world: An example GNU package")
    (description
     "GNU Hello prints the message \"Hello, world!\" and then exits.  It
serves as an example of standard GNU coding practices.  As such, it supports
command-line arguments, multiple languages, and so on.")
    (home-page "https://www.gnu.org/software/hello/")
    (license gpl3+)))
Ricardo Wurmus's avatar
Ricardo Wurmus committed

As you can see, most of it is rather straightforward.  But let's review the
fields together:

@table @samp
@item name
The project name.  Using Scheme conventions, we prefer to keep it
lower case, without underscore and using dash-separated words.

@item source
This field contains a description of the source code origin.  The
@code{origin} record contains these fields:

@enumerate
@item  The method, here @code{url-fetch} to download via HTTP/FTP, but other methods
    exist, such as @code{git-fetch} for Git repositories.
@item  The URI, which is typically some @code{https://} location for @code{url-fetch}.  Here
    the special `mirror://gnu` refers to a set of well known locations, all of
    which can be used by Guix to fetch the source, should some of them fail.
@item  The @code{sha256} checksum of the requested file.  This is essential to ensure
    the source is not corrupted.  Note that Guix works with base32 strings,
    hence the call to the @code{base32} function.
@end enumerate

@item build-system

This is where the power of abstraction provided by the Scheme language really
shines: in this case, the @code{gnu-build-system} abstracts away the famous
@code{./configure && make && make install} shell invocations.  Other build
systems include the @code{trivial-build-system} which does not do anything and
requires from the packager to program all the build steps, the
@code{python-build-system}, the @code{emacs-build-system}, and many more
(@pxref{Build Systems,,, guix, GNU Guix Reference Manual}).

@item synopsis
It should be a concise summary of what the package does.  For many packages a
tagline from the project's home page can be used as the synopsis.

@item description
Same as for the synopsis, it's fine to re-use the project description from the
homepage.  Note that Guix uses Texinfo syntax.

@item home-page
Use HTTPS if available.

@item license
See @code{guix/licenses.scm} in the project source for a full list of
available licenses.
@end table

Time to build our first package!  Nothing fancy here for now: we will stick to a
dummy @code{my-hello}, a copy of the above declaration.
As with the ritualistic ``Hello World'' taught with most programming languages,
this will possibly be the most ``manual'' approach.  We will work out an ideal
Ricardo Wurmus's avatar
Ricardo Wurmus committed
setup later; for now we will go the simplest route.

Save the following to a file @file{my-hello.scm}.

Ricardo Wurmus's avatar
Ricardo Wurmus committed
(use-modules (guix packages)
             (guix download)
             (guix build-system gnu)
             (guix licenses))

(package
  (name "my-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)
  (synopsis "Hello, Guix world: An example custom Guix package")
  (description
   "GNU Hello prints the message \"Hello, world!\" and then exits.  It
serves as an example of standard GNU coding practices.  As such, it supports
command-line arguments, multiple languages, and so on.")
  (home-page "https://www.gnu.org/software/hello/")
  (license gpl3+))
Ricardo Wurmus's avatar
Ricardo Wurmus committed

We will explain the extra code in a moment.

Feel free to play with the different values of the various fields.  If you
change the source, you'll need to update the checksum.  Indeed, Guix refuses to
build anything if the given checksum does not match the computed checksum of the
source code.  To obtain the correct checksum of the package declaration, we
need to download the source, compute the sha256 checksum and convert it to
base32.

Thankfully, Guix can automate this task for us; all we need is to provide the
URI:

@c TRANSLATORS: This is example shell output.
@example sh
$ guix download mirror://gnu/hello/hello-2.10.tar.gz

Starting download of /tmp/guix-file.JLYgL7
From https://ftpmirror.gnu.org/gnu/hello/hello-2.10.tar.gz...
following redirection to `https://mirror.ibcp.fr/pub/gnu/hello/hello-2.10.tar.gz'...
10.tar.gz  709KiB                                 2.5MiB/s 00:00 [##################] 100.0%
/gnu/store/hbdalsf5lpf01x4dcknwx6xbn6n5km6k-hello-2.10.tar.gz
0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i
@end example

In this specific case the output tells us which mirror was chosen.
If the result of the above command is not the same as in the above snippet,
update your @code{my-hello} declaration accordingly.

Note that GNU package tarballs come with an OpenPGP signature, so you
should definitely check the signature of this tarball with `gpg` to
authenticate it before going further:

@c TRANSLATORS: This is example shell output.
@example sh
$ guix download mirror://gnu/hello/hello-2.10.tar.gz.sig

Starting download of /tmp/guix-file.03tFfb
From https://ftpmirror.gnu.org/gnu/hello/hello-2.10.tar.gz.sig...
following redirection to `https://ftp.igh.cnrs.fr/pub/gnu/hello/hello-2.10.tar.gz.sig'...
 ….tar.gz.sig  819B                                                                                                                       1.2MiB/s 00:00 [##################] 100.0%
/gnu/store/rzs8wba9ka7grrmgcpfyxvs58mly0sx6-hello-2.10.tar.gz.sig
0q0v86n3y38z17rl146gdakw9xc4mcscpk8dscs412j22glrv9jf
$ gpg --verify /gnu/store/rzs8wba9ka7grrmgcpfyxvs58mly0sx6-hello-2.10.tar.gz.sig /gnu/store/hbdalsf5lpf01x4dcknwx6xbn6n5km6k-hello-2.10.tar.gz
gpg: Signature made Sun 16 Nov 2014 01:08:37 PM CET
gpg:                using RSA key A9553245FDE9B739
gpg: Good signature from "Sami Kerola <kerolasa@@iki.fi>" [unknown]
gpg:                 aka "Sami Kerola (http://www.iki.fi/kerolasa/) <kerolasa@@iki.fi>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 8ED3 96E3 7E38 D471 A005  30D3 A955 3245 FDE9 B739
@end example

You can then happily run

@c TRANSLATORS: Do not translate this command
@example sh
$ guix package --install-from-file=my-hello.scm
@end example

You should now have @code{my-hello} in your profile!

@c TRANSLATORS: Do not translate this command
@example sh
$ guix package --list-installed=my-hello
my-hello	2.10	out
/gnu/store/f1db2mfm8syb8qvc357c53slbvf1g9m9-my-hello-2.10
@end example

We've gone as far as we could without any knowledge of Scheme.  Before moving
on to more complex packages, now is the right time to brush up on your Scheme
knowledge.  @pxref{A Scheme Crash Course} to get up to speed.

@node Setup
@subsection Setup
In the rest of this chapter we will rely on some basic Scheme
programming knowledge.  Now let's detail the different possible setups
for working on Guix packages.

There are several ways to set up a Guix packaging environment.

We recommend you work directly on the Guix source checkout since it makes it
easier for everyone to contribute to the project.

But first, let's look at other possibilities.

@node Local file
@subsubsection Local file

This is what we previously did with @samp{my-hello}.  With the Scheme basics we've
covered, we are now able to explain the leading chunks.  As stated in @code{guix
package --help}:

@example
  -f, --install-from-file=FILE
                         install the package that the code within FILE
                         evaluates to
@end example

Thus the last expression @emph{must} return a package, which is the case in our
earlier example.

The @code{use-modules} expression tells which of the modules we need in the file.
Modules are a collection of values and procedures.  They are commonly called
``libraries'' or ``packages'' in other programming languages.

@node @samp{GUIX_PACKAGE_PATH}
@subsubsection @samp{GUIX_PACKAGE_PATH}

@emph{Note: Starting from Guix 0.16, the more flexible Guix @dfn{channels} are the
preferred way and supersede @samp{GUIX_PACKAGE_PATH}.  See next section.}

It can be tedious to specify the file from the command line instead of simply
calling @code{guix package --install my-hello} as you would do with the official
packages.

Guix makes it possible to streamline the process by adding as many ``package
declaration directories'' as you want.
Create a directory, say @file{~./guix-packages} and add it to the @samp{GUIX_PACKAGE_PATH}
environment variable:

@example
$ mkdir ~/guix-packages
$ export GUIX_PACKAGE_PATH=~/guix-packages
@end example

To add several directories, separate them with a colon (@code{:}).

Our previous @samp{my-hello} needs some adjustments though:

(define-module (my-hello)
  #:use-module (guix licenses)
  #:use-module (guix packages)
  #:use-module (guix build-system gnu)
  #:use-module (guix download))

(define-public my-hello
  (package
    (name "my-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)
    (synopsis "Hello, Guix world: An example custom Guix package")
    (description
     "GNU Hello prints the message \"Hello, world!\" and then exits.  It
serves as an example of standard GNU coding practices.  As such, it supports
command-line arguments, multiple languages, and so on.")
    (home-page "https://www.gnu.org/software/hello/")
    (license gpl3+)))

Note that we have assigned the package value to an exported variable name with
@code{define-public}.  This is effectively assigning the package to the @code{my-hello}
variable so that it can be referenced, among other as dependency of other
packages.

If you use @code{guix package --install-from-file=my-hello.scm} on the above file, it
will fail because the last expression, @code{define-public}, does not return a
package.  If you want to use @code{define-public} in this use-case nonetheless, make
sure the file ends with an evaluation of @code{my-hello}:

; ...
(define-public my-hello
  ; ...
  )

my-hello

This last example is not very typical.

Now @samp{my-hello} should be part of the package collection like all other official
packages.  You can verify this with:

@example
$ guix package --show=my-hello
@end example

@node Guix channels
@subsubsection Guix channels

Guix 0.16 features channels, which is very similar to @samp{GUIX_PACKAGE_PATH} but
provides better integration and provenance tracking.  Channels are not
necessarily local, they can be maintained as a public Git repository for
instance.  Of course, several channels can be used at the same time.

@xref{Channels,,, guix, GNU Guix Reference Manual} for setup details.

@node Direct checkout hacking
@subsubsection Direct checkout hacking

Working directly on the Guix project is recommended: it reduces the friction
when the time comes to submit your changes upstream to let the community benefit
from your hard work!

Unlike most software distributions, the Guix repository holds in one place both
the tooling (including the package manager) and the package definitions.  This
choice was made so that it would give developers the flexibility to modify the
API without breakage by updating all packages at the same time.  This reduces
development inertia.

Check out the official @uref{https://git-scm.com/, Git} repository:

@example
$ git clone https://git.savannah.gnu.org/git/guix.git
@end example

In the rest of this article, we use @samp{$GUIX_CHECKOUT} to refer to the location of
the checkout.


Follow the instructions in the manual (@pxref{Contributing,,, guix, GNU Guix
Reference Manual}) to set up the repository environment.

Once ready, you should be able to use the package definitions from the
repository environment.

Feel free to edit package definitions found in @samp{$GUIX_CHECKOUT/gnu/packages}.

The @samp{$GUIX_CHECKOUT/pre-inst-env} script lets you use @samp{guix} over the package
collection of the repository (@pxref{Running Guix Before It Is
Installed,,, guix, GNU Guix Reference Manual}).

@itemize
@item
Search packages, such as Ruby:

@example
  $ cd $GUIX_CHECKOUT
  $ ./pre-inst-env guix package --list-available=ruby
      ruby    1.8.7-p374      out     gnu/packages/ruby.scm:119:2
      ruby    2.1.6   out     gnu/packages/ruby.scm:91:2
      ruby    2.2.2   out     gnu/packages/ruby.scm:39:2
@end example

@item
Build a package, here Ruby version 2.1:

@example
  $ ./pre-inst-env guix build --keep-failed ruby@@2.1
  /gnu/store/c13v73jxmj2nir2xjqaz5259zywsa9zi-ruby-2.1.6
@end example

@item
Install it to your user profile:

@example
  $ ./pre-inst-env guix package --install ruby@@2.1
@end example

@item
Check for common mistakes:

@example
  $ ./pre-inst-env guix lint ruby@@2.1
@end example
@end itemize

Guix strives at maintaining a high packaging standard; when contributing to the
Guix project, remember to

@itemize
@item
follow the coding style (@pxref{Coding Style,,, guix, GNU Guix Reference Manual}),
@item
and review the check list from the manual (@pxref{Submitting Patches,,, guix, GNU Guix Reference Manual}).
@end itemize

Once you are happy with the result, you are welcome to send your contribution to
make it part of Guix.  This process is also detailed in the manual.  (@pxref{Contributing,,, guix, GNU Guix Reference Manual})


It's a community effort so the more join in, the better Guix becomes!

@node Extended example
@subsection Extended example

The above ``Hello World'' example is as simple as it goes.  Packages can be more
complex than that and Guix can handle more advanced scenarios.  Let's look at
another, more sophisticated package (slightly modified from the source):

(define-module (gnu packages version-control)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (guix utils)
  #:use-module (guix packages)
  #:use-module (guix git-download)
  #:use-module (guix build-system cmake)
  #:use-module (gnu packages ssh)
  #:use-module (gnu packages web)
  #:use-module (gnu packages pkg-config)
  #:use-module (gnu packages python)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages tls))

(define-public my-libgit2
  (let ((commit "e98d0a37c93574d2c6107bf7f31140b548c6a7bf")
        (revision "1"))
    (package
      (name "my-libgit2")
      (version (git-version "0.26.6" revision commit))
      (source (origin
                (method git-fetch)
                (uri (git-reference
                      (url "https://github.com/libgit2/libgit2/")
                      (commit commit)))
                (file-name (git-file-name name version))
                (sha256
                 (base32
                  "17pjvprmdrx4h6bb1hhc98w9qi6ki7yl57f090n9kbhswxqfs7s3"))
                (patches (search-patches "libgit2-mtime-0.patch"))
                (modules '((guix build utils)))
                (snippet '(begin
                            ;; Remove bundled software.
                            (delete-file-recursively "deps")
      (build-system cmake-build-system)
      (outputs '("out" "debug"))
      (arguments
       `(#:tests? #true                         ; Run the test suite (this is the default)
         #:configure-flags '("-DUSE_SHA1DC=ON") ; SHA-1 collision detection
         #:phases
         (modify-phases %standard-phases
           (add-after 'unpack 'fix-hardcoded-paths
             (lambda _
               (substitute* "tests/repo/init.c"
                 (("#!/bin/sh") (string-append "#!" (which "sh"))))
               (substitute* "tests/clar/fs.h"
                 (("/bin/cp") (which "cp"))
                 (("/bin/rm") (which "rm")))
           ;; Run checks more verbosely.
           (replace 'check
             (lambda _ (invoke "./libgit2_clar" "-v" "-Q")))
           (add-after 'unpack 'make-files-writable-for-tests
             (lambda _ (for-each make-file-writable (find-files "." ".*")))))))
      (inputs
       `(("libssh2" ,libssh2)
         ("http-parser" ,http-parser)
         ("python" ,python-wrapper)))
      (native-inputs
       `(("pkg-config" ,pkg-config)))
      (propagated-inputs
       ;; These two libraries are in 'Requires.private' in libgit2.pc.
       `(("openssl" ,openssl)
         ("zlib" ,zlib)))
      (home-page "https://libgit2.github.com/")
      (synopsis "Library providing Git core methods")
      (description
       "Libgit2 is a portable, pure C implementation of the Git core methods
provided as a re-entrant linkable library with a solid API, allowing you to
write native speed custom Git applications in any language with bindings.")
      ;; GPLv2 with linking exception
      (license license:gpl2))))

(In those cases were you only want to tweak a few fields from a package
definition, you should rely on inheritance instead of copy-pasting everything.
See below.)

Let's discuss those fields in depth.

@subsubsection @code{git-fetch} method

Unlike the @code{url-fetch} method, @code{git-fetch} expects a @code{git-reference} which takes
a Git repository and a commit.  The commit can be any Git reference such as
tags, so if the @code{version} is tagged, then it can be used directly.  Sometimes
the tag is prefixed with a @code{v}, in which case you'd use @code{(commit (string-append
"v" version))}.

To ensure that the source code from the Git repository is stored in a
directory with a descriptive name, we use @code{(file-name (git-file-name name
The @code{git-version} procedure can be used to derive the
version when packaging programs for a specific commit, following the
Guix contributor guidelines (@pxref{Version Numbers,,, guix, GNU Guix
Reference Manual}).
How does one obtain the @code{sha256} hash that's in there, you ask?  By
invoking @command{guix hash} on a checkout of the desired commit, along
these lines:

@example
git clone https://github.com/libgit2/libgit2/
cd libgit2
git checkout v0.26.6
guix hash -rx .
@end example

@command{guix hash -rx} computes a SHA256 hash over the whole directory,
excluding the @file{.git} sub-directory (@pxref{Invoking guix hash,,,
guix, GNU Guix Reference Manual}).

In the future, @command{guix download} will hopefully be able to do
these steps for you, just like it does for regular downloads.

@subsubsection Snippets

Snippets are quoted (i.e. non-evaluated) Scheme code that are a means of patching
the source.  They are a Guix-y alternative to the traditional @file{.patch} files.
Because of the quote, the code in only evaluated when passed to the Guix daemon
for building.  There can be as many snippets as needed.

Snippets might need additional Guile modules which can be imported from the
@code{modules} field.

@subsubsection Inputs

First, a syntactic comment: See the quasi-quote / comma syntax?

    (native-inputs
     `(("pkg-config" ,pkg-config)))
    (native-inputs
     (list (list "pkg-config" pkg-config)))

You'll mostly see the former because it's shorter.

There are 3 different input types.  In short:

@table @asis
@item native-inputs
Required for building but not runtime -- installing a package
through a substitute won't install these inputs.
@item inputs
Installed in the store but not in the profile, as well as being
present at build time.
@item propagated-inputs
Installed in the store and in the profile, as well as
being present at build time.
@end table

@xref{Package Reference,,, guix, GNU Guix Reference Manual} for more details.

The distinction between the various inputs is important: if a dependency can be
handled as an @emph{input} instead of a @emph{propagated input}, it should be done so, or
else it ``pollutes'' the user profile for no good reason.

For instance, a user installing a graphical program that depends on a
command line tool might only be interested in the graphical part, so there is no
need to force the command line tool into the user profile.  The dependency is a
concern to the package, not to the user.  @emph{Inputs} make it possible to handle
dependencies without bugging the user by adding undesired executable files (or
libraries) to their profile.

Same goes for @emph{native-inputs}: once the program is installed, build-time
dependencies can be safely garbage-collected.
It also matters when a substitute is available, in which case only the @emph{inputs}
and @emph{propagated inputs} will be fetched: the @emph{native inputs} are not required to
install a package from a substitute.

@subsubsection Outputs

Just like how a package can have multiple inputs, it can also produce multiple
outputs.

Each output corresponds to a separate directory in the store.

The user can choose which output to install; this is useful to save space or
to avoid polluting the user profile with unwanted executables or libraries.

Output separation is optional.  When the @code{outputs} field is left out, the
default and only output (the complete package) is referred to as @code{"out"}.

Typical separate output names include @code{debug} and @code{doc}.

It's advised to separate outputs only when you've shown it's worth it: if the
output size is significant (compare with @code{guix size}) or in case the package is
modular.

@subsubsection Build system arguments

The @code{arguments} is a keyword-value list used to configure the build process.

The simplest argument @code{#:tests?} can be used to disable the test suite when
building the package.  This is mostly useful when the package does not feature
any test suite.  It's strongly recommended to keep the test suite on if there is
one.

Another  common argument is @code{:make-flags}, which specifies a list of flags to
append when running make, as you would from the command line.  For instance, the
following flags

#:make-flags (list (string-append "prefix=" (assoc-ref %outputs "out"))
                   "CC=gcc")

translate into

@example
$ make CC=gcc prefix=/gnu/store/...-<out>
@end example

This sets the C compiler to @code{gcc} and the @code{prefix} variable (the installation
directory in Make parlance) to @code{(assoc-ref %outputs "out")}, which is a build-stage
global variable pointing to the destination directory in the store (something like
@file{/gnu/store/...-my-libgit2-20180408}).
Similarly, it's possible to set the configure flags:
#:configure-flags '("-DUSE_SHA1DC=ON")

The @code{%build-inputs} variable is also generated in scope.  It's an association
table that maps the input names to their store directories.

The @code{phases} keyword lists the sequential steps of the build system.  Typically
phases include @code{unpack}, @code{configure}, @code{build}, @code{install} and @code{check}.  To know
more about those phases, you need to work out the appropriate build system