Skip to content

Instantly share code, notes, and snippets.

@zacque0
Last active October 17, 2021 13:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zacque0/6889be0629946d7625bc916311b63d37 to your computer and use it in GitHub Desktop.
Save zacque0/6889be0629946d7625bc916311b63d37 to your computer and use it in GitHub Desktop.
A tutorial on packaging using Guix package manager. Based on: https://github.com/FooBarWidget/debian-packaging-for-the-modern-developer

Package a Trivial C Application

This is roughly based on https://github.com/FooBarWidget/debian-packaging-for-the-modern-developer/tree/master/tutorial-3.

What’s worth noting is that we are going to package a C application using the GNU standard build procedure. It makes heavy use of GCC, glibc, bash, GNU Make, and more.

Create the application

To make it simple, create a directory “chello” at /tmp:

mkdir /tmp/chello
cd /tmp/chello

Then create a file called “hello.c”:

#include <stdio.h>

int main() {
  printf("Hello world! 1.0.0\n");
  return 0;
}

Then create a Makefile:

CC ?= gcc
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
MANDIR ?= $(PREFIX)/share/man

.PHONY: all clean install

all: hello

hello: hello.c
	gcc -Wall -g hello.c -o chello

clean:
	rm -f chello

install:
	mkdir -p $(DESTDIR)/$(BINDIR)
	install -c chello $(DESTDIR)/$(BINDIR)/chello

Done.

Package the application

Tar and gzip the application directory.

cd /tmp
tar -czf chello-1.0.0.tar.gz chello

Compute the guix hash.

guix hash chello-1.0.0.tar.gz chello

Done.

Write the package definition.

We shall make use of the previous guixpkgtut.scm file by appending a new package definition to it:

(define-public chello
  (package
   (name "chello")
   (version "1.0.0")
   (source (origin
	    (method url-fetch)
	    (uri (string-append "file:///tmp/chello-" version ".tar.gz"))
	    (sha256
	     (base32 "0crvmzy9mr2w6mflmlg3g3r8ka06b593qzsivypaf8maav3wmx7y"))))
   (build-system gnu-build-system)
   (arguments
    `(#:make-flags
      (list (string-append "CC=" ,(cc-for-target))
	    (string-append "PREFIX=" (assoc-ref %outputs "out")))
      #:phases
      (modify-phases %standard-phases
	(delete 'configure) ; no configure script
	(delete 'check)))) ; no make check target
   (home-page #f)
   (synopsis "My compiled hello package.")
   (description "A package to learn packaging a compiled C application that says hello.")
   (license license:bsd-2)))

Again, we can check our package definition by searching it with guix:

guix search chello

then build it:

guix build chello

Install and run the installed package

Try running in shell:

guix environment --ad-hoc chello -- chello

Done. You’ve successfully package a compiled application.

Package a Trivial Python Script

To get started, a package is a gzipped tar file, with the name “PACKAGE.tar.gz”. It means that all applications should be packaged in the gzipped tar format when it’s ready for distribution/installation. All the project metadata are described in a separate package definition file, which is a Scheme file ending with “.scm”.

Steps:

  1. Create the application.
  2. Package the application.
  3. Write the package definition.
  4. Install and run the installed package.

Create the application

To make it simple, let’s create a project directory named “pyhello” at /tmp.

mkdir /tmp/pyhello
cd /tmp/pyhello

Then, create our simple Python script/application.

editor pyhello

In the “pyhello” file, write a simple “hello” in Python:

#!/usr/bin/env python3
print("Hello world! 1.0.0")

Note: In Guix, the package python is python-3.8 as of writing, and its executable is named “python3” instead of “python”, thus the shebang line “#!/usr/bin/env python3”.

Save and exit editing. Then make the file executable.

chmod u+x pyhello

Done. Our application is ready.

Package the application

Tar and gzip the project directory.

cd /tmp
tar -czf pyhello-1.0.0.tar.gz pyhello

Obtain its guix hash.

guix hash pyhello-1.0.0.tar.gz

Write the package definition

Prerequisite: We are going to put the package definition on our local file system. There are two ways to make Guix aware of our local package definitions: define a local channel or set $GUIX_PACKAGE_PATH. A local channel is simply a git repo + some guix configurations. I’m going to use the second method—setting the $GUIX_PACKAGE_PATH.

Create a directory to store local package definitions.

mkdir ~/my-guix-packages
export GUIX_PACKAGE_PATH="$HOME/my-guix-packages"
guix describe # verify that guix can indeed find your GUIX_PACKAGE_PATH

Write the package definition. Let’s name the file as guixpkgtut.scm. And put these into it:

(define-module (guixpkgtut)
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix build-system copy)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (gnu packages python))

(define-public pyhello
  (package
   (name "pyhello")
   (version "1.0.0")
   (source (origin
	    (method url-fetch)
	    (uri (string-append "file:///tmp/pyhello-" version ".tar.gz"))
	    (sha256
	     (base32 "063mrmgjxymxwsaypln9flm71naxqlgi3kgi1hzyad1c0dg5gklm"))))
   (build-system copy-build-system)
   (arguments
    `(#:install-plan
      '(("pyhello" "bin/"))))
   (propagated-inputs `(("python" ,python)))
   (home-page #f)
   (synopsis "My pyhello package.")
   (description "A package to learn packaging a simply Python script that says hello.")
   (license license:bsd-2)))

To verify that guix can find your “pyhello” package:

guix search pyhello

There you are. You can see that the package location is pointing to your package definition. And the synopsis and description are what you have written above.

To test whether your package definition is working fine, build the package:

guix build pyhello

It succeeds if there is no error during build.

Install and run the installed package

Install in a guix environment:

guix environment --ad-hoc pyhello
pyhello
exit

OR

guix environment --ad-hoc pyhello -- pyhello
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment