3. The PKG_CHECK_MODULES Macro

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.

3.1. Syntax

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.

3.2. Default variables

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.

3.3. Modules specification

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])

3.4. Optional Modules

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])

3.5. Alternatives

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.