The “Defining Packages” section of the manual introduces the basics of Guix packaging (see Defining Packages in GNU Guix Reference Manual). In the following section, we will partly go over those basics again.
GNU Hello is a dummy project that serves as an idiomatic example for
packaging. It uses the GNU build system (
./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
hello from the command line. Let’s see how it looks:
(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+)))
As you can see, most of it is rather straightforward. But let’s review the fields together:
The project name. Using Scheme conventions, we prefer to keep it lower case, without underscore and using dash-separated words.
This field contains a description of the source code origin. The
origin record contains these fields:
url-fetchto download via HTTP/FTP, but other methods exist, such as
git-fetchfor Git repositories.
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.
sha256checksum 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
This is where the power of abstraction provided by the Scheme language really
shines: in this case, the
gnu-build-system abstracts away the famous
./configure && make && make install shell invocations. Other build
systems include the
trivial-build-system which does not do anything and
requires from the packager to program all the build steps, the
emacs-build-system, and many more
(see Build Systems in GNU Guix Reference Manual).
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.
Same as for the synopsis, it’s fine to re-use the project description from the homepage. Note that Guix uses Texinfo syntax.
Use HTTPS if available.
guix/licenses.scm in the project source for a full list of
Time to build our first package! Nothing fancy here for now: we will stick to a
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 setup later; for now we will go the simplest route.
Save the following to a file my-hello.scm.
(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+))
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:
$ 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
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,
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:
$ 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 <email@example.com>" [unknown] gpg: aka "Sami Kerola (http://www.iki.fi/kerolasa/) <firstname.lastname@example.org>" [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
You can then happily run
$ guix package --install-from-file=my-hello.scm
You should now have
my-hello in your profile!
$ guix package --list-installed=my-hello my-hello 2.10 out /gnu/store/f1db2mfm8syb8qvc357c53slbvf1g9m9-my-hello-2.10
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. see A Scheme Crash Course to get up to speed.