manpagez: man pages & more
info autoconf
Home | html | info | man

File: autoconf.info,  Node: Expanded Before Required,  Next: Debugging,  Prev: Present But Cannot Be Compiled,  Up: FAQ

20.8 Expanded Before Required
=============================

Older versions of Autoconf silently built files with incorrect ordering
between dependent macros if an outer macro first expanded, then later
indirectly required, an inner macro.  Starting with Autoconf 2.64, this
situation no longer generates out-of-order code, but results in
duplicate output and a syntax warning:

     $ cat configure.ac
     ⇒AC_DEFUN([TESTA], [[echo in A
     ⇒if test -n "$SEEN_A" ; then echo duplicate ; fi
     ⇒SEEN_A=:]])
     ⇒AC_DEFUN([TESTB], [AC_REQUIRE([TESTA])[echo in B
     ⇒if test -z "$SEEN_A" ; then echo bug ; fi]])
     ⇒AC_DEFUN([TESTC], [AC_REQUIRE([TESTB])[echo in C]])
     ⇒AC_DEFUN([OUTER], [[echo in OUTER]
     ⇒TESTA
     ⇒TESTC])
     ⇒AC_INIT
     ⇒OUTER
     ⇒AC_OUTPUT
     $ autoconf
     ⇒configure.ac:11: warning: AC_REQUIRE:
     ⇒ 'TESTA' was expanded before it was required
     ⇒configure.ac:4: TESTB is expanded from...
     ⇒configure.ac:6: TESTC is expanded from...
     ⇒configure.ac:7: OUTER is expanded from...
     ⇒configure.ac:11: the top level

To avoid this warning, decide what purpose the macro in question serves.
If it only needs to be expanded once (for example, if it provides
initialization text used by later macros), then the simplest fix is to
change the macro to be declared with ‘AC_DEFUN_ONCE’ (*note One-Shot
Macros::), although this only works in Autoconf 2.64 and newer.  A more
portable fix is to change all instances of direct calls to instead go
through ‘AC_REQUIRE’ (*note Prerequisite Macros::).  If, instead, the
macro is parameterized by arguments or by the current definition of
other macros in the m4 environment, then the macro should always be
directly expanded instead of required.

   For another case study, consider this example trimmed down from an
actual package.  Originally, the package contained shell code and
multiple macro invocations at the top level of ‘configure.ac’:

     AC_DEFUN([FOO], [AC_COMPILE_IFELSE([...])])
     foobar=
     AC_PROG_CC
     FOO

but that was getting complex, so the author wanted to offload some of
the text into a new macro in another file included via ‘aclocal.m4’.
The naïve approach merely wraps the text in a new macro:

     AC_DEFUN([FOO], [AC_COMPILE_IFELSE([...])])
     AC_DEFUN([BAR], [
     foobar=
     AC_PROG_CC
     FOO
     ])
     BAR

With older versions of Autoconf, the setting of ‘foobar=’ occurs before
the single compiler check, as the author intended.  But with Autoconf
2.64, this issues the "expanded before it was required" warning for
‘AC_PROG_CC’, and outputs two copies of the compiler check, one before
‘foobar=’, and one after.  To understand why this is happening, remember
that the use of ‘AC_COMPILE_IFELSE’ includes a call to
‘AC_REQUIRE([AC_PROG_CC])’ under the hood.  According to the documented
semantics of ‘AC_REQUIRE’, this means that ‘AC_PROG_CC’ _must_ occur
before the body of the outermost ‘AC_DEFUN’, which in this case is
‘BAR’, thus preceding the use of ‘foobar=’.  The older versions of
Autoconf were broken with regards to the rules of ‘AC_REQUIRE’, which
explains why the code changed from one over to two copies of
‘AC_PROG_CC’ when upgrading autoconf.  In other words, the author was
unknowingly relying on a bug exploit to get the desired results, and
that exploit broke once the bug was fixed.

   So, what recourse does the author have, to restore their intended
semantics of setting ‘foobar=’ prior to a single compiler check,
regardless of whether Autoconf 2.63 or 2.64 is used?  One idea is to
remember that only ‘AC_DEFUN’ is impacted by ‘AC_REQUIRE’; there is
always the possibility of using the lower-level ‘m4_define’:

     AC_DEFUN([FOO], [AC_COMPILE_IFELSE([...])])
     m4_define([BAR], [
     foobar=
     AC_PROG_CC
     FOO
     ])
     BAR

This works great if everything is in the same file.  However, it does
not help in the case where the author wants to have ‘aclocal’ find the
definition of ‘BAR’ from its own file, since ‘aclocal’ requires the use
of ‘AC_DEFUN’.  In this case, a better fix is to recognize that if ‘BAR’
also uses ‘AC_REQUIRE’, then there will no longer be direct expansion
prior to a subsequent require.  Then, by creating yet another helper
macro, the author can once again guarantee a single invocation of
‘AC_PROG_CC’, which will still occur after ‘foobar=’.  The author can
also use ‘AC_BEFORE’ to make sure no other macro appearing before ‘BAR’
has triggered an unwanted expansion of ‘AC_PROG_CC’.

     AC_DEFUN([FOO], [AC_COMPILE_IFELSE([...])])
     AC_DEFUN([BEFORE_CC], [
     foobar=
     ])
     AC_DEFUN([BAR], [
     AC_BEFORE([$0], [AC_PROG_CC])dnl
     AC_REQUIRE([BEFORE_CC])dnl
     AC_REQUIRE([AC_PROG_CC])dnl
     FOO
     ])
     BAR

© manpagez.com 2000-2025
Individual documents may contain additional copyright information.