Notes on Autotools
Check out illustrations below in addition to perusing the links and the short
text samples (not meant to replace actual reading of the source material).
Better comments on configure.in
can be had here and Makefile.am here. To
create an rpm specification, see here.
GNU autotools summary and random notes...
autoconf is m4 macros that...
create a script named config for the software package based
on a template file
config probes the platform headers for portability-related
informaiton; based on this, it produces platform-specific make- and
header files
these makes and headers are used on the fly to produce the binaries
for the supported platform
automake produces makefile templates called Makefile.in in
each build build directory; autoconf consumes these by means of
Makefile.am , also in each subdirectory.
automake requires the presence and efforts of Autconf.
libtool does not require autoconf nor automake ; it
builds libraries in a portable way.
Autotools help produce code conforming to the GNU specification by generating
boiler-plate sources before coding begins.
Autotools facilitate...
multidirectory builds of software packages
automatic configuration
automatic makefiles
support for test suites
shared libraries
(autoconf )
(automake )
(libtool )
How to set up and use autotools
The two most important and fundamental developer-controlled files are
Makefile.am and configure.in (see them circled in red in the
diagram below). They are created thus:
-- Makefile.am -------------------------------------------------------------
bin_PROGRAMS = id # (if creating a binary to install)
nosint_PROGRAMS = id # (if creating a binary that won’t be installed)
hello_SOURCES = id.c id.h
hello_LDFLAGS = -L/opt/quest/lib
hello_LDADD = -lvas
lib_LTLIBRARIES = libid.a # (if creating a library)
(other macros as needed...)
-- configure.in ------------------------------------------------------------
AC_INIT(hello.c)
AM_INIT_AUTOMAKE(hello,0.1)
AM_CONFIG_HEADER(config.h)
AM_PROG_LIBTOOL # (initialize libtool if creating a library)
AC_CHECK_CC # checks for gcc (?)
AC_HEADER_STDC # checks for headers
AC_CHECK_HEADERS(errno.h stdio.h stdlib.h string.h vas.h)
AC_CHECK_FUNCS(fprintf free)
AC_PROG_CC
AC_PROG_LIBTOOL # (only if creating a library)
AC_PROG_INSTALL # (only if creating a binary to install)
AC_OUTPUT(Makefile)
Useful note for reading configure.in : m4 macros abound. The
comment-to-end-of-line symbol is dnl .
Building for debug...
...is done at configure time using an option before running
make :
./configure --enable-debug
make
It requires the creation of some statements in configure.in nearer the
top than the bottom:
dnl This mechanism allows one to enable debug compilations...
AC_ARG_ENABLE(debug,
[ --enable-debug enable debugging and disable optimization],
[ if test "$enable_debug" = "yes"; then
DEBUG_CFLAGS="-g3 -DDEBUG"
else
DEBUG_CFLAGS="-O2 -DNDEBUG"
fi
]
)
AM_CONDITIONAL(ENABLE_DEBUG, test "$enable_debug" = "yes")
CFLAGS="$DEBUG_CFLAGS"
How it works: when autoconf is run, it sets up the state that, if
defined on the configure commandline, the “--enable-debug”
option will be reflected in the $enable_debug variable having value
yes . This state being tested, DEBUG_CFLAGS , a macro, is
established as being “-g3 -DDEBUG”.
Also, macro ENABLE_DEBUG is established for use by Makefile.am
if needed (it doesn’t have to be used).
Finally, standard macro CFLAGS is established before Makefile
is generated (this cannot apparently be done in Makefile.am —I know
because I tried doing it and it leads to a complaint about CFLAGS
already being set up).
So, when Makefile is run with make , it gets the flags as they
were set up in configure.in , which will be the optimized ones if the
debug option to configure isn’t present. Note that, by default,
autotools like to set up CFLAGS as “-g -O2” for some,
unexplained reason.
Then, run the following sequence of commands:
aclocal
autoconf
automake # (tells us some files are missing...)
touch NEWS README AUTHORS ChangeLog
automake -a
./configure
make
make install
make distcheck
make dist
(etc.)
To cause automake to supply default versions of missing files, ...
automake --add-missing
That will give you things like:
russ@taliesin:~/php-vas> ll install-sh
lrwxrwxrwx 1 russ users 34 2007-0308 install-sh -> /usr/share/automake-1.9/install-sh
Good links on autotools...
The version of the GNU tools that are in use presently (early 2006) include:
autoconf 2.59-81
automake 1.9.6-2
make 3.80-188
libtool 1.5.18-2
Books
http://sourceware.org/autobook/
—the only bound book on GNU autotools,
can be read on-line at this address,
but is out of date as big changes in November 2003 make it obsolete
except as for use by comparison. The tools versions employed when the
book was written were autoconf (2.13), automake (1.4-p5)
and libtool (1.4.2).
Diagram
User-controlled files are circled in red.
Flowchart
Fileset
In the illustrations on this page, some trouble has been gone to to illustrate
that the .in files are inputs to autoconf . In one case,
configure.in , it is manufactured by you. In other cases, it is the
output of automake , autoheader , etc. In all cases, it is
input to autoconf .
It is useful to think of the autotools as mere filters that massage a certain
number of files created intelligently by the consumer dumbly into successively
intermediate, then final files by autotools. Then, via make , all of
the intermediate files are “filtered” into a final product, usually
a binary and/or a set of other files.
aclocal , or local “auto-configuration” filter is another
intermediary.
A script, usually named bootstrap.sh , is created to run all the
intermediaries (aclocal , autoheader , automake ,
autoconf ) preliminary to invoking ./configure
and make .
The following files are explained. Unless otherwise noted, the location for the
file is in the same directory as Makefile.am and configure.in .
The best tutorial on these questions seems to be
http://seul.org/docs/autotut .
Makefile.am
makefile macro and command source read by the automake
tool.
configure.in
macro source read by the autoconf tool; can contain
Bourne shell script in addition to m4 macros; typically, you should
not have a configure.in in each subdirectory, but only in
the dominating one.
aclocal.m4
any m4 macro definitions of your own, however, this
file also usually contains about 800 lines put there by autoconf
for its own purposes; is it alright to create it before the first
run of autoconf?
configure
typically the output from autoconf and
configure.in .
acinclude.m4
more m4 macros if using aclocal.
config.h
great approach to avoiding long gcc command lines by
collecting preprocessor defines in one place included in every
module; configure.in need only define AM_CONFIG_HEADER plus
a config.h.in with any additional definitions you desire
must be created or autoconf will complain.
acconfig.h
your chance to add yet more defines to config.h
before it’s generated by autoconf.
INSTALL
standard installation text; explains to downloading
consumer how to install software including how to build it.
COPYING
contains the GNU General Public License (GPL) if your
software is GPL; automake doesn’t seem to insist upon it.
README
for the tarball;
AUTHORS
more complicated than mere list of authors involved,
but mostly only that.
ChangeLog
as name implies, contains whatever change you want to
reveal to the consumer.
Getting macros out to the Makefile...
In order for a macro definition in configure.ac to reach the makefile,
you have to use AC_SUBST :
configure.ac:
PHP_INCLUDE_PATH=/usr/include/php
...
AC_SUBST(PHP_INCLUDE_PATH)
Makefile.am:
INCLUDES = -I$(PHP_INCLUDE_PATH)
The problem of libraries...
To check for the existence of standard or extra-standard functions in the
library, use:
AC_CHECK_FUNCS(fprintf free)
On the other hand, to check for symbols consumed from third-party libraries,
do:
AC_CHECK_LIB(libbase-name , symbol , exists-action , doesn’t exist-action )
For example:
AC_CHECK_LIB(vas, vas_id_get_name,,AC_MSG_ERROR(Where’s the VAS SDK library?))
(All arguments after the second are optional.)
This won’t work unless the VAS SDK library is put onto /usr/lib .
Using Linux construct, /etc/ld.so.conf , will solve this for the actual
load from the executable (ELF) binary, but will not solve
autoconf ’s inability to find it. A symbolic link from
/usr/lib to /opt/quest/lib/libvas.a and
/opt/quest/lib/libvas.so will. This isn’t very satisfactory.
Bring in the howitzer...
Another way cool macro to use is AC_SEARCH_LIBS :
AC_SEARCH_LIBS[ cos, m ]
This puts the library into $LIBS thus:
$LIBS=-lm
However, no matter what you do, it cannot locate a symbol in a third-party
library regardless of how you specify it (name, filename, full path) even if
you add its parent directory to PATH . Bummer.
Don’t attempt to use [ or ]
A case in point (one experience). I know I’m not giving enough background
here, but I make a useful point that cannot be mistaken.
So, I have to use shell commands to locate my library and version.
What blocks nice tricks like the grep -v ^[ld] is a fundamental
problem I now feel I’ve accurately observed: Even though in
configure.ac I’m not trying to do this stuff inside an m4
macro, you simply can NOT use brackets ( [ ] ) meaningfully. It
appears to discard them without telling you.
So, led to believe that the shell invoked by autoconf is some rather
poor relative of any I have ever worked in, I was finally reduced to the
realization that everything I did in shell worked as long as it didn’t
make use of brackets.
For me, at least, this is some kind of quantum leap through this mess.
My solution? Distribute a script, libvas-info.sh , callable from
configure.ac that works this out and gives the full analysis back to
configure.ac .
It works perfectly.