The design of the current pkg-config application and the interface of
PKG_PROG_PKG_CONFIG
allows them to be instrumental in proper
cross-compilation of software, when used correctly. This only requires following a few simple
rules.
When cross-compiling packages with multiple dependencies or entire operating system images, the
focus is usually around one specific directory, called sysroot, used as
prefix while mimicking the installation layout of a normal running system. This path needs to be
prefixed to the paths added to the list of searched paths for headers and libraries, i.e., those
that are passed to -I
/-L
, respectively to the compiler and
link editor. At the same time, it should not be compiled in programs to refer to at runtime, nor
it should be used as the destination path during installation.
Since pkg-config original, and main, task is to report flags and paths, it is
crucial that the sysroot handling is taken into consideration. At the time of writing, with
version 0.25 of pkgconfig package, this is achieved mainly through
the PKG_CONFIG_SYSROOT_DIR
variable, which is set to the path of the sysroot,
and is inserted in-between the -I
or -L
flags and the
following path.
The content of PKG_CONFIG_SYSROOT_DIR
is not injected in paths that are
returned by pkg-config --variable, which makes them unsuitable to use
during cross-compilation unless specifically designed to be used at that time.
To design a variable to contain a path that needs to be used at build time, such as the path
where a generation script is, you can prefix it in the .pc
file with
the built-in variable ${pc_sysrootdir}
.
Often, during cross-compilation, builds are mixed of tools to use on the host, and libraries
to install on the target, making it unfeasible to simply set
PKG_CONFIG_SYSROOT_DIR
during the build. To cope with this, the usual
method to set the variable is to use a wrapper script, with either a custom a general
${CHOST}-pkg-config name.
This is supported by the autoconf macros provided by the package,
as they all respect $PKG_CONFIG
if set in the environment, and look for a
target tool (${CHOST}-pkg-config) before falling back to the usual
pkg-config command.
When using the tool to identify variables within a configure.ac
or
Makefile.am
file, it is thus important to not call it directly, but to
rather call $PKG_CONFIG
so to not bypass sysroot awareness.
It also requires other build systems to respect the value set into the environment, the code for which depends on a system by system basis.
The wrapper script should not only set the PKG_CONFIG_SYSROOT_DIR
variable:
when cross-compiling you want to ignore the packages installed in the system, and instead rely
only on those installed in the cross-compiled environment. This is achieved by resetting
PKG_CONFIG_PATH
(which lists additional search paths), and at the same time
setting PKG_CONFIG_LIBDIR
to override the default base search paths.
As of pkg-config version 0.28, a tool-prefixed executable, with the same name as the wrapper documented in this section, is installed by default, both when cross compiling and when not, to support multiple ABI on the same system. This does not, though, make the wrapper approach obsolete, yet.
Example 4.4. Common pkg-config wrapper script for cross-compilation
#!/bin/sh SYSROOT=/build/root export PKG_CONFIG_PATH= export PKG_CONFIG_LIBDIR=${SYSROOT}/usr/lib/pkgconfig:${SYSROOT}/usr/share/pkgconfig export PKG_CONFIG_SYSROOT_DIR=${SYSROOT} exec pkg-config "$@"