5. Supporting Cross-Compilation

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.

5.1. Paths Handling

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.

Important

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}.

5.2. Tool Calling Conventions

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.

Important

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 "$@"