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?


Reply via email to