Autoconf macros are defined using the
AC_DEFUN
macro, which is similar to the M4 builtinm4_define
macro; this creates a macro named name and with body as its expansion. In addition to defining a macro,AC_DEFUN
adds to it some code that is used to constrain the order in which macros are called, while avoiding redundant output (see Prerequisite Macros).
An Autoconf macro definition looks like this:
AC_DEFUN(macro-name, macro-body)
You can refer to any arguments passed to the macro as ‘$1’, ‘$2’, etc. See How to define new macros, for more complete information on writing M4 macros.
Most macros fall in one of two general categories. The first category
includes macros which take arguments, in order to generate output
parameterized by those arguments. Macros in this category are designed
to be directly expanded, often multiple times, and should not be used as
the argument to AC_REQUIRE
. The other category includes macros
which are shorthand for a fixed block of text, and therefore do not take
arguments. For this category of macros, directly expanding the macro
multiple times results in redundant output, so it is more common to use
the macro as the argument to AC_REQUIRE
, or to declare the macro
with AC_DEFUN_ONCE
(see One-Shot Macros).
Be sure to properly quote both the macro-body and the macro-name to avoid any problems if the macro happens to have been previously defined.
Each macro should have a header comment that gives its prototype, and a brief description. When arguments have default values, display them in the prototype. For example:
# AC_MSG_ERROR(ERROR, [EXIT-STATUS = 1]) # -------------------------------------- m4_define([AC_MSG_ERROR], [{ AS_MESSAGE([error: $1], [2]) exit m4_default([$2], [1]); }])
Comments about the macro should be left in the header comment. Most other comments make their way into configure, so just keep using ‘#’ to introduce comments.
If you have some special comments about pure M4 code, comments
that make no sense in configure and in the header comment, then
use the builtin dnl
: it causes M4 to discard the text
through the next newline.
Keep in mind that dnl
is rarely needed to introduce comments;
dnl
is more useful to get rid of the newlines following macros
that produce no output, such as AC_REQUIRE
.
Public third-party macros need to use AC_DEFUN
, and not
m4_define
, in order to be found by aclocal
(see Extending aclocal).
Additionally, if it is ever determined that a macro should be made
obsolete, it is easy to convert from AC_DEFUN
to AU_DEFUN
in order to have autoupdate assist the user in choosing a
better alternative, but there is no corresponding way to make
m4_define
issue an upgrade notice (see AU_DEFUN).
There is another subtle, but important, difference between using
m4_define
and AC_DEFUN
: only the former is unaffected by
AC_REQUIRE
. When writing a file, it is always safe to replace a
block of text with a m4_define
macro that will expand to the same
text. But replacing a block of text with an AC_DEFUN
macro with
the same content does not necessarily give the same results, because it
changes the location where any embedded but unsatisfied
AC_REQUIRE
invocations within the block will be expanded. For an
example of this, see Expanded Before Required.