Managing a Software Package using the GNU Autotools

You may have seen software you can easily build and install using the following commands:

./configure
make
make install

If the configure script follows the GNU coding standards you can choose some parameters like ./configure --prefix=/opt/local to change the behavior in a consistent way. This particular example is how the MacPorts people like to configure their packages. In general, using configure will make it easy to create software packages for a variety of systems (like Debian, Redhat, MacPorts, etc.).

Writing a configure script that works in all circumstances can be a challenge. For this reason software has been written to help with the task. This collection of tools has grown over time and is generally known as the GNU build system or shorter as autotools. Its main components are autoconf and automake.

Learning the autotools can be hard if you dive into the comprehensive manuals (for autoconf, automake, etc.) or if you use an existing software package as an example. There are so many details pertaining to the particular case that you quickly loose sight of the forrest for the trees.

So let us just use the most simple example we can think of. This allows us to see the structure of an autoconfiscated package. It will be overkill for the example but if your package starts to grow it will be a good thing if you started small.

The Example Program

Let us take a simple script called foobar that does not do much and more precisely that does not depend on libraries or a compiler.

 #!/bin/sh
echo 'frobnicating foo...'
sleep 1
echo 'frobnicating bar...'
sleep 1
echo 'done.'

All we want is that this script ends up in the directory that holds programs and script, i.e., that is in the $PATH of the target system. With the default prefix this will be /usr/local/bin/foobar and with a --prefix=/opt/local it will be /opt/local/bin/foobar.

The Autotools Files

Autoconf and automake need two files (at least for this simple case). Let us look at them.

configure.ac

AC_INIT([myfoobar], [1.0], [coder@example.org])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

This file is written in the M4 preprocessor language. It has function calls (or macros) that consistently use two levels of parentheses. The macro itself uses round parentheses () and each argument is surrounded by square brackets []. Arguments are separated by commas , and the square brackets protect the arguments against macro expansion should one word be the same as a known macro. Also inside brackets a comma will not separate two arguments.

AC_INIT sets some parameters for the package. The package name myfoobar does not need to be the same as the name of the program although often it is. The other two parameters is the version number and the e-mail address of the author. AC_INIT can have more parameters which you can find in the manual.

AM_INIT_AUTOMAKE sets the default options for automake. These values shown are the recommended ones. For details consult the manual.

AC_CONFIG_FILES lists the files that configure needs to generate. In our simple case we only need the Makefile.

AC_OUTPUT is a macro that needs no parameters. It instructs configure to generate the files mentioned above.

Makefile.am

dist_bin_SCRIPTS = foobar

All we have to do is define this one variable. The name of the variable is relevant and tells automake what to do with value after the equal sign. The bin part specifies the $prefix/bin (e.g., /usr/local/bin) directory as expected. There are a few allowed values like etc, man, lib, or include. There are ways to define your own. The SCRIPTS part says that this is a program that needs not to be compiled. Some other values are PROGRAMS, MANS, or DATA. With dist we tell automake that our foobar script needs to be part of the distributed source package.

For more details consult the automake manual.

Creating the ''configure'' script

Now we can run

autoreconf --install

to generate the configure script. The --install option tells it to generate some helper files if necessary. You may want to add a --force option if you already used autoreconf earlier and want to make sure to use the latest helper files.

autoreconf will call automake, autoconf, and possibly other programs from the GNU build system and will generate the Makefile.in in addition to the configure script. This is all you need.

Creating a Distributable Package

With

./configure
make dist

you can create the file myfoobar-1.0.tar.gz that you can distribute. The name of the packages and the version number are taken from configure.ac .

If you do

./configure
make distcheck

you can also check for inaccuracies in your configuration in addition to creating the .tar.gz file.

If you want to clean up you can call

make distclean

A more Complicated Example

If you want to see how to use the autotools to build a program that needs to be compiled you can look at the amhello programm in the automake manual.

Integration with Git

If you use a version control system like Git it is recommended that you only track files that you edit yourself. You should not track files that are generated. For Git you can use the following .gitignore file:

/configure
/Makefile.in
/aclocal.m4
/autom4te.cache
/install-sh
/missing

Further Reading