Developers seem to do a lot of fighting with bleeding-edge libraries installed in a --prefix, so I thought I'd share how I develop telepathy-glib (a library) and telepathy-gabble (a program using that library).

~/Collabora/telepathy/tpglib on my laptop is a git clone of telepathy-glib.git, branched using the process I documented on http://telepathy.freedesktop.org/wiki/Git, which is basically:

  • clone the upstream repository (git+ssh://git.collabora.co.uk/git/telepathy-glib.git in this case) into your home directory on the server (git+ssh://people.collabora.co.uk/home/smcv/public_html/git/telepathy-glib-smcv.git in this case)
  • clone that onto your laptop
  • on your laptop, add "upstream" as a remote, tracking the upstream repository
  • this reduces mistakes, because "git push" pushes to origin (which is in my home directory) for review, and "git push upstream" is necessary when I actually want to commit to the upstream repository

~/Collabora/telepathy/gabble is a git clone of telepathy-gabble.git, using the same process.

In my Gabble checkout, I used to configure like this:

cd ~/Collabora/telepathy/gabble
./autogen.sh \
TP_GLIB_CFLAGS="-I${HOME}/Collabora/telepathy/tpglib" \
TP_GLIB_LIBS="${HOME}/Collabora/telepathy/tpglib/telepathy-glib/libtelepathy-glib.la"

This would make libtool link Gabble against the copy of telepathy-glib built by my bleeding-edge git checkout, without ever needing to install it. This allowed me to try out my latest telepathy-glib changes with Gabble's more extensive regression tests, which was a great win.

It also meant I could develop Gabble branches that required a not-yet-released telepathy-glib, and all without touching my system copy of telepathy-glib (the one I use to run Empathy and talk to people - which is the packaged version from Debian unstable or experimental).

The reason I could do this is that I laid out the telepathy-glib source tree in The Right Way™, which is: if a header is designed to be used via #include <my-library/foo.h>, then it goes in a my-library/ directory in the source tree, and includes other headers (even from the same project) with #include <my-library/other.h>.

This means you can just add the top directory of the source tree to your include path (which automake does by default) and the right thing will happen.

(Actually, this is a slight simplification of the truth: because telepathy-glib contains generated headers, you have to add the top directory of the build tree to your include path too, if you want to support out-of-tree builds. Which, of course, you do.)

Other projects that do this correctly include GLib and Avahi. Avahi is a particularly interesting example because it has numerous libraries in the same tarball (including avahi-common, avahi-core, avahi-glib and avahi-gobject, which form a dependency chain).

Projects that don't do this correctly include telepathy-mission-control (which is on my hit list for further swamp-draining) and libtelepathy (which is obsolete).

Today I committed a patch to telepathy-glib, inspired by GStreamer, to generate telepathy-glib-uninstalled.pc. The presence of this patch simplifies the process further, to:

./autogen.sh PKG_CONFIG_PATH=$HOME/Collabora/tpglib/telepathy-glib

This has the same benefits as setting TP_GLIB_CFLAGS and TP_GLIB_LIBS, but is easier to remember, and is more future-proof against changes to telepathy-glib.

It only works because pkg-config has a special case for this situation - if you ask for the package "foo", pkg-config will always look for foo-uninstalled.pc before foo.pc.

(Edited 2009-01-13: putting environment variables on the ./configure or ./autogen.sh command line like ./autogen.sh PKG_CONFIG_PATH=foo is better than putting them in the environment like PKG_CONFIG_PATH=foo ./autogen.sh, since it works around Debian bug #398901 and bugs like it)