6:26 am General

Statically linked shared objects

OK – I can use the time to share something I found interesting.

Yesterday someone was asking on a mailing list I’m on whether there is a way to ship a library which uses glib as a shared object, but without depending on glib being installed.

That is, he has an API, and uses (say) GObject for his object structure, glib for his portability level and so on. But on install, he doesn’t want to force the person to install glib.

His choices seemed to be

  • Ship with glib-2.0.so and do some LD_RUN_PATH magic to find the one he ships with
  • Ship statically linked libs, linked statically with glib

and neither of those were particularly attractive.

So I proposed a third solution, which consisted of generating a shared library, but at the linking stage linking in libglib-2.0.a rather than dynamically linking to libglib-2.0.so. And it works!

$ gcc `pkg-config --cflags glib-2.0` -c module.c
$ gcc -shared -Wl,-soname,libtruc.so -o libtruc.so.0.1 module.o /usr/lib/libglib-2.0.a
$ ldd libtruc.so.0.1
        libc.so.6 => /lib/libc.so.6 (0x40008000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

Look! No glib!

Yves even improved things by finding a libtoolable solution (kind of) – if he wants to build with the static glib, he runs

$ make GLIB_LIBS="/usr/lib/libglib-2.0.a"

to link glib statically.

It’s a pity that pkg-config doesn’t have a –static-libs flag, actually, since this would be a lot cleaner if it did.

Update: Someone (Owen, can I say it was you?) pointed out that this is a horrible thing to do for a number of reasons – first, it won’t work unless your glib was compiled to generate position independent code (in gcc that means compiling with -fPIC), and secondly (which I knew) this is likely to come back and bite you hard in the ass later on if you ever have your shared library linked to an application which is also sharing another libglib-2.0.so.

Why this is so is left as an excercise for the reader 🙂

Comments are closed.