The main interface between autoconf and
pkg-config is the
PKG_CHECK_MODULES
macro, which provides a
very basic and easy way to check for the presence of a given
package in the system. Nonetheless, there are some caveats that
require attention when using the macro.
PKG_CHECK_MODULES(prefix, list-of-modules, action-if-found, action-if-not-found)
prefix
Each call to PKG_CHECK_MODULES
should
have a different prefix
value (with
a few exceptions discussed later on). This value, usually
provided in uppercase, is used as prefix to the variables
holding the compiler flags and libraries reported by
pkg-config.
For instance, if your prefix was to be
FOO
you'll be provided two variables
FOO_CFLAGS
and
FOO_LIBS
.
This will also be used as message during the configure
checks: checking for FOO...
.
list-of-modules
A single call to the macro can check for the presence of
one or more packages; you'll see later how to make good
use of this feature. Each entry in the list can have a
version comparison specifier, with the same syntax as the
Requires
keyword in the data files themselves.
action-if-found
, action-if-not-found
As most of the original autoconf macros, there are boolean
values provided, for the cases when the check succeeded or failed. In contrast with
almost all of the original macros, though, the default
action-if-not-found
will end the execution with an error for not
having found the dependency.
By default, the macro will set up two variables, joining the
given prefix with the suffixes _CFLAGS
and
_LIBS
. The names of these variables can
be somewhat misleading, since the former will generally provide
the flags to pass to the preprocessor, rather than the compiler,
such as include paths and macro definitions, and the latter will
provide the library paths as well as the libraries themselves.
On older versions of pkg-config, the
macro will not call
AC_SUBST
on these variables; modern
versions (at least version 0.24) will take care of that
already. Running it twice, though, will not cause problems, so
if you have doubts, you should add a snippet like the following.
AC_SUBST([FOO_CFLAGS]) AC_SUBST([FOO_LIBS])
In addition to defining these variables, the macro also declare
them as important variables through AC_ARG_VAR
so that the user can override the values if needed.
Beside checking for the presence of a package, pkg-config can also check for a minimum (or maximum) version of a package, by using C-style comparison operators, so that you can ensure that the correct version of a package will be used, and not an older or newer version.
You can also check for multiple packages at the same time, by listing one after the other separated by whitespace. This has the positive effect of emitting a reduced amount of code rather than testing them separately, but also brings one further problem: since the variables are supposed to be overridden, merging multiple packages together will require the users to parse the file to make sure they are passing the values for all of them.
Example 4.2. Example of module specifications for PKG_CHECK_MODULES
PKG_CHECK_MODULES([FOO], [foo >= 3]) PKG_CHECK_MODULES([BAR], [bar < 4]) PKG_CHECK_MODULES([BAZ], [baz = 2]) PKG_CHECK_MODULES([DEPENDENCIES], [foo >= 3 bar baz <= 4])
Sometimes, you're supposed to check for given modules only under
some conditions; it's a trivial setup, but it's one of the most
common mistakes. The pkg-config
command is discovered through a separate macro,
PKG_PROG_PKG_CONFIG
that takes care of
identifying the presence (and version) of
pkg-config itself. This macro is
called through AC_REQUIRE
so that is
expanded before PKG_CHECK_MODULES
.
If you have the first call to
PKG_CHECK_MODULES
inside a bash conditional
block, the expansion of PKG_PROG_PKG_CONFIG
will also be conditional, so the following code will fail to
work, when the condition is false:
AC_ARG_WITH([gtk], AS_HELP_STRING([--with-gtk], [Build with the GTK+ interface])) if test "x$with_gtk" = "xyes"; then PKG_CHECK_MODULES([GTK], [gtk+-2.0]) fi PKG_CHECK_MODULES([GLIB], [glib-2.0])
Since the check for GTK+ will not execute by default, you'll receive the following error if
you try to execute configure
without any argument:
% ./configure checking for GLIB... no configure: error: in `/path': configure: error: The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GLIB_CFLAGS and GLIB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see <http://pkg-config.freedesktop.org/>. See `config.log' for more details.
You can solve this problem in two ways; you can either
explicitly call PKG_PROG_PKG_CONFIG
outside
of any conditional, forcing checking for
pkg-config as soon as possible; or
you can rewrite your conditionals to use the proper syntax, as
discussed in Section 1, “M4sh”.
The proper code written in M4sh for the above logic is the following:
AC_ARG_WITH([gtk], AS_HELP_STRING([--with-gtk], [Build with the GTK+ interface])) AS_IF([test "x$with_gtk" = "xyes"], [ PKG_CHECK_MODULES([GTK], [gtk+-2.0]) ]) PKG_CHECK_MODULES([GLIB], [glib-2.0])
Sometimes you need to check for alternative modules; for
instance you might fall-back from
udev to
HAL if the former cannot be
found. You can easily write this by chaining the
PKG_CHECK_MODULES
call, through the
action-if-not-found
parameter, keeping
the best choice outward:
PKG_CHECK_MODULES([UDEV], [libudev], [AC_DEFINE([HAVE_UDEV], [1], [Use UDEV])], [PKG_CHECK_MODULES([HAL], [hal], [AC_DEFINE([HAVE_HAL], [1], [Use HAL]) ]) ])
It's important here to note that all the parameters here are
quoted; this is important; if you don't quote the chained
PKG_CHECK_MODULES
call properly, you will
receive a syntax error when executing
./configure.
As an exception to the rule declared earlier, it's possible to
use two chained calls to PKG_CHECK_MODULES
with the same prefix; this is useful to identify cases where you
need co-variant versions of two packages (explicitly) or if a
package renames its own data file.
PKG_CHECK_MODULES([NM], [libnm-glib],, [ PKG_CHECK_MODULES([NM], [libnm_glib]) ])
Even here, remember to quote the chained call.