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 can be had here and here. To create an rpm specification, see here.

GNU autotools summary and random notes...

autoconf is m4 macros that...

automake produces makefile templates called in each build build directory; autoconf consumes these by means of, 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



How to set up and use autotools

The two most important and fundamental developer-controlled files are and (see them circled in red in the diagram below). They are created thus:

	-- -------------------------------------------------------------
	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...)

	-- ------------------------------------------------------------
	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_LIBTOOL              # (only if creating a library)
	AC_PROG_INSTALL              # (only if creating a binary to install)

Useful note for reading m4 macros abound. The comment-to-end-of-line symbol is dnl.

Building for debug... done at configure time using an option before running make:

	./configure --enable-debug

It requires the creation of some statements in nearer the top than the bottom:

	dnl This mechanism allows one to enable debug compilations...
	[  --enable-debug     enable debugging and disable optimization],
	[  if test "$enable_debug" = "yes"; then
	AM_CONDITIONAL(ENABLE_DEBUG, test "$enable_debug" = "yes")

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 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—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, 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:

	automake                     # (tells us some files are missing...)
	automake -a
	make install
	make distcheck
	make dist

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:


User-controlled files are circled in red.



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,, 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, 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 and

The best tutorial on these questions seems to be makefile macro and command source read by the automake tool. macro source read by the autoconf tool; can contain Bourne shell script in addition to m4 macros; typically, you should not have a 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
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; need only define AM_CONFIG_HEADER plus a 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 to reach the makefile, you have to use AC_SUBST:

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/, 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/ 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:


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 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,, callable from that works this out and gives the full analysis back to

It works perfectly.