Next: Bonus: Package Variants, Previous: Level 1: Building with Guix, Up: Software Development [Contents][Index]
We now have a Git repository containing (among other things) a package definition (see Level 1: Building with Guix). Can’t we turn it into a channel (see Channels in GNU Guix Reference Manual)? After all, channels are designed to ship package definitions to users, and that’s exactly what we’re doing with our guix.scm.
Turns out we can indeed turn it into a channel, but with one caveat: we
must create a separate directory for the .scm
file(s) of our
channel so that guix pull
doesn’t load unrelated .scm
files when someone pulls the channel—and in Guile, there are lots of
them! So we’ll start like this, keeping a top-level guix.scm
symlink for the sake of guix shell
:
mkdir -p .guix/modules mv guix.scm .guix/modules/guile-package.scm ln -s .guix/modules/guile-package.scm guix.scm
To make it usable as part of a channel, we need to turn our
guix.scm file into a package module (see Package
Modules in GNU Guix Reference Manual):
we do that by changing the use-modules
form at the top to a
define-module
form. We also need to actually export a
package variable, with define-public
, while still returning the
package value at the end of the file so we can still use
guix shell
and guix build -f guix.scm
. The end result
looks like this (not repeating things that haven’t changed):
(define-module (guile-package) #:use-module (guix) #:use-module (guix git-download) ;for ‘git-predicate’ …) (define vcs-file? ;; Return true if the given file is under version control. (or (git-predicate (dirname (dirname (current-source-directory)))) (const #t))) ;not in a Git checkout (define-public guile (package (name "guile") (version "3.0.99-git") ;funky version number (source (local-file "../.." "guile-checkout" #:recursive? #t #:select? vcs-file?)) …)) ;; Return the package object define above at the end of the module. guile
We need one last thing: a
.guix-channel
file so Guix knows where to look for package modules in our repository:
;; This file lets us present this repo as a Guix channel. (channel (version 0) (directory ".guix/modules")) ;look for package modules under .guix/modules/
To recap, we now have these files:
. ├── .guix-channel ├── guix.scm → .guix/modules/guile-package.scm └── .guix └── modules └── guile-package.scm
And that’s it: we have a channel! (We could do better and support
channel
authentication so users know they’re pulling genuine code. We’ll spare
you the details here but it’s worth considering!) Users can pull from
this channel by
adding
it to ~/.config/guix/channels.scm
, along these lines:
(append (list (channel
(name 'guile)
(url "https://git.savannah.gnu.org/git/guile.git")
(branch "main")))
%default-channels)
After running guix pull
, we can see the new package:
$ guix describe Generation 264 May 26 2023 16:00:35 (current) guile 36fd2b4 repository URL: https://git.savannah.gnu.org/git/guile.git branch: main commit: 36fd2b4920ae926c79b936c29e739e71a6dff2bc guix c5bc698 repository URL: https://git.savannah.gnu.org/git/guix.git commit: c5bc698e8922d78ed85989985cc2ceb034de2f23 $ guix package -A ^guile$ guile 3.0.99-git out,debug guile-package.scm:51:4 guile 3.0.9 out,debug gnu/packages/guile.scm:317:2 guile 2.2.7 out,debug gnu/packages/guile.scm:258:2 guile 2.2.4 out,debug gnu/packages/guile.scm:304:2 guile 2.0.14 out,debug gnu/packages/guile.scm:148:2 guile 1.8.8 out gnu/packages/guile.scm:77:2 $ guix build guile@3.0.99-git […] /gnu/store/axnzbl89yz7ld78bmx72vpqp802dwsar-guile-3.0.99-git-debug /gnu/store/r34gsij7f0glg2fbakcmmk0zn4v62s5w-guile-3.0.99-git
That’s how, as a developer, you get your software delivered directly into the hands of users! No intermediaries, yet no loss of transparency and provenance tracking.
With that in place, it also becomes trivial for anyone to create Docker
images, Deb/RPM packages, or a plain tarball with guix pack
(see Invoking guix pack in GNU Guix Reference Manual):
# How about a Docker image of our Guile snapshot? guix pack -f docker -S /bin=bin guile@3.0.99-git # And a relocatable RPM? guix pack -f rpm -R -S /bin=bin guile@3.0.99-git
Next: Bonus: Package Variants, Previous: Level 1: Building with Guix, Up: Software Development [Contents][Index]