The pkg-config file format provides two main interfaces to declare
dependencies between libraries (and other project using these files), as described in Section 1, “File Format of *.pc
Files”: the Requires
definitions and the
Libs
definition. Both of them also provide a .private
variant. While this might sound redundant, their use is different enough to warrant their
presence.
The Requires
definition allows to import dependency information directly from
another .pc
data file, including compiler flags
(Cflags
), libraries, and its own set of required libraries.
The Libs
definition instead only lists libraries, without inspecting their
dependencies; this should usually be used for libraries that do not provide a
.pc
file, such as system libraries.
The reason why two sets of definitions are present has to be found in the way the link editors work in the UNIX world (Windows and Mac OS X are different worlds), and in particular in the world of ELF: shared libraries carry internally the list of their dependencies, but static libraries (archives) do not. This means that if you're linking statically to something, you need to provide its dependencies explicitly.
The decision on where to list a given dependency should follow a semantic approach: does the
current library augment the dependency, or wrap around it? If the consumers of the current
library still need to use interfaces from the former, the dependency should be visible directly
to the consumers, so declare it as Requires
or Libs
. If,
on the other hand, the dependency's interface is wrapper and hidden from the consumers, it
should be declared in Requires.private
or Libs.private
.
When using the private definitions for dependencies, the behaviour of pkg-config will change depending on whether it's targeting dynamic or static linking. In the former case, private dependencies will not be listed in the output, as they are not exposed to the consumer directly, and shared libraries will handle them.
Contrarily, when the link is static, it'll expand (recursively) all the private dependencies so that all the libraries are brought in. This is once again needed because of the way UNIX link editors work, as archives do not list their own dependencies directly. While libtool actually provides a wrapper around these archives, they are getting less and less common, so relying on them is not a good idea.
Unfortunately, at least as of February 2013, there is no easy way to tell at once to an Autotools-based build system that you intend to link statically; this means that the most common way to signal this to pkg-config becomes the command ./configure LDFLAGS="-static" PKG_CONFIG="pkg-config --static".