We use a slightly extended version of autoconf. See
autoconf --version
for the base version number.
The goal of autoconf is to help you make your program portable, by allowing you, at build time, to adapt the program to the facilities available on the machine on which the program is being built.
You control this through a script called
configure.ac
(which was called
configure.in
in older versions of autoconf).
The autoconf program produces from this a very portable
/bin/sh
script called configure
,
which is distributed as part of your package, and which
the person building the package runs as the first part of
the ./configure; make; make install
incantation.
The ./configure
script probes the system it
is running on, finding compilers, testing the behaviour of
the local unix system, testing whether specific include files
exist or not, testing whether required functions are
available and working as expected, and managing some
configuration by the user, such as allowing them to
specify where the package is to be installed.
This information is only useful if it can be communicated to your program in some way. This is done by the configure script by editing the values of certain `substitution variables' into a list of template files.
For example, you might have a version header
file
version.h.in
, containing the line
The configure variableconst char version[] = "@PACKAGE_VERSION@";
PACKAGE_VERSION
is one of those
substituted by default, and if this file were listed as
one of those to be substituted (by mentioning it in the
autoconf macro
AC_CONFIG_FILES(version.h)
),
then a file version.h
would be created
containing the contents of the version.h.in
file with the @PACKAGE_VERSION@
substituted by the
version number declared within the
configure
file.Although this substitution process can be done for any template file, there are two template files which are used particularly often.
The first is Makefile.in
, which is a
skeleton makefile which
you might write by hand (though see the discussion of
automake in Section 2.1.2). There is an
example of this at the top level of the Starlink build
tree. A typical Makefile.in
might include
lines like
That, combined with autoconf macrosLN_S = @LN_S@ CC = @CC@ myfile.o: myfile.c $(CC) -o myfile.o myfile.c
AC_PROG_CC
and AC_PROG_LN_S
,
would allow you to produce a file Makefile
which was customised to use the C compiler appropriate to
the local environment, and which had, in the makefile
variable $(LN_S)
a command which makes links
between files if the local platform supports that, or
makes hard links or simple copies if that is all that is
possible.As well as configuring the makefile, you may also want to
configure the source code, so that you can take different
actions in your code depending on whether certain
functions or headers are available. That is is most
often done via a particular configured file,
conventionally named config.h
. This second
way of communicating with your source code has the
config.h
file substituted with a number of C
preprocessor #define
statements. For
example, if you included in your configure.ac
file the lines
then the configure script generated from that source would include a test of whether theAC_CHECK_HEADERS([sys/wait.h]) AC_CHECK_FUNCS([strchr])
sys/wait.h
header file was available, and whether the
strchr
function was available in the C
library. If so, the resulting config.h
file
would include the lines
Whereas most configured files are substituted as a result of being mentioned in a#define HAVE_SYS_WAIT_H 1 #define HAVE_STRCHR 1
AC_CONFIG_FILES()
macro, the config.h.in
input file is
configured through
AC_CONFIG_HEADERS(config.h)
, which does its
configuration in a slightly different way.After including this file into your source code with
you can adjust the compiled code with suitable#include <config.h>
#if
preprocessor conditionals, such as
#if HAVE_SYS_WAIT_H #include <sys/wait.h> #endif
It is possible to maintain the config.h.in
file by hand, but generally better to generate it by using
the autoheader application which is part of
autoconf. This scans your configure.ac
and
extracts into config.h.in
mentions of all those
preprocessor defines it finds. Autoheader knows about
macros such as AC_CHECK_HEADERS
above; if you
wish to add further switches to the config.h.in
file, you should do so by calling the autoconf macro
AC_DEFINE
. See the
section 7.1 Defining C
Preprocessor Symbols in the autoconf manual for
further details. Autoheader is one of those applications
run on your behalf by autoreconf (see Section 2.1.4).
Note the angle brackets round config.h
: this
is preferred to double quotes, as it gives the makefile the
option of controlling where the source code is; in the
simplest case this is handed by simply adding
-I.
to the compile line. We don't take take
advantage of this particular flexibility, but it is a good
habit to get into.
An illustrative
configure.ac
might look like this (with line numbers inserted):
1 AC_INIT(mypack, 1.2, ussc@star.rl.ac.uk) 2 AC_CONFIG_SRCDIR(src.c) 3 STAR_DEFAULTS 4 AC_PROG_CC 5 AC_PATH_PROG(PERL, perl) 6 AC_CHECK_HEADERS([sys/time.h]) 7 STAR_MESSGEN(mypack_err.msg) 8 AC_CONFIG_HEADERS(config.h) 9 AC_CONFIG_FILES(Makefile) 10 AC_CONFIG_FILES(myscript.pl, [chmod +x myscript.pl]) 11 AC_OUTPUT
Line 1: This line is required. It declares the package
name, version number, and bug-report address. Each of
these is available for substitution via the substitution
variables PACKAGE_NAME
,
PACKAGE_VERSION
and
PACKAGE_BUGREPORT
. See
autoconf
4.1 Initializing configure
Line 2: This is largely a sanity check, and produces an
error if the named file (in this case src.c
)
is not in the source directory. The source directory is
typically the current directory, but you can specify a
different one using the --srcdir
option to
./configure
, if you have a good reason for
doing that. See autoconf
4.3 Finding configure Input
Line 3: This macro is one of the Starlink extensions, and
the only required Starlink macro. It
sets up the defaults required for building Starlink
applications, and assures the starconf
program that it's being run in the correct directory. See
Section 2.2 for a description of the starconf
application, and Appendix A for details of
the associated macros.
Line 4: This finds a working C compiler, and prepares to
substitute it in the substitution variable
CC
. Presumably the Makefile.in has a line
CC=@CC@
.
See autoconf
5.10.3 C Compiler Characteristics
Line 5: Find a binary called perl
in the
current PATH
and assign the substitution
variable PERL
the full path to it. The most
common way of using this would be for the file
myscript.pl.in
to start off with the line
so that the script ends up with the correct full path. See line 10 and autoconf 5.2.2 Generic Program and File Checks.#! @PERL@ -w
Line 6: check that the system has an include file
sys/time.h
in the include path, and if it
has, make sure that the cpp
variable
HAVE_SYS_TIME_H
is defined. If this were a
real configure file, you would likely have several other
header tests here (in a space-separated list, surrounded
by square brackets), and cpp branching inside your source
code to handle the various cases. See line 8 and autoconf
5.6.3 Generic Header Checks.
Line 7: Another Starlink extension. It
declares that this package has a set of ERR messages in
the given file, and that autoconf should check the
location of the messgen application. The argument is in
fact optional (it merely causes the files to be declared
as pre-distribution files -- see Appendix A.26); this line should be
partnered by a declaration of the variable
include_MESSAGES
in the corresponding
Makefile.am
. See Appendix A.22
for fuller details.
Line 8: This is the macro that makes cpp configuration
information available, by editing the header file
config.h.in
(this file name is conventional, but
not required). See autoconf
4.8
Configuration Header Files. If you
want to put extra information into this file, use the
AC_DEFINE
macro: a declaration like
AC_DEFINE(SPECIALCASE,1)
would insert
#define SPECIALCASE 1
into the
config.h
; autoheader also spots this and puts
a suitable template into config.h.in
. See
the autoconf manual, section Defining C
preprocessor symbols, for further details.
Line 9: This does the work of substituting the results of
the various tests into the files being configured. For each
of the files named in the (space-separated list) argument,
which most typically includes Makefile
,
autoconf expects to find a file of the same name but with
.in
appended, and this is the file which has
the substitutions edited in. (Automake also looks at this
line, and if it sees a Makefile
mentioned
here, it looks to see if there is a corresponding
Makefile.am
already present, and if so, recurses)
Line 10: This is a variant of line 9. The
AC_CONFIG_FILES
macro takes a second argument
consisting of one or more lines of shell script to
post-process the file in question, in this case making
sure that the generated file is executable.
Line 11: This is the line which really does the work. See 4.4 Outputting Files.
Of this script, it is lines 1, 2 and 11 which are absolutely required, along with something like line 9 to make the configure script do something useful.
It is useful to think of the configure.ac
file as being the template for the final
./configure
script, with the autoconf macros
simply expanding to (large chunks of) shell script during
translation by the autoconf program. This isn't the whole
truth, but it suffices for almost all purposes. About the
only place where this view might deceive you is if you
wished to modify a file after it was generated by
AC_CONFIG_FILES
for example; if you did that
immediately after the AC_CONFIG_FILES
line it
would fail, since the code which generates the files is
in a different place from the AC_CONFIG_FILES
line -- that is why AC_CONFIG_FILES
has
its second argument. With this view it is natural that
you can add any other shell scripting to your
configure.ac, adding any tests and switches you fancy.
You communicate the results of your scripting to the
output files by making shell variables into substitution
variables, and the way you do that is by calling
AC_SUBST
on them. Thus, after
any occurrences of the stringwibble='' ... # lots of clever scripting AC_SUBST(wibble)
@wibble@
in the
substituted files will be replaced by the value of
wibble
at the end of the
./configure
script.Autoconf does its work by running the
configure.ac
file through the text processor
GNU m4
, and this can cause occasional
surprises.
M4 is a macro language, intended for very much the sort of rewriting that autoconf does. When m4 processes a file, anything at all that looks like an m4 macro is substituted, so that there is no macro invocation character like the backslash in TeX. Macros can take arguments, delimited by round brackets and separated by commas, as illustrated above.
The first oddity is to do with comment characters. The
default m4 comment character is #
, but
since this is also the shell script and makefile comment
character, autoconf makes it an ordinary character.
Thus to add comments to a configure.ac
file
which won't make it into the ./configure
file, you should prefix them with the m4 macro
dnl
(which means `delete to next newline'),
as in
There's no harm in includingdnl This is a comment AC_INIT(...)
#
-style
comments in your configure.ac
file and
allowing these to be passed through to the output file,
since `got-here' type comments can sometimes help you
debug the ./configure
script.The default m4 quote characters are the left and right single quotes, but autoconf changes these to left and right square brackets. You need to use these in two circumstances, firstly when you have a multi-word argument to a macro, and particularly when that argument contains a comma, and secondly if a piece of text looks like a current m4 macro. In general, if you need to care about m4 quoting rules, you're in trouble, but see section 8.1 M4 Quotation in the autoconf manual, for some advice.