It is unfortunate that the most important rule is still a secret today:
configure.ac
s that are rejected by different
versions of Autoconf, or will be rejected in the future. The Autoconf
maintainers often receive complaints about such problems, but they are
really introduced by the users themselves.
The first most common problem is relying on undocumented features. You should never do that. If it is undocumented, it is private, and likely to be changed in the future. The most frequent reason to rely on undocumented feature is to save some typing: you have to address a task, and notice some internal macro performs a job close to your needs. Don't use it: either you copy and adjust it to your very needs --under a different name of course--, or you ask to the maintainers to make a public version of this macro.
The worst case is with people who want to rely on very low level details, or even in some cases, change some low level macros! This is doomed to failure. There are several reasons making maintainers try this perverse game:
configure
. You
should really stick to these standards, experience has proved that they
cover all the needs, possibly in an admittedly convoluted way. And if
they don't, then ask for changes in the GNU Coding Standards: Autoconf
will follow.
AC_PROG_CC
is called I want MY_PROG_CC_HOOK
to be
invoked". You cannot imagine the complex tissue of interdependencies
that already exists in Autoconf! Checking for a compiler for instance,
requires relying on many different preliminary initializations and
checks. The following figures should give you an idea of this amount of
work: AC_PROG_CC
alone produces more than 20Kb of code, almost
900 lines of shell script! And this code is not contiguous: it goes
into three different sections of configure
.
Don't try to hook your macros: just invoke them. Sure, your change is no longer "invisible", the user must call it explicitly, but at least it will be robust.
If you see no option to address your need, ask the Autoconf
maintainers: maybe they know the right way to do it or they can
provide you with a new macro in the official Autoconf.
The second most common problem is people trying to optimize
configure
. For instance they skip long series of tests
needed only for some features the user did not chose. This exposes
you to extremely nasty, stealthy, vicious bugs. Unless you know
exactly what you do (I am here referring to people who have an exact
knowledge of Autoconf), never perform tests conditionally:
depend conditionally on their output!
Here is a simple example of such a broken "optimized"
configure.ac
:
AC_INIT AC_ARG_WITH([fprintf]) if test "x$with_fprintf" = xyes; then AC_CHECK_FUNCS([fprintf]) fi AC_ARG_WITH([sprintf]) if test "x$with_sprintf" = xyes; then AC_CHECK_FUNCS([sprintf]) fi
The following runs clearly demonstrate the point of this optimization:
$ ./configure
as nothing was needed, nothing was checked for. If using fprintf
is requested, then of course, we need a C compiler to check for its
existence, and then check for it:
$ ./configure --with-fprintf checking for gcc... gcc checking for C compiler default output... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for executable suffix... checking for object suffix... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for fprintf... yes
Similarly if both fprintf
and sprintf
are needed:
$ ./configure --with-fprintf --with-sprintf checking for gcc... gcc checking for C compiler default output... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for executable suffix... checking for object suffix... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for fprintf... yes checking for sprintf... yes
As expected, fprintf
and sprintf
are both available on my
GNU/Linux system.
Now, sit back, and look at this:
$ ./configure --with-sprintf checking for sprintf... no
although sprintf
is present!
What happened is that Autoconf knows that checking for a function
requires a compiler for the current language (here, C), so it actually
expands something similar to the following configure.ac
:
AC_INIT AC_ARG_WITH([fprintf]) if test "x$with_fprintf" = xyes; then AC_PROG_CC AC_CHECK_FUNCS(fprintf) fi AC_ARG_WITH([sprintf]) if test "x$with_sprintf" = xyes; then AC_CHECK_FUNCS(sprintf) fi
As a consequence, if fprintf
is not requested,
configure
will not look for a C compiler, and all the
following tests are broken. Never run tests conditionally: depend
conditionally on the results of the tests:
AC_INIT AC_ARG_WITH([fprintf]) AC_CHECK_FUNCS(fprintf) if test "x$with_fprintf" = xyes; then # Depend on the presence/absence of fprintf here. fi AC_ARG_WITH([sprintf]) AC_CHECK_FUNCS(sprintf) if test "x$with_sprintf" = xyes; then # Depend on the presence/absence of sprintf here. fi