Using ``make`` to manage guix home and system profiles

I am not a Makefile expert by any stretch of the imagination but I’ve been using make to simplify managing guix to minimize typing and wanted to share. The motivation for it comes especially with “pinning” channels to avoid rebuilding packages that take a long time to build and to only reconfigure when the configuration files have actually changed or guix has changed after a pull. Corrections and suggestions appreciated since the finer points of make conventions and syntax elude me.

Note: the way I actually use this is to include it in the Makefile where I set GUIX_HOME_CONFIG GUIX_SYSTEM_CONFIG GUIX_MANIFEST. Also I think checking out /var/guix/profiles really helps to understand how guix works.

# -L :: don't follow links
MAKEFLAGS += -L
CURRENT_GUIX = /var/guix/profiles/per-user/${USER}/current-guix
GUIX_HOME_PROFILE = /var/guix/profiles/per-user/${USER}/guix-home
GUIX_DEFAULT_PROFILE = /var/guix/profiles/per-user/${USER}/guix-profile
GUIX_SYSTEM_PROFILE = /var/guix/profiles/system
GUIX_CHANNELS = ${HOME}/.config/guix/channels.scm

# .guix-home links to $(GUIX_HOME_PROFILE) anyway
$(GUIX_HOME_PROFILE): $(GUIX_HOME_CONFIG) $(CURRENT_GUIX)
	guix home reconfigure $< 

# is sudo -E ok?
$(GUIX_SYSTEM_PROFILE): $(GUIX_SYSTEM_CONFIG) $(CURRENT_GUIX)
	sudo -E guix system reconfigure $<

.PHONY = test-guix-home test-guix-system
test-guix-home: $(GUIX_HOME_CONFIG)
	guix home reconfigure --dry-run --no-substitutes $<

test-guix-system: $(GUIX_SYSTEM_CONFIG)
	sudo -E guix system reconfigure --dry-run --no-substitutes $<

$(GUIX_DEFAULT_PROFILE): $(GUIX_MANIFEST)
	guix package --manifest=$<

$(GUIX_CHANNELS):
	guix describe -f channels > $@

$(GUIX_MANIFEST):
	guix package --export-manifest > $@

.PHONY = home
home: $(GUIX_HOME_PROFILE)

.PHONY = system
system: $(GUIX_SYSTEM_PROFILE)

.PHONY = profile
profile: $(GUIX_DEFAULT_PROFILE)

# guix pull && make channels
.PHONY = channels
channels:
	make --always-make $(GUIX_CHANNELS)

My update process looks about like this:

# update current-guix and pin channels
# channels can be "unpinned" by deleting a channel's commit field.
guix pull && make channels

# reconfigure system
make system

# reconfigure guix-home
make home

These I don’t use so much, I included them for “completeness” I guess

# reconfigure default profile, ie ~/.guix-profile
make profile
# also, can export the manifest of the default profile, again, haven't really used this:
make manifest
2 Likes

Thanks for posting this, I’m following a similar approach, I’m not using channels yet and I usually install the profiles manually, I almost never use install_profiles . Here is my makefile (I think that there is a .PHONY statement missing).

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
mkfile_dir := $(dir $(mkfile_path))
mkfile_parent_dir := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))../)

all: container

container:
	guix home container environment.scm -L $(mkfile_parent_dir)

reconfigure:
	guix home reconfigure environment.scm -L $(mkfile_parent_dir)

install_profiles: $(PROFILES)

PROFILES = \
	base  \
	development \
	emacs  \
	graphics \
	shell \
	desktop-utils \
	xfce \
	sway

$(PROFILES): 
	mkdir -p ~/.guix-extra-profiles/$@
	guix package -m $(mkfile_dir)/manifests/$@.scm -p ~/.guix-extra-profiles/$@/$@ -L $(mkfile_parent_dir)

That looks a lot like I had it setup before even using MAKEFILE_LIST.

I only recently started messing around with channels. I have guix/channel setup under version-control and in channels.scm with file:// and the local path for the url. And then guix/modules which are part of GUIX_PACKAGE_PATH and GUILE_LOAD_PATH (why I have to use sudo -E to reconfigure the system profile)

I never implemented the extras profiles but I definitely see the virtue in it. Ideally, just to complicate things, I’d like to get cuirass setup so that it automatically builds manifests from the channel .