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

File: autoconf.info,  Node: Prerequisite Macros,  Next: Suggested Ordering,  Up: Dependencies Between Macros

10.3.1 Prerequisite Macros
--------------------------

A macro that you write might need to use values that have previously
been computed by other macros.  For example, ‘AC_DECL_YYTEXT’ examines
the output of ‘flex’ or ‘lex’, so it depends on ‘AC_PROG_LEX’ having
been called first to set the shell variable ‘LEX’.

   Rather than forcing the user of the macros to keep track of the
dependencies between them, you can use the ‘AC_REQUIRE’ macro to do it
automatically.  ‘AC_REQUIRE’ can ensure that a macro is only called if
it is needed, and only called once.

 -- Macro: AC_REQUIRE (MACRO-NAME)
     If the M4 macro MACRO-NAME has not already been called, call it
     (without any arguments).  Make sure to quote MACRO-NAME with square
     brackets.  MACRO-NAME must have been defined using ‘AC_DEFUN’ or
     else contain a call to ‘AC_PROVIDE’ to indicate that it has been
     called.

     ‘AC_REQUIRE’ must be used inside a macro defined by ‘AC_DEFUN’; it
     must not be called from the top level.  Also, it does not make
     sense to require a macro that takes parameters.

   ‘AC_REQUIRE’ is often misunderstood.  It really implements
dependencies between macros in the sense that if one macro depends upon
another, the latter is expanded _before_ the body of the former.  To be
more precise, the required macro is expanded before the outermost
defined macro in the current expansion stack.  In particular,
‘AC_REQUIRE([FOO])’ is not replaced with the body of ‘FOO’.  For
instance, this definition of macros:

     AC_DEFUN([TRAVOLTA],
     [test "$body_temperature_in_Celsius" -gt 38 &&
       dance_floor=occupied])
     AC_DEFUN([NEWTON_JOHN],
     [test "x$hair_style" = xcurly &&
       dance_floor=occupied])

     AC_DEFUN([RESERVE_DANCE_FLOOR],
     [if test "x`date +%A`" = xSaturday; then
       AC_REQUIRE([TRAVOLTA])
       AC_REQUIRE([NEWTON_JOHN])
     fi])

with this ‘configure.ac’

     AC_INIT([Dance Manager], [1.0], [bug-dance@example.org])
     RESERVE_DANCE_FLOOR
     if test "x$dance_floor" = xoccupied; then
       AC_MSG_ERROR([cannot pick up here, let's move])
     fi

does not leave you with a better chance to meet a kindred soul on days
other than Saturday, since the call to ‘RESERVE_DANCE_FLOOR’ expands to:

     test "$body_temperature_in_Celsius" -gt 38 &&
       dance_floor=occupied
     test "x$hair_style" = xcurly &&
       dance_floor=occupied
     if test "x`date +%A`" = xSaturday; then


     fi

   This behavior was chosen on purpose: (i) it prevents messages in
required macros from interrupting the messages in the requiring macros;
(ii) it avoids bad surprises when shell conditionals are used, as in:

     if ...; then
       AC_REQUIRE([SOME_CHECK])
     fi
     ...
     SOME_CHECK

   However, this implementation can lead to another class of problems.
Consider the case where an outer macro first expands, then indirectly
requires, an inner macro:

     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])
     OUTER

Prior to Autoconf 2.64, the implementation of ‘AC_REQUIRE’ recognized
that ‘TESTB’ needed to be hoisted prior to the expansion of ‘OUTER’, but
because ‘TESTA’ had already been directly expanded, it failed to hoist
‘TESTA’.  Therefore, the expansion of ‘TESTB’ occurs prior to its
prerequisites, leading to the following output:

     in B
     bug
     in OUTER
     in A
     in C

Newer Autoconf is smart enough to recognize this situation, and hoists
‘TESTA’ even though it has already been expanded, but issues a syntax
warning in the process.  This is because the hoisted expansion of
‘TESTA’ defeats the purpose of using ‘AC_REQUIRE’ to avoid redundant
code, and causes its own set of problems if the hoisted macro is not
idempotent:

     in A
     in B
     in OUTER
     in A
     duplicate
     in C

   The bug is not in Autoconf, but in the macro definitions.  If you
ever pass a particular macro name to ‘AC_REQUIRE’, then you are implying
that the macro only needs to be expanded once.  But to enforce this,
either the macro must be declared with ‘AC_DEFUN_ONCE’ (although this
only helps in Autoconf 2.64 or newer), or all uses of that macro should
be through ‘AC_REQUIRE’; directly expanding the macro defeats the point
of using ‘AC_REQUIRE’ to eliminate redundant expansion.  In the example,
this rule of thumb was violated because ‘TESTB’ requires ‘TESTA’ while
‘OUTER’ directly expands it.  One way of fixing the bug is to factor
‘TESTA’ into two macros, the portion designed for direct and repeated
use (here, named ‘TESTA’), and the portion designed for one-shot output
and used only inside ‘AC_REQUIRE’ (here, named ‘TESTA_PREREQ’).  Then,
by fixing all clients to use the correct calling convention according to
their needs:

     AC_DEFUN([TESTA], [AC_REQUIRE([TESTA_PREREQ])[echo in A]])
     AC_DEFUN([TESTA_PREREQ], [[echo in A_PREREQ
     if test -n "$SEEN_A" ; then echo duplicate ; fi
     SEEN_A=:]])
     AC_DEFUN([TESTB], [AC_REQUIRE([TESTA_PREREQ])[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])
     OUTER

the resulting output will then obey all dependency rules and avoid any
syntax warnings, whether the script is built with old or new Autoconf
versions:

     in A_PREREQ
     in B
     in OUTER
     in A
     in C

   You can use the helper macros ‘AS_IF’ and ‘AS_CASE’ in top-level code
to enforce expansion of required macros outside of shell conditional
constructs; these helpers are not needed in the bodies of macros defined
by ‘AC_DEFUN’.  You are furthermore encouraged, although not required,
to put all ‘AC_REQUIRE’ calls at the beginning of a macro.  You can use
‘dnl’ to avoid the empty lines they leave.

   Autoconf will normally warn if an ‘AC_REQUIRE’ call refers to a macro
that has not been defined.  However, the ‘aclocal’ tool relies on
parsing an incomplete set of input files to trace which macros have been
required, in order to then pull in additional files that provide those
macros; for this particular use case, pre-defining the macro
‘m4_require_silent_probe’ will avoid the warnings.

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