How to handle gobject-2.0-0 and other library headers

For example, a python project with weasyprint will fail under nix with a message like:

OSError: cannot load library 'gobject-2.0-0': gobject-2.0-0: cannot open shared object file: No such file or directory.  Additionally, ctypes.util.find_library() did not manage to locate a library called 'gobject-2.0-0'

There might be a proper way, but for a quick n’ dirty solution,
enter a nix repl with the package list loaded:

nix repl --expr 'import <nixpkgs>{}'

find the desired package by writing it’s name. it auto-completes with a tab

nix-repl> glib
Β«derivation /nix/store/mwnrirg6ms58v7slply6aahgvj43ysrv-glib-2.76.2.drvΒ»
nix-repl> glib.
glib.DETERMINISTIC_BUILD          glib.depsHostHostPropagated       glib.meta                         glib.postPatch
glib.NIX_CFLAGS_COMPILE           glib.depsTargetTarget             glib.mkHardcodeGsettingsPatch     glib.preCheck
<truncated>

Usually, out.outPath is what you want.

nix-repl> glib.out.outPath + "/lib"
"/nix/store/kaq6wabyc6bgj71ryv4wk7nb824h9kih-glib-2.76.2/lib"

we can check if this is the one by cd’ing into it and looking around

$ tree /nix/store/kaq6wabyc6bgj71ryv4wk7nb824h9kih-glib-2.76.2/
/nix/store/kaq6wabyc6bgj71ryv4wk7nb824h9kih-glib-2.76.2/
β”œβ”€β”€ lib
β”‚   β”œβ”€β”€ gio
β”‚   β”‚   └── modules
β”‚   β”œβ”€β”€ glib-2.0
β”‚   β”‚   └── include
β”‚   β”‚       └── glibconfig.h
β”‚   β”œβ”€β”€ libgio-2.0.so -> libgio-2.0.so.0
β”‚   β”œβ”€β”€ libgio-2.0.so.0 -> libgio-2.0.so.0.7600.2
β”‚   β”œβ”€β”€ libgio-2.0.so.0.7600.2
β”‚   β”œβ”€β”€ libglib-2.0.so -> libglib-2.0.so.0
β”‚   β”œβ”€β”€ libglib-2.0.so.0 -> libglib-2.0.so.0.7600.2
β”‚   β”œβ”€β”€ libglib-2.0.so.0.7600.2
β”‚   β”œβ”€β”€ libgmodule-2.0.so -> libgmodule-2.0.so.0
β”‚   β”œβ”€β”€ libgmodule-2.0.so.0 -> libgmodule-2.0.so.0.7600.2
β”‚   β”œβ”€β”€ libgmodule-2.0.so.0.7600.2
β”‚   β”œβ”€β”€ libgobject-2.0.so -> libgobject-2.0.so.0
β”‚   β”œβ”€β”€ libgobject-2.0.so.0 -> libgobject-2.0.so.0.7600.2
β”‚   β”œβ”€β”€ libgobject-2.0.so.0.7600.2
β”‚   β”œβ”€β”€ libgthread-2.0.so -> libgthread-2.0.so.0
β”‚   β”œβ”€β”€ libgthread-2.0.so.0 -> libgthread-2.0.so.0.7600.2
β”‚   └── libgthread-2.0.so.0.7600.2
β”œβ”€β”€ libexec
β”‚   └── gio-launch-desktop
└── share

line libgobject-2.0.so -> libgobject-2.0.so.0 tells us that this is the right nix expression.

then, in shell.nix, add the environment variable:

export LD_LIBRARY_PATH="${glib.out}/lib"

enter the nix-shell and gobject-2.0-0 should be accessible and you’re free of complaints.

This works for other packages too, but, i heave a feeling that nix must do this for us.
Honestly I wish there was a better (quicker) way to fix these problems.

The proper way of fixing packages using dlopen() or other similar functions (ctypes.util.find_library() in this case) is patching the code:

Using LD_LIBRARY_PATH is discouraged because environment variables are inherited by child processes and LD_LIBRARY_PATH takes precedence over DT_RUNPATH entry stored in ELF programs. As a result, if the program launches a different program, which depends on the library you are adding through LD_LIBRARY_PATH, and you are not careful about using the same build of the library as the one the child program was linked against, you might get ABI breakage.

1 Like