Indirect dependencies

Julio M. Merino Vidal jmmv84 at gmail.com
Sat Oct 1 12:40:20 PDT 2005


Hello,

[ please CC me any replies as I'm not subscribed to this list ]

I've been updating the GTK+ packages in the NetBSD Packages Collection
from 2.6 to 2.8 and have hit a quite annoying problem that is possibly
found in pkg-config.  The problem is that the --libs flag outputs linker flags
for indirect dependencies, so a program ends up linked with libraries it
does not use.

Let's see an example.  Consider a very simple GTK+ application that
creates a window and a button within it.  It's clear that this application uses
GTK+, but the developer hasn't knowingly used, e.g., neither Cairo nor
Pango to write its code.  Then he builds his application using the regular
command:

gcc `pkg-config --cflags --libs gtk+-2.0` test.c

And everything apparently goes fine.  Now take a look to the dynamic
libraries the new a.out binary file has, using 'objdump -p a.out'.  You'll
see that a.out is linked against gtk, but also against pango and cairo
and many other things.

This is "incorrect", as I see it.  The binary program now relies on things it
didn't care about, making package maintenance a nightmare.  The program
should have been linked against gtk _only_ (i.e., against the libraries it
really uses in its code).  If the developer really needed to use, e.g., some
Cairo features, he should have had to pass 'cairo' to pkg-config too.

But why is this incorrect?  Suppose we have the B library that internally
depends on A to do something; A's API is not exposed at all to users of B.
Given this dependency chain, a user builds an application against B and
the resulting binaries are explicitly linked against B and A.

At a later time, the B developers drop all A usages from their code for
whatever reason.  When this happens, our user updates B to the new
version and removes A from his system.  Given the nature of dynamic
linking, he shouldn't have to rebuild his application, but he'll have to!
Otherwise, it simply won't work because it will be referring to A, which
is now non-existent.

The real problem I'm facing comes from GTK, though, and it is the
other way around.  In 2.8, Cairo has been added as a dependency.
GTK 2.8 is binary compatible with older versions.  Now consider I have
a program X that requires GTK 2.6.  I build X on my system against
2.8 and pass the resulting binary to a friend who still has 2.6.  He will
be unable to run the program, not because incompatibilities in GTK
but because the binary will refer to Cairo, which may not be installed
on the target system.

Hmm... long mail... but I hope you get idea.

When I look at gtk's pkg-config file, I see:

Requires: gdk-${target}-2.0 atk cairo
Libs: -Wl,-R${libdir} -L${libdir} -lgtk-${target}-2.0

so, all I should be using to link against gtk are the flags shown in Libs,
not the flags provided by all the packages listed in Requires.

Is it there something wrong in the gtk pkg-config file?  If not, do you
feel this issue could be addressed in pkg-config in some way?

Thank you,

--
Julio M. Merino Vidal <jmmv84 at gmail.com>
http://www.livejournal.com/users/jmmv/
The NetBSD Project - http://www.NetBSD.org/


More information about the pkg-config mailing list