Originally published: June 1, 2005
Table of Contents
- A Minimal Project
- Editing Automake-based Projects with KDevelop
- Adding Doxygen Support
- A More Complex Example
- Topics Not Covered
This article presents several simple Automake/Autoconf-based projects. I assume that you know what Automake, Autoconf, and
configure are, and that you know how to install a software package from sources (i.e., you know how to invoke
"configure & make & make install"). (If you don’t, you can still follow the instructions to create a very small project to play around with.) This article does not contain lengthy explanations or detailed background information. Rather, I present a few examples that (hopefully) get the ideas across.
Some of the topics for which examples are presented:
- Doxygen support
- Multiple subdirectories
- Flex/Bison support
- Libtool Convenience libraries
- KDevelop Automake Manager
I have tested all examples on GNU/Linux using Automake 1.9.5 and Autoconf 2.59.
I am not an Automake guru myself (not yet 😉 ). When I ported mfGraph to Automake, I was looking for short and simple examples like those presented in this article that would illustrate what the Automake and Autoconf manuals were talking about. I didn’t find exactly what I was looking for. The Automake Book , while being a good introduction, didn’t answer all my questions either. If you’re like me, maybe you’ll find this article helpful.
I appreciate all your feedback, especially if you find any errors or abuses of Automake/Autoconf concepts.
In the meantime, another very interesting book about Automake/Autoconf is available online: Autotools: a practitioner’s guide to Autoconf, Automake and Libtool  at the Free Software Magazine web site.
A Minimal Project
Create a directry structure with the following files in it:
foobar/ m4/ src/ Makefile.am <your source code files> AUTHORS COPYING ChangeLog Makefile.am NEWS README autogen.sh configure.ac
This is the source tree of the project. Apart from the .cpp and .h files, these text files are the only files that you need to create for a minimal GNU Automake/Autoconf-based project. All other files will be generated by the tools.
Let’s take a look at the contents of the files. The files named
Makefile.am are the input to the Automake tool. First, the root
foobar/Makefile.am: ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src EXTRA_DIST = autogen.sh
- For a minimal project, we only need to name the subdirectories containing additional
- The option
-I m4tells Autoconf to look for additional Autoconf macros in the m4 subdirectory. We’ll make use of this when we introduce Doxygen.
EXTRA_DISTdirective tells Automake to place the file
autogen.shin the distribution archive, so that that file is shipped to our users.
autogen.sh is a shell script that invokes
autoreconf for us. The tool
autoreconf is responsible for calling Autoconf, Automake and related tools in the right order.
Don’t forget to set the Execute bit for the file
foobar/autogen.sh: #!/bin/sh autoreconf --force --install -I config -I m4
--forceoption rebuilds the
configurescript regardless of its timestamp in relation to that of the file
- The option
--installcopies some missing files to the directory, including the text files
- We add
-I m4so that the tools find the files that we’re going to place in those subdirectories instead of in the project root.
Note: Don’t run
autogen.sh yet. We have to write
For more information on
info autoreconf. If you’re using KDE, you can also enter
info:autoreconf in the Konqueror address box.
configure.ac is the input to Autoconf. Autoconf produces the
configure shell script, which, in turn, produces the final Makefiles, so that users can type
make install to install your software.
foobar/configure.ac: dnl Process this file with autoconf to produce a configure script. AC_INIT(foobar, 1.0, email@example.com) AC_CONFIG_AUX_DIR(config) AC_CONFIG_SRCDIR(src/foobar.cpp) AM_INIT_AUTOMAKE AC_PROG_CXX AC_OUTPUT(Makefile src/Makefile)
- The lines up to and including
AM_INIT_AUTOMAKEare more or less boilerplate code.
AC_CONFIG_AUX_DIRis the place where some helper files will be placed. This keeps the root directory cleaner.
AC_PROG_CXXenables C++ compiler support. Autoconf will generate code for the
configurescript that determines the location of the compiler, tests various compiler switches, etc.
- Larger projects will require additional checks and switches here.
AC_OUTPUTlists the Makefiles that the
configurescript should generate on the user’s machine. For every
Makefile.amthat we write, Automake will generate a
configurescripts turns these into Makefiles.
For more information on Autoconf, please see the Autoconf manual (
Each subdirectory has its own
Makefile.am. Our file
src/Makefile.am builds an executable program from a single C++ source file.
foobar/src/Makefile.am: bin_PROGRAMS = foobar foobar_SOURCES = foobar.cpp
"PROGRAMS"is called a primary. Other primaries include:
LIBRARIESfor static libraries (.a)
LTLIBRARIESfor Libtool-based shared libraries (.la)
- The prefix
"bin_"tells Automake where to copy the resulting program when the user runs
make install. Known directory prefixes include:
bin_– for programs, e.g.,
lib_– where libraries are placed, e.g.,
include_– where header files are placed, e.g.,
noinst_– files that will not be copied anywhere by
Note: The user can specify the locations of these directories when running the
configurescript. For more info, run
"SOURCES"is a variable that lists the source files of the program. For programs and libraries, possible variables include:
CFLAGS, CPPFLAGS, CXXFLAGS– extra arguments passed to the compiler/preprocessor
LIBADD– extra objects for a library
LDADD– extra objects for a program
LDFLAGS– extra arguments passed to the linker
For more information on Automake, please see the Automake manual (
Running the Tools
Now it’s time to run the tools and attempt a build.
./autogen.shand see which files are produced by this step.
- Create a separate build tree and run
> mkdir build > cd build > ../configure
Note: You can pass various arguments to
configure. Take a look at these by running
Again, see which files are produced by this step.
- To produce a distribution package, run
make distor, better yet,
Editing Automake-based Projects with KDevelop
You can work with Automake-based projects from within the KDevelop IDE.
- Click Project > Import Existing Project…
- Specify the directory that contains your Automake-based project
(Screenshot taken in KDevelop 3.2.0)
- Using the Automake Manager, you can add/remove sub-projects, add/remove files, set options, etc.
- If your main program is not named after the project, you need to set the Run Options in Project > Options to be able to debug:
Adding Doxygen Support
Doxygen is a tool that generates HTML documentation from special comments in C++ source code. (However, I assume you already know the tool. If you don’t, you can safely skip this section.)
Adding Doxygen support means that we want to have a Make target that generates the HTML documentation, and that the generated HTML documentation should be included in the distribution archive. For this to work, you need to download a few files from Oren Ben-Kiki’s web site and place them in your directory structure (new files are in boldface):
foobar/ m4/ ac_doxygen.m4 src/ Makefile.am <your source code files> AUTHORS COPYING ChangeLog Makefile.am NEWS README aminclude.am autogen.sh configure.ac doxygen.cfg
Note: Older versions of these files seem to be available at the Autoconf Macro Archive, but these don’t work as good.
ac_doxygen.m4contains Autoconf macros that we can use in
aminclude.amcontains the Doxygen-related make targets.
Doxyfiletemplate that contains a few macros that will be expanded when the
configurescript is run. Modify the file so that it suits your needs (and the version of Doxygen that you’re using!).
Next, we need to make a change to the file
Makefile.am in the root directory so that the generated documentation will be included in the distribution archive (added lines are in boldface):
foobar/Makefile.am: ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src include aminclude.am EXTRA_DIST = autogen.sh $(DX_CONFIG) doc/html
Finally, we add Doxygen-related macro calls to the file
configure.ac (added lines are in boldface):
foobar/configure.ac: dnl Process this file with autoconf to produce a configure script. AC_INIT(foobar, 1.0, firstname.lastname@example.org) AC_CONFIG_AUX_DIR(config) AC_CONFIG_SRCDIR(src/foobar.cpp) AM_INIT_AUTOMAKE AC_PROG_CXX DX_HTML_FEATURE(ON) DX_CHM_FEATURE(OFF) DX_CHI_FEATURE(OFF) DX_MAN_FEATURE(OFF) DX_RTF_FEATURE(OFF) DX_XML_FEATURE(OFF) DX_PDF_FEATURE(OFF) DX_PS_FEATURE(OFF) DX_INIT_DOXYGEN(foobar, doxygen.cfg, doc) AC_OUTPUT(Makefile src/Makefile)
Documentation will be generated when you run
make doxygen-doc or when you produce a distribution archive with
Note: When you look at the generated Makefile, you’ll see that the documentation only depends on the files in
pkginclude_HEADERS, regardless of what you set
"INPUT" to in the file
doxygen.cfg. If you want to force the documentation to be re-generated (maybe before the final build), it might be a good idea to delete the entire Doxygen output folder (
doc/html by default) before doing the build.
A More Complex Example
Finally, I’d like to present a more complex example with the following features:
- Several subdirectories, each with their own
- Libtool shared and convenience libraries
- Generated source files (the typical Flex/Bison example)
The new directory structure looks like this (added entries in boldface):
foobar/ m4/ ac_doxygen.m4 some_shared_lib/ Makefile.am <your some_shared_lib-specific source code files> src/ Makefile.am <your source code files> AUTHORS COPYING ChangeLog Makefile.am NEWS README aminclude.am autogen.sh configure.ac doxygen.cfg
For Libtool libraries as well as for Flex/Bison, we need additional checks in
configure.ac. Also, we must specify the new subdirectory (added text in boldface):
foobar/configure.ac: dnl Process this file with autoconf to produce a configure script. AC_INIT(foobar, 1.0, email@example.com) AC_CONFIG_AUX_DIR(config) AC_CONFIG_SRCDIR(src/foobar.cpp) AM_INIT_AUTOMAKE AC_PROG_CXX AM_PROG_LEX AC_PROG_YACC AC_PROG_LIBTOOL DX_HTML_FEATURE(ON) DX_CHM_FEATURE(OFF) DX_CHI_FEATURE(OFF) DX_MAN_FEATURE(OFF) DX_RTF_FEATURE(OFF) DX_XML_FEATURE(OFF) DX_PDF_FEATURE(OFF) DX_PS_FEATURE(OFF) DX_INIT_DOXYGEN(foobar, doxygen.cfg, doc) AC_OUTPUT(Makefile src/Makefile some_shared_lib/Makefile)
Note: When building with Libtool, all sources will be compiled twice–once for static libraries and once for dynamic libraries. If you only ever build dynamic libraries, you can save compilation time by inserting
The additional subdirectory must also be added to
Makefile.am (added text in boldface):
foobar/Makefile.am: ACLOCAL_AMFLAGS = -I m4 SUBDIRS = src some_shared_lib include aminclude.am EXTRA_DIST = autogen.sh $(DX_CONFIG) doc/html
In the file
src/Makefile.am, we build a Libtool convenience library from the sources in the
src directory. A convenience library is a library that is not installed (as specified by the
"noinst_" prefix). Such a library is useful whenever you want to link the same set of sources into several executables or shared libraries, without having to list these sources in every
Another complication in
src/Makefile.am is that it includes a Flex/Bison-generated parser. With Automake, you only have to list the Bison grammar file (.yy) and the Flex lexer file (.ll) file; Automake knows how to invoke Flex/Bison to generate the source code.
The only thing you have to remember is to specify
BUILT_SOURCES. This way, Automake will run the commands that generate
mfg_bison.h before compiling any other files that might depend on it. (Typically, the generated
mfg_flex.cpp is one such file that depends on
mfg_bison.h. If you don’t specify
BUILT_SOURCES, it might happen that the Make tool tries to compile
We also specify
public_api.h in the list
pkginclude_HEADERS. When the user runs
make install, the listed files will be copied to
/usr/local/include/foobar (or a different directory passed to
foobar/src/Makefile.am: BUILT_SOURCES = mfg_bison.h AM_YFLAGS = -d -p mfg AM_LFLAGS = -o$(LEX_OUTPUT_ROOT).c noinst_LTLIBRARIES = libsrc.la libsrc_la_SOURCES = public_api.cpp mfg_bison.yy mfg_flex.ll pkginclude_HEADERS = public_api.h
If we didn’t want to install any headers, we’d list the headers in
libsrc_la_SOURCES. Headers that are not listed anywhere are not included in the distribution archive.
In the subdirectory
some_shared_lib, we link the convenience library,
libsrc.la, and an additional source file into a shared library,
libfoobar.la, that will be installed to
/usr/local/lib (or a different directory passed to
Makefile.am looks like this:
foobar/some_shared_lib/Makefile.am: lib_LTLIBRARIES = libfoobar.la libfoobar_la_SOURCES = shared_library.cpp libfoobar_la_CPPFLAGS = -I$(top_srcdir)/src libfoobar_la_LIBADD = ../src/libsrc.la
$(top_srcdir)/src as an additional include directory, because it’s common to have
#include directives for sources found in
src in source files such as
some_shared_lib/shared_library.cpp. Note that for linking to the convenience library, I specifiy
../src instead. This is because the library will be found in the build tree, not in the source tree.
Topics Not Covered
One topic that I didn’t cover but that I’m very much interested in is
- building and running a unit test suite automatically during a build.
Maybe someone of you has a simple working example?
- Gary V. Vaughan, Ben Elliston, Tom Tromey and Ian Lance Taylor. GNU Automake, Autoconf, and Libtool. http://sources.redhat.com/autobook/.
- Automake Manual. http://sources.redhat.com/automake/automake.html.
- Autoconf Manual. http://www.gnu.org/software/autoconf/manual/index.html.
- The GNU Autoconf Macro Archive. http://www.gnu.org/software/ac-archive/.
- Oren Ben-Kiki. Doxample. http://ben-kiki.org/oren/doxample/.
- This article presents another Automake example: Building SWIG Python Extensions on GNU/Linux
- John Calcote. Autotools: a practitioner’s guide to Autoconf, Automake and Libtool. http://www.freesoftwaremagazine.com/books/autotools_a_guide_to_autoconf_automake_libtool.