Setting up Autoconf

In this tutorial, you will learn how to set up an empty Autotools build system.

This is the first tutorial in the Setting up a real-life GTK application series.

To get started, we will build up an Autotools project from scratch. First create a directory called app-skeleton1. In the directory, create an empty file called Makefile.am. (For example, you can type touch Makefile.am in a terminal.) This is an Automake file, which is where we put the instructions for transforming source code into programs. We will fill it later. First, we will use Autoconf to configure our project.

Open a new file in the directory with your editor and call it configure.ac. This is an Autoconf file, where we put instructions for what tools we would like to use to build our project. We also note what capabilities of the system we would like to use, so that Autoconf can check to make sure the system has those capabilities. In configure.ac, write:

AC_INIT([App Skeleton], [1], [philip.chimento@gmail.com])
AM_INIT_AUTOMAKE([-Wall foreign])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

This file consists of macros that Autoconf expands into shell scripts. Macros beginning with AC_ are Autoconf's own macros, and macros that start with AM_ belong to Automake. Notice that the macros' argument lists are enclosed in parentheses, and each argument is enclosed in square brackets. The square brackets are quotes. They are quite complicated and explained in detail in the Autoconf manual, but a good rule of thumb is: always quote each argument of a macro. We will go through these macros one by one:

AC_INIT

This initializes Autoconf, telling it the name and version of the project. The third, optional argument is an e-mail address for reporting bugs in the program. You can replace it with your own e-mail address if you like, but bugs in the tutorial programs should probably still be reported to me.

AM_INIT_AUTOMAKE

This tells Autoconf that we will be using Automake (yes, it is possible to use one without the other.) It also initializes Automake and configures it. -Wall and foreign are Automake options. Note that they are not separate arguments to the AM_INIT_AUTOMAKE macro; all the options are one space-separated argument.

-Wall tells Automake to have the compiler report all warnings when compiling our program, much like the -Wall option to the C compiler. foreign tells Automake that we will not be building a GNU package, so it will not complain about the lack of files such as README. If you are building a real application, you might want to remove the foreign option so that you will not forget to provide any files that users might expect.

AC_CONFIG_FILES

This is a list of files that we would like to output when configuring our project. If we put a file named plerp in this list, then Autoconf will look for a file named plerp.in and transform it into plerp. It does this by scanning plerp.in and replacing any text in the form of @VARIABLE@ with the contents of the variable VARIABLE. We have not defined any of these variables explicitly yet, but they are defined internally by many Autoconf and Automake macros.

Here, we tell Autoconf that we would like to transform Makefile.in into Makefile. Where is Makefile.in? When we run Automake, it creates Makefile.in from Makefile.am. We will do this in the next step.

AC_OUTPUT

This macro takes care of outputting any files we have asked Autoconf to output.

We must now bootstrap this project (initialize it from this pristine state into a state where the build system is working.) The Autoreconf program does this. Autoreconf runs Autoconf, Automake, and several other programs in order to get the project ready to be built. In a terminal, type:

autoreconf -i
configure.ac:2: installing `./install.sh'
configure.ac:2: installing `./missing'

You will be notified of files being installed. (That is what the -i option does; once the files are there, you can simply run autoreconf without any options.) If you look inside the directory, however, those won't be the only files that have appeared. Makefile.in, aclocal.m4, configure, and a directory autom4te.cache will also have been created.

Bootstrapping

It is worth noting here that anybody who wants to build your program from this point onwards doesn't need Autoconf or Automake, only a shell and Make. Distributions of source code usually include all the files that are in the directory right now, so that users who want to compile the software from source don't have to bother with Autotools. When checking out source code from a repository, however, only the handwritten files are included. The reasoning goes that those who are savvy enough to mess with development snapshots of software can be expected to have various build tools installed. If you check out source code from a repository, bootstrap it using autoreconf -i. Sometimes there is a script called autogen.sh or bootstrap to do this for you, especially if there are other steps needed for bootstrapping. If one of these files exists, use it instead.

Now the build system is initialized, we can build the source in the usual way.

./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
configure: creating ./config.status
config.status: creating Makefile
make
make: Nothing to be done for `all'.

Of course there is nothing for make to do. We have no source files, and our Makefile.am was empty. If you look at the size of the generated Makefile, however, it is anything but empty: my system reports it to be 14 kilobytes large. Even though we have no project yet, we still have a versatile build system in place.

For an example of just how versatile, type make dist. A file named app-skeleton-1.tar.gz will appear in the directory. It is a tarball (archive) of the project's source code, ready to be distributed. It is also worth noting that whoever downloads this tarball can build the project without having Autotools installed: all they need are the configure and Makefile files, which are included.

We can do other things, such as clean up our project directory. For a full list of standard make targets, refer to the Make manual.