7. Caching Results

For the way autoconf is designed, some tests are quite expensive, in terms of the required work from the system running the configure script. For this reason, in the design of autoconf there is a place for a caching system.

This system provides caching both for the current run (so that the same check in multiple code paths will not require execution of the same test twice) and on-disk caching for multiple runs. At the same time it's also often used to provide fake values to sidestep tests that might lead to wrong results.

Warning

The use of this feature is designed for a very narrow use case, as you can see in Section 7.1, “Why Caching is Not What You're Looking For”. Please think twice before deciding to make use of this technique when running a configure script.

If you're writing a configure.ac file, though, read on, and follow this advice for properly caching the values, as having cached tests available becomes pretty useful especially when debugging mistakes.

7.1. Why Caching is Not What You're Looking For

Often enough, ideas appear of using the caching system of autoconf to avoid repeating the same tests when configuring different projects. This approach is dangerous and unstable for very good reasons.

The first problem is that, while the caching system does provide some sanity checks to ensure that the user hasn't changed settings like compiler and flags used to build between different calls; it does not verify that the tests are executed under the same conditions. For instance, it does not take into consideration the current selected language dialect.

As an example, take two almost identical configure.ac files available as examples of this guide: a default C variant and a C99 variant. These two scripts only check for thisonlyworksonc99.h simply changing the language dialect (not even the full language) changes the results coming from the two different runs:

whynot % ./configure.c CPPFLAGS="-I."
[ ... ]
checking thisonlyworksonc99.h usability... no
checking thisonlyworksonc99.h presence... no
checking for thisonlyworksonc99.h... no
configure.c: creating ./config.status

whynot % ./configure.c99 CPPFLAGS="-I."
[ ... ]
checking thisonlyworksonc99.h usability... yes
checking thisonlyworksonc99.h presence... yes
checking for thisonlyworksonc99.h... yes
configure.c99: creating ./config.status

Because of the way the header is designed, it will only be found when C99 is used (remember that starting from autoconf 2.64, the “usability” test is the dominant one; see Section 4.2, “Checking For Headers”), but if you were to use the same cache file for both scripts, you'd be having some funky, unstable results:

whynot % ./configure.c CPPFLAGS="-I." -C
configure.c: creating cache config.cache
[ ... ]
checking thisonlyworksonc99.h usability... no
checking thisonlyworksonc99.h presence... no
checking for thisonlyworksonc99.h... no
configure.c: updating cache config.cache
configure.c: creating ./config.status

whynot % ./configure.c99 CPPFLAGS="-I." -C
configure.c99: loading cache config.cache
[ ... ]
checking for thisonlyworksonc99.h... (cached) no
configure.c99: updating cache config.cache
configure.c99: creating ./config.status

whynot % rm config.cache

whynot % ./configure.c99 CPPFLAGS="-I." -C
configure.c99: creating cache config.cache
[ ... ]
checking thisonlyworksonc99.h usability... yes
checking thisonlyworksonc99.h presence... yes
checking for thisonlyworksonc99.h... yes
configure.c99: updating cache config.cache
configure.c99: creating ./config.status

whynot % ./configure.c CPPFLAGS="-I." -C
configure.c: loading cache config.cache
[ ... ]
checking for thisonlyworksonc99.h... (cached) yes
configure.c: creating ./config.status

As you can see, autoconf does not validate whether the cache comes from the same configure script, nor if the same compiler options are enabled in both runs.

It doesn't stop here though, since you can write your own tests, you can easily re-use the same cache value variable name for very different meanings, and that will also produce bogus results. In turn bogus results can create multi-layer failures that are also difficult to debug unless it is known that the cache was polluted.

To make the matter worse, a common but subtle problem with cache pollution is related to pkg-config, and the fact that it allows the developer to choose any given keyword to check for any package using the same name; like NEEDED or COMMON, to look for different libraries in different projects also deems the cache to be unusable between them.

Bottom-line suggestion is that you should make use of caching sparingly, when developing code, without touching the configure.ac file nor changing the environment, which is, indeed, a very limited use of caching.