The configuration stages of different software packages are never entirely unique. There are repetitive, similar (if not outright identical) tasks that have to be completed for different packages, with more or less sharing between them.
To avoid repeating the same code over and over, most programming languages provide the facility of functions; m4 instead, being a macro language, provides macros, which share not only the name but also most of the details with the C preprocessor macros: they are expanded inline, they don't have their own variables' scope, the parameters are not typed, and so on.
Confusingly enough, the macro to define new macros is called
AC_DEFUN
which often confuses the
developers into thinking about them in terms of functions. This
can lead to many problems, which is why I suggest to always
explicitly think and talk about them in terms of
macros.
Since autoconf macros are often developed to solve generic problems, rather than specific problems of a project (otherwise direct M4sh code would be good enough for most uses), they are often shared across packages and across projects.
In the past, most packages shipped their own macro file with a standardised macro to search for them in a system at build time, making use of particularities of the package, or through configuration helper scripts. For most projects these have been phased out in favour of pkg-config.
There are, though, reusable macros, shipped with various projects or present in archives, such as the Autoconf Archive. Depending on the nature of the macro, the file where it is written is either installed in the system (to be used by autoconf directly) or is simply available to be picked up from the source distribution.
To take two examples, the pkg.m4
file that is shipped with
pkg-config is installed in the system, while the
attributes.m4
macro file, shipped with xine-lib,
PulseAudio and the LScube projects, is
simply shared by copying it out of the source distribution or repositories.
When using external macro files to store custom and generic macros (which is, most of the time, the suggested approach), you have to tell autoconf where to look for them. Many different approaches are available for this task, and this guide will try to explain most, if not all, of them.
While there is no functional requirement for that, the guide will assume that all your macro
files are inside the m4/
directory; this is the most common directory
used to keep the macro files, and for the principle of least surprise, you probably want to
also put yours there.
Some projects use other directory names (autoconf/
,
ac-macros/
, …) but this often adds more work for the distributors
packaging or fixing the software, since they have to check where to find the macros.
When not using automake, and just relying on autoconf, the macro files are not picked up by default.
Indeed, if you just added your testing macro in the configure.ac
file,
you'll be finding it just copied over in the final configure
:
% cat m4/test.m4 AC_DEFUN([AUTOTOOLS_MYTHBUSTER], [ AC_MSG_CHECKING([testing]) AC_MSG_RESULT([ok]) ]) % fgrep AUTOTOOLS_MYTHBUSTER configure.ac AUTOTOOLS_MYTHBUSTER() % fgrep AUTOTOOLS_MYTHBUSTER configure AUTOTOOLS_MYTHBUSTER()
Indeed, what you have to do is to force the actual inclusion of the macro file in the
configure.ac
file.
Example 1.5. Including an External Macro File without automake
AC_INIT m4_include([m4/autotools_mythbuster.m4]) AUTOTOOLS_MYTHBUSTER
The m4_include
directive works quite like the
#include
directive of the C programming language, and simply copies
over the content of the file.
To not include comments starting with #
in the generated
configure
script call the m4_include
before the
AC_INIT
.
The only file that is read by autoconf other than the
configure.ac
file is the aclocal.m4
file. This file
is often managed with the aclocal utility that ships with automake, so it's really suggested not to make use of it manually.
The autoconf tool has a parameter -I that allows adding a directory to the search path for the conversion. This command is also not used to discover macro files.
What it is useful for is to avoid using the full path name of a macro file, letting it be picked up either from the system or from the local directory (giving priority to the system copy).
AC_INIT m4_include([pkg.m4]) PKG_PROG_PKG_CONFIG
In this case, the macro file is included with the generic base name value of
pkg.m4
instead of m4/pkg.m4
. If the macro file is
available to the system (in /usr/share/autoconf
for instance) the macro
will be picked up from there; otherwise, if autoconf -I m4 is used, the
one in the m4
directory will be used.
Starting from version 2.58, autoconf provide the macro
AC_CONFIG_MACRO_DIR
to declare where additional macro files are to be put
and found. The argument passed to this macro is commonly m4
.
This macro, for the longest time, has been used only by libtool starting from version 2.0, to identify where to copy its own macro files when using libtoolize --copy.
Starting from version 1.13, automake augments autoconf with a macro
called AC_CONFIG_MACRO_DIRS
, that provides a space-separated list of
directories to use for looking up m4 files. The same macro will be available as part of
autoconf 2.70.
The list of directories declared in these macros will be used by the
aclocal tool to look up the macros called by the
configure.ac
file. After all the macros (and their dependencies) have
been gathered, it will create a aclocal.m4
file that
autoconf will use.
% cat configure.ac AC_INIT PKG_PROG_PKG_CONFIG % aclocal % ls -l aclocal.m4 -rw-r--r-- 1 flame flame 5775 2009-08-06 10:17 aclocal.m4 % fgrep PKG_PROG_PKG_CONFIG aclocal.m4 | grep AC_DEFUN AC_DEFUN([PKG_PROG_PKG_CONFIG], % autoconf % ./configure checking for pkg-config... /usr/bin/pkg-config checking pkg-config is at least version 0.9.0... yes
In contrast to what autoconf does,
aclocal takes its macro files from the
/usr/share/aclocal
path, where most software installs them, and copies
the macro files where they are defined directly inside aclocal.m4
,
appending them to one another. Then autoconf reads the
file as if it was part of its macros' library.
Local macros will also be looked up, but their content will not be appended to
aclocal.m4
. Instead, it will use the m4_include
directive, to include the local file.
The search path for local files, as of version 1.13 of automake, is
defined by the directories listed in AC_CONFIG_MACRO_DIR
and
AC_CONFIG_MACRO_DIRS
arguments. Previously, it was common to use a
variable defined in Makefile.am
(ACLOCAL_AMFLAGS
) to
pass extra parameters to aclocal. This behaviour is deprecated and
will soon not be supported.
% cat configure.ac AC_INIT AC_CONFIG_MACRO_DIR([m4]) AUTOTOOLS_MYTHBUSTER % aclocal % cat aclocal.m4 # generated automatically by aclocal 1.13 -*- Autoconf -*- dnl […] snip […] m4_include([m4/autotools_mythbuster.m4]) % autoconf % ./configure checking testing... ok
In addition to searching its own directory and the include path given on the command line,
the aclocal tool takes into consideration another file:
acinclude.m4
. This file is also copied (rather than included) in the
final output of the tool, and then picked up by autoconf.
This file is often used to put together multiple macros from different macro files, without
having to use an m4/
directory or equivalent. This usage is discouraged
by this guide, because it often leads to overly long files, with no logical distinction
between macros.
Once again, this has to be considered an old interface kept for compatibility; the
m4/
macro directory with its macro files is the suggested method of
adding new macros to a project.
Since macro calls are expanded inline, multiple calls to the same
macro will cause more code to be emitted in the final
configure
script. In turn, this will
require a longer time to execute the configure phase, both
because more code is to be executed, and because
bash gets easily slowed by long
scripts.
To solve this problem, a subset of macros can be called through
the so-called “Once-Expansion”. Such a macro is usually immune
to most of the changes in the current environment, so that the
place in the configure
script where it is
called is not important for the successful completion of the
configure phase.
Of course, this comes with a price: once macros might not be called conditionally, and they lack configurable side effects on success or failure (they can have standard side effects like setting variables and cache values, and generating definitions).
To create a once macro, you just define it
almost normally, but using the
AC_DEFUN_ONCE
definition macro. A macro
created this way should not make use of parameters that can
change between calls; it either has to take parameters used to
identify the project or the options to enable (think
AC_INIT
) or none at all.
Similarly to once-expanded macros, recent autoconf versions provide the so-called “once-expanded checks” for functions, headers, declarations, …
The use of these macros is slightly different from the standard checks, since they follow, for the most part, the same rules as once-expanded macros: with the exclusion of the parameter with the list of elements to check for, there can be no parameters executing side-effects or changing the default behaviour.
For instance when checking for a series of headers with once-expansion, you'd just write it as this:
AC_CHECK_HEADERS_ONCE([header1.h header2.h header3.h])
In this case you cannot stop when the first of these is found, you cannot error out when one is not found either, and finally you cannot pass further headers, not even to fix problems with headers present that cannot be compiled.
Like once-expanded macros, once-expanded checks are expanded as early as possible, bundled together, and at most one time. This reduces the amount of code generated, especially if multiple code paths would check for the same header multiple times.