Getting my hands dirty with GuixSD

4 minute read Published:

So last week, being bored with Fedora I tried to spice up my computing life with trying the GuixSD. It is a GNU/Linux distro that is built along the lines proposed by NixOS, that is it’s a declarative distro (meaning you declare how you want your system to be and it builds itself this way). The idea behind these systems is quite novel and a good start to understand the principles can be found in the original paper that defined the concept and led to the creation of NixOS.

So why did I choose GuixSD over NixOS, also given that NixOS seems to be more mature at the moment? Well the answer is Lisp! Everything in GuiSD is configured and programmed with GNU Guile, a Scheme dialect. I also wanted to have a completely free system and GuixSD is even FSF approved so the choice was clear to me.

Of course since GuixSD is still beta, there are some rough corners, but the community is quite helpful and the documentation is there but still a little unorganized. This is a place I would like to help, after getting a better look in the internals.

So for a little starter let’s see how we can update a package that has been left behind, in fact it is quite easy!

We shall start by cloning the Guix repo, since the team has made the -wise- decision to keep tooling and packages in a single repository. I think this makes the development of the distro, or the guix package manager, quite more fluid.

cd ~/guix
git clone https://git.savannah.gnu.org/git/guix.git

So after this we shall build the repo to see if everything is well, so we need the usual tools like autoconf etc. But still we don’t need to pollute our environment with these. By invoking:

guix environment guix

we get a shell with all the appropriate tools to build guix! Of course we can define our own environments for whatever purpose and the guix docs are very helpful for this!

So inside our new shell we can run:

./bootstrap
./configure --localstatedir=/var
make check -j

Now the build and tests will begin to run. Since -hopefully- all is well, let’s see a package:

(define-public emacs-projectile
  (package
    (name "emacs-projectile")
    (version "0.14.0")
    (source (origin
	      (method url-fetch)
	      (uri (string-append "https://raw.githubusercontent.com/bbatsov"
				  "/projectile/v" version "/projectile.el"))
	      (file-name (string-append "projectile-" version ".el"))
	      (sha256
	       (base32
		"1ql1wnzhblbwnv66hf2y0wq45g71hh6s9inc090lmhm1vgylbd1f"))))
    (build-system emacs-build-system)
    (propagated-inputs
     `(("emacs-dash" ,emacs-dash)
       ("emacs-pkg-info" ,emacs-pkg-info)))
    (home-page "https://github.com/bbatsov/projectile")
    (synopsis "Manage and navigate projects in Emacs easily")
    (description
     "This library provides easy project management and navigation.  The
concept of a project is pretty basic - just a folder containing special file.
Currently git, mercurial and bazaar repos are considered projects by default.
If you want to mark a folder manually as a project just create an empty
.projectile file in it.")
    (license license:gpl3+)))

So here we define a package with the package macro and make it public under the name emacs-projectile. Packages in guix are Scheme objects that are organized in modules. Documentation had got this nicely covered as well.

So to get the latest release of projectile we just need to bump up the version and update the hash of the source.

After that we can test our package. Guix offers the pre-inst-env in the root of the repo to invoke guix on the checkout of the git repo. So we can run, after evaluating the new declaration of the package:

./pre-inst-env guix build emacs-projectile@2.0.0
./pre-inst-env guix lint emacs-projectile@2.0.0

By using the emacs-guix package we can also type “C-c . b” and “C-c . l” over our package definition for the same results!

We can also install the package in our system by invoking:

./pre-inst-env guix -i emacs-projectile@2.0.0

This way we can check if the package builds ok and if there are any problems with our coding style. It’s also good to check for dependent packages and if our build is reproducible and in general it’s wise to follow the guidelines for submitting patches.

Then following the above guidelines we can submit a patch to the guix-patches mailing list!

Anyway this was just a glimpse in the guix packaging system, but there are so many more things. It’s something that got me excited to operating systems again after many years! You can share packages, mix versions of the same package, create vms of your system, even docker containers all in a very simple way that is based on the functional model the system and the package manager adheres to.