A minimal jhbuild GNOME session in Debian

I recently setup a GNOME development environment (after about seven years!). That meant starting from scratch since my old notes and scripts were completely useless.

My goal for this setup was once again to have the bare minimum jhbuild modules on top of a solid base system provided by my distro. The Linux desktop stack has changed a bit, specially around activation, dbus, and systemd, so I was a bit lost on how to do things properly.

Luckily around the time I was trying to figure this out, I ran into Florian Müllner’s excellent post on how to work on shell hacking on a Silverblue system.

After removing the container-related bits, I was able to get a reliable jhbuild session integrated into my system.

Here is how to run a development GNOME session, fully integrated into your system.

Register a new session

First, you need to tell GDM about your new session. I was able to do that by creating /usr/share/wayland-sessions/jhbuild.desktop:

[Desktop Entry]
Name=jhbuild GNOME
Comment=This session logs you into a development GNOME

Other distros might have slightly different paths. Check the installed files of your GDM package.

Create a wrapper gnome-session-jhbuild

The above jhbuild.desktop won’t do anything unless you create an executable that starts the session. Most of the script is actually moving some systemd/dbus plumbing around so the right jhbuild services get started.

Put this in /usr/local/bin/gnome-session-jhbuild:

# All credit to fmuellner!
# https://gitlab.gnome.org/fmuellner/silverblue-stuff/-/blob/master/sb-session-setup.sh
set -x

jhbuild() {
  /home/diegoe/.local/bin/jhbuild "[email protected]"

export $(jhbuild run env | grep JHBUILD_PREFIX= | sed 's:\r::')


if [ ! -e $USER_UNIT_DIR ]
  # Pick up systemd units defined in jhbuild
  ln -s $JHBUILD_PREFIX/lib/systemd/user $USER_UNIT_DIR
  systemctl --user daemon-reload


if [ ! -e $DBUS_SERVICE_DIR ]
  ln -s $JHBUILD_PREFIX/share/dbus-1 $DBUS_SERVICE_DIR

# $PATH and a few other things are likely overriden by your distro on your
# ~/.profile file (see /etc/skel/.profile) -- this might cause .desktop files
# to be seen as "broken" (because TryExec/Exec can't confirm there's a valid
# binary to use)
jhbuild run gnome-session

systemctl --user daemon-reload

Don’t forget to mark the gnome-session-jhbuild script as executable!

A minimal jhbuild module list

I can currently get a stable session running with the following modules built:

$ jhbuild buildone adwaita-icon-theme glib dconf glib-networking gvfs gtk+ gtksourceview glade gnome-session gnome-desktop gnome-session gnome-settings-daemon gnome-control-center gjs mutter gnome-shell 

You might need to buildone a few others to satisfy dependencies, but most of the time it’s better to try and fill the missing pieces with the distro -dev packages.

If for some reason your new session doesn’t start and you get stuck unable to log into any session, this is likely because of stuck services or processes. A reboot will clean things up, but make sure you change back to your system’s default session, or you’ll keep trying to log into the broken one!

A word on $PATH and installed apps

I ran into a hair pulling issue where I couldn’t get any of my jhbuild installed apps to appear in the overview unless I had the equivalent app installed on the base system. $PATH was being lost as soon as a gnome-session binary started.

Well, turns out the answer is rather obvious. gnome-session starts a login shell which means that your system takes charge and sets a few things for you, this means that the $PATH visible in calls to jhbuild run or jhbuild shell is dropped, among other things.

The solution in my system was to add the following to my ~/.profile file:

# add jhbuild PATH
if [ -n "$UNDER_JHBUILD" ]; then

The $UNDER_JHBUILD var is set whenever you are running inside jhbuild so you can use it to do other fun things in your shell, like adding an emoji to your prompt:

To get something like the above prompt you can add this to your ~/.bashrc:

if [ -n "$UNDER_JHBUILD" ]; then
  PS1="🍄 $PS1"