Hi,
So I was trying to resume writing some Gtk programs I've been writing.
That went... very very badly on Guix.
That's the same problem I had years ago on Guix as well.
So here I go describing the problem and some causes in the hope it will help
finding the root cause.
There are multiple definitions (same package version) of the packages glib (and
gobject-introspection and python-pygobject), in the same Guix repo. So far
okay.
But if you aren't very very careful [so basically always], you end up with
different versions of glib in the same profile (even when using "guix shell
--pure" and a manifest) and, eventually, in the same process. glib (and GNOME
in general) cannot handle that. It's just the way the gobject system works, it
assumes that there's just one of each library (and for that matter class,
interface etc). The libraries register into a global gobject (reflection)
system--and if there are two different registries (in two different libraries)
then all hell breaks loose. (for understanding: Guile's module system assumes
the same--and so does Python's). Debugging those problems is a nightmare.
Really, we should make some way in Guix to prevent this from happening for good.
It would be fine if my package, or the manifest, just failed to build--but it's
not okay to refer to two different glibs in the same program and let the user
sort it out at runtime.
In any case, after I rooted out all other problems (that took many many
hours[1]), I STILL had a non-working gtk example program.
So what was up now? Grafts. I found out it works just fine with "--no-grafts"
(and after doing all the rooting-out I did before. Needless to say this is a
non-starter for any professional development! It's completely ridiculous)
And with grafts I don't understand enough to fix that.
Anyway, here comes the description:
Create guix.scm:
(define-public m3
(package
(name "m3")
(version "FIXME")
(source (local-file %source-dir
#:recursive? #t))
(build-system pyproject-build-system)
(arguments
(list #:tests? #f))
(native-inputs
(list pkg-config python-setuptools python-wheel python-pytest))
;; FIXME: propagating glib and gtk+ and gobject-introspection--not even
that forces an error.
(propagated-inputs
(list python-numpy
python-pyopengl python-pyopengl-accelerate
python-pygobject gtk+ glib gobject-introspection
python-pyglm
))
(synopsis "m3")
(description "FIXME")
(home-page "FIXME")
(license license:gpl3+))) ; FIXME
m3
Create manifest.scm:
(load "guix.scm")
(use-modules (gnu packages gtk))
(use-modules (gnu packages glib))
(packages->manifest
(cons* m3
;auto gtk+
;auto glib
;(list glib "bin")
(specifications->packages
(list "python" ;"python-glfw" ; TODO: Is glfw needed ?
;"python-pygobject" ;"python-pyopengl"
"python-pyopengl-accelerate"
;"gobject-introspection"
"sed" ; someone, not us, uses this (probably some guix shell
thing, or a profile hook--who knows).
))))
Create mini.py:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
win = Gtk.Window()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
Do:
guix shell --rebuild-cache --pure
python3 mini.py
It will fail with "unknown signal destroy". Also, all properties are unknown,
and so is the global (reflection) type hierarchy. Then it will segfault.
That's because it has two different glibs loaded.
(A classic is also: "TypeError: gobject `...gtk+MainWindow' doesn't support
property `title'")
It will also fail when using this:
File w:
export
GI_TYPELIB_PATH=/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0
export
GUIX_PYTHONPATH=/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/python3.11/site-packages
export DISPLAY=:0
exec "$@"
So I filter out all environment variables except those three.
In guix shell --rebuild-cache --pure:
$ /run/current-system/profile/bin/env -i ./w
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/bin/python3 mini.py
Traceback (most recent call last):
File "/home/dannym/src/material-ex/m3/mini.py", line 11, in <module>
win.connect("destroy", Gtk.main_quit)
TypeError: <Gtk.Window object at 0x7f8c2c33df80 (GtkWindow at 0x230bb590)>:
unknown signal name: destroy
Segmentation fault
$ /home/dannym/.guix-home/profile/bin/strace -f
/run/current-system/profile/bin/env -i ./w
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/bin/python3 mini.py 2>&1
|/home/dannym/.guix-home/profile/bin/grep 'glib-[^/]*[.]so'
|/home/dannym/.guix-home/profile/bin/grep -v ENOENT
openat(AT_FDCWD,
"/gnu/store/fvfzcrgkn4jvqafhrzm8a6kwxzdjpz72-glib-2.82.1/lib/libglib-2.0.so.0",
O_RDONLY|O_CLOEXEC) = 3
newfstatat(AT_FDCWD,
"/gnu/store/wx0xwypxpgcwa47grr2wgpcdiaws6wfc-glib-2.82.1/lib/libglib-2.0.so.0",
{st_mode=S_IFREG|0555, st_size=1344808, ...}, 0) = 0
openat(AT_FDCWD,
"/gnu/store/wx0xwypxpgcwa47grr2wgpcdiaws6wfc-glib-2.82.1/lib/libglib-2.0.so.0",
O_RDONLY|O_CLOEXEC) = 3
$ /home/dannym/.guix-home/profile/bin/grep -Rial fvfzcr
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/python3.11/site-packages
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/python3.11/site-packages/gi/_gi.cpython-311-x86_64-linux-gnu.so
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/python3.11/site-packages/gi/_gi_cairo.cpython-311-x86_64-linux-gnu.so
$ /home/dannym/.guix-home/profile/bin/grep -Rial wx0xwypxpgcwa
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/python3.11/site-packages
[nothing]
$ /home/dannym/.guix-home/profile/bin/grep -Rial fvfzcr
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0
$ /home/dannym/.guix-home/profile/bin/grep -Rial wx0xwypxpgcwa
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0/GLib-2.0.typelib
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0/GModule-2.0.typelib
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0/GLibUnix-2.0.typelib
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0/Gio-2.0.typelib
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0/GIRepository-3.0.typelib
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0/GObject-2.0.typelib
/gnu/store/ypq7qyv9p5b1k2yb3wk9vhr6y4bwgfsv-profile/lib/girepository-1.0/GioUnix-2.0.typelib
What is going on? Why are there two different glib references, one in the
typelibs (presumably the wrong one--see below) and one in the .so files?
$ guix describe
Generation 223 May 23 2025 19:45:24 (current)
guix 001ceac
repository URL: https://git.savannah.gnu.org/git/guix.git
branch: master
commit: 001ceac870bd116bf963ace23b082733d58e90ec
guix-hpc 7a3f957
[...]
The two different glibs are:
- /gnu/store/fvfzcrgkn4jvqafhrzm8a6kwxzdjpz72-glib-2.82.1
See also: ./bin/gdk-pixbuf-thumbnailer:export
GIO_EXTRA_MODULES="/gnu/store/fvfzcrgkn4jvqafhrzm8a6kwxzdjpz72-glib-2.82.1/lib/gio/modules${GIO_EXTRA_MODULES:+:}$GIO_EXTRA_MODULES"
grep: ./bin/g-ir-generate: binary file matches
$ guix gc --referrers /gnu/store/fvfzcrgkn4jvqafhrzm8a6kwxzdjpz72-glib-2.82.1
/gnu/store/zabag4j88d4rv2dkcw8dcnsciwjm9x95-xdg-desktop-portal-gtk-1.14.1
/gnu/store/zbfzqgaa0fcvs0p0xwbfgs576mknikm2-gnome-autoar-0.4.5
/gnu/store/zcmcz5456mfw2m7q9n1fy2qgjxhl9flg-suil-0.10.20
/gnu/store/zdpdhy8ngyxw7gjpwyr9asbbhp0bfhbv-geeqie-2.0.1
/gnu/store/zgz434zcfqwljqi3a6gmiyp51sgil149-gtk+-3.24.43
/gnu/store/zhrkiisdi44skv9xw4klfrnxwp7xx6x3-libblockdev-3.3.0
/gnu/store/zigdhb3d4yalssh9pm7ssny9yq3vhnss-at-spi2-core-2.52.0
/gnu/store/zn180wzpwyah1mvpadwxzc2hpadyv4r6-qtshadertools-6.7.2
/gnu/store/znvkv19cpk1cc53q0yv21rf3xs6mmlcm-gtk-4.16.13
/gnu/store/zp2xq5pk15biaclgxaaax6b25ibxy4ik-gjs-1.82.1
/gnu/store/zqd0xpbrnbx72mpx331c96y124p4pvs5-kicad-9.0.0
/gnu/store/zrjvfzp4hc15xd0h6b48lx7f1ysxwkw0-pa-notify-1.5.0
/gnu/store/zs4xx0asc4xw5yqf6j19hn0dh3rywy8k-dconf-editor-45.0.1
/gnu/store/zwfsdidllwyr5nqmqcn54d7qxnnmpcw8-qtmultimedia-5.15.15
[... so basically everything else. I daresay that's the "correct" one then?]
- /gnu/store/wx0xwypxpgcwa47grr2wgpcdiaws6wfc-glib-2.82.1
$ guix gc --referrers /gnu/store/wx0xwypxpgcwa47grr2wgpcdiaws6wfc-glib-2.82.1
/gnu/store/03sjrb1fdfzz67c4200c2ks9vyb36h4m-glib-schemas
/gnu/store/0cn36cwax3ah73c8lp0z608c9airf7xg-profile
/gnu/store/11v2qv6yc2iqmbzp4gpzyy2f2ba13jn1-profile
/gnu/store/15zl4g5jf04468w497wvicxj26wcm1lg-glib-schemas
/gnu/store/1s9s6cg5y82m2adn6d8vz9mg7v16zh13-profile
[... so I take it that's the wrong one]
I would prefer there to be a general mechanism in guix for detecting and/or
preventing problems like this, rather than us just finding where this instance
of the problem originated.
[1]
- (Guix-undetected) problem when referring to "gobject-introspection" (with
quotes) (or "glib" or "gtk+") via packages->manifest. In hindsight, that's
obviously a bad idea to do. But it very easy to make this mistake, EVEN IF YOU
KNOW IT IS A PROBLEM. Try adding "gobject-introspection" (with quotes) to
manifest.scm -> all hell breaks loose.
- The environment variables are cumulative and it's very easy to [read: you
almost always] end up with GI_TYPELIB_PATH, LD_LIBRARY_PATH, GUIX_PYTHON_PATH
advertising (at least :P) two different incompatible glibs. That won't work.
- It doesn't even complain when I make the stuff propagated-inputs . Why not?!
Shouldn't the glibs conflict in guix then?