Manuals and HowTo's : GNU Build System (configure, automake, ...)
Ludicrous Home > Manuals and HowTo's > GNU Build System (configure, automake, ...)

Contents

Introduction to the tools of the automatic makefile generation suite.

Several tools and files are needed for the automatic makefile generation.
Even if this sounds complicated (and it is), the advantage of this suite is overwhelming for a project that should be compilable on almost all kind of systems.

autoscan

Examines source files in a given directory tree.
Searches the source files for common portability problems, checks for incompleteness of configure.ac, and creates a file configure.scan which is a preliminary configure.ac for that package.

Reuse it at least before you ship
When you add more and more to your source tree, you should invoke autoscan in the root tree and compare the new configure.scan for new entries that you should pass to your configure.ac

autoconf

This is an alphabetical list of the autoconf macros.
All available macros are assigned into one of the following categories.

automake

Macro and Variable Index

autoheader

aclocal

Scans the system and given folders for m4 macro language files, and merges all needed macros into one file that can be used by the autoconf tool.
It checks the configure.ac script whether a macro is needed or not.

autoreconf

Installing the various components of the GNU Build System can be tedious: running autopoint for Gettext, automake for `Makefile.in' etc. in each directory.

autoreconf runs autoconf, autoheader, aclocal, automake, libtoolize, and autopoint (when appropriate) repeatedly to update the GNU Build System in the specified directories and their subdirectories.

configure

This isn't exaclty a tool, but a configuration script generated by some of the above tools.
This script checks the whole system and adapts all compiling switches so that the source is compilable on the used system.
This is the heart of the so powerful adaption and which makes it possible to compile your projects on almost any system (Linux, CygWin, MacOs, AmigaOS, ...)

autoupdate

Updates an old configure.ac if preset, or else configure.in, to the syntax of the current version of autoconf.

Have a look at the configure.ac chapter about a possible linefeed problem.

Steps for creating the automatic makefile generation suite

  1. Create your project folder structure and put all your source code in the appropriate folders.
  2. Create Makefile.am templates in each folder and subfolder where you need to compile source files.
  3. Launch autoscan in the root folder.
    • This will create the configure.scan template file.
    • Rename it to configure.ac and edit it for tweaking so that everything needed is there.
  4. Launch autoreconf --verbose --install -I config.
    • This will create some missing files, will create a valid configure.
  5. Create a build folder mkdir build.
  6. Create Makefiles with cd build ; ../configure.
  7. Now you can start the compilation with make.
  8. make install as root to install the new software.
    Automatic generation
    Once the Makefiles are created, you'll never have to call the 4th step with autoreconf again, as the Makefiles check for changes to the configure.ac and Makefile.am files and will launch the respective tools to generate the Makefiles again.

Additional steps

  1. make dist creates are distribution tarball which can be unpacked and compiled anywhere else.
  2. make clean removes binaries and object files.
  3. make distclean removes not only the binaries, but all the configuration results created by the configure script. You should make this target before importing your source tree into any source control repository.

Automatic generation

It is recommended to write a small shell script to perform the above steps automatically.
This script can be used also for shipping a source code package, and you can find lots of them shipping with an autogen.sh shell script.

Here we give an example for such a script.

autogen.sh

#!/bin/sh

if ! test -d config; then mkdir config; fi

# For some, when aclocal is launched from autoreconf, the macros in
# the m4 folder aren't included, so we launch it here ourselves.
aclocal --install -I config --verbose

autoreconf --install --verbose

if ! test -d build; then mkdir build; fi

cd build

../configure

make

Tweaking the compilation process

Here we give some hints, how to influence in the complete compilation process.
You should read the respective manuals for more details.

configure.ac

Absolutely necessary

The template generated by autoscan needs some modifications, otherwise configure will fail.

  • We need to add the following line at the beginning, because we instructed autoreconf to create some helper files in the config subfolder:

    AC_CONFIG_AUX_DIR(config)

  • Declare where the Makefiles should be generated, in the main build folder and in all subfolders that hold source files (this macro is at the end of the file):

    AC_CONFIG_FILES([Makefile subfolder1/Makefile subfolder2/Makefile ......])
    AC_OUTPUT

Unix filesystem line ends
You have to make absolutely sure that all Line-feeds are Unix-style (dos2unix), otherwise autoconf could behave erroneous with very strange warnings.
autoupdate doesn't create linefeeds always for Unix, so make sure to call dos2unix on your updated configure.ac

Should be done

  • Add the following line to declare a "foreign" type distribution (i.e. don't require all the standard GNU files). And we want a dist-bzip2 rule to be able to create .tar.bz2 dist files.

    AM_INIT_AUTOMAKE([foreign dist-bzip2])

Could be done

  • Changing the following default line has the advantage that some useful compiler defines are generated and the distribution tar-archive gets the right name:

    AC_INIT(your-project-name, 0.1, your@email.adr)

    This will give you the following compiler defines:

    #define PACKAGE_NAME "your-project-name"
    #define PACKAGE_TARNAME "your-project-name"
    #define PACKAGE_VERSION "0.1"
    #define PACKAGE_STRING "your-project-name 0.1"
    #define PACKAGE_BUGREPORT "your@email.adr"
    

Makefile.am

Creating the templates for the Makefile generation is much more easier than the one for the configure script.
We'll present to kinds of Makefile templates here.

Makefile.am pointing to subdirectories

This is the easiest one. It could be just like this example:

SUBDIRS = \
subfolder1 \
subfolder2

Each subdirectory must have its own Makefile.am.

Makefile.am for source files

These are a bit more complicated than the subfolder ones.
Basically, you declare two types of information:

  1. What you will generate.
  2. What are the sources for each item.

Compile programs

The *_PROGRAMS variables specify programs to be built.
bin_PROGRAMS list programs to be built and installed to @prefix@/bin, sbin_PROGRAMS are built and installed to @prefix@/sbin; EXTRA_PROGRAMS are built but not installed.

For each program listed, program_SOURCES lists the source files.
include_HEADERS lists headers that are installed to @prefix@/include.
EXTRA_DIST and noinst_HEADERS files are included in the distribution but not installed.

Sounds complicated? Look at this example, to see it isn't:

bin_PROGRAMS = myProggy anotherProggy
EXTRA_PROGRAMS = testProggies

myProggy_SOURCES = myMain.cpp

anotherProggy_SOURCES = another.cpp

testProggies_SOURCES = test.cpp
testProggies_CPPFLAGS = -w2 -DTEST=1

Compile flags

The last line of the above example shows, how to declare specific compiler flags for each program.
You can also declare flags for all programs with a specific automake variable:

AM_CPPFLAGS = -w3 \
-I@top_srcdir@/include \
-I@srcdir@/include> \
-I@srcdir@/anothersubfolder/include
  • @top_srcdir@ points to the root folder of the project, where the topmost Makefile resides.
  • @srcdir@ points to the folder of each source file that is compiled.

Link against libraries

You can define that all programs link against some libraries or specify them for each program:

LDADD = \
../src/libcommon.a \
$(BOOST_PROGRAM_OPTIONS_LIB)

myProggy_LDADD = specific.la

Compile libraries

lib_LIBRARIES = \
libmyLib.a

libmyLib_a_SOURCES = myLib.cpp

libmyLib_a_LDFLAGS = -version-info 0:0:0
When target names have dashes (-) or dots (.), they're substituted for underscores.
RANLIB

You will have to tweak the configure.ac script again, otherwise the automake tool will claim about a missing definition for RANLIB.
The usual way to define RANLIB is to add AC_PROG_RANLIB to configure.ac and run autoconf again.

Linker flags

The last line of the above example shows, how to declare specific compiler flags for each program or library.
You can also declare flags for all programs with a specific LDFLAGS variable.

Conditionals

Before using a conditional in the Makefiles, you must define it by using AM_CONDITIONAL in the configure.ac file:

AC_ARG_ENABLE(debug,
[  --enable-debug    Turn on debugging],
[case "${enableval}" in
yes) debug=true ;;
no)  debug=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[debug=false])
AM_CONDITIONAL(DEBUG, test x$debug = xtrue)

Here is an example of how to use that conditional in `Makefile.am':

if DEBUG
DBG = debug
else
DBG =
endif
noinst_PROGRAMS = $(DBG)

Conditionals do not interact very smoothly with the append operator. In particular, an append must happen in the same conditional context as the original assignment. This means that the following will not work:

DBG = foo
if DEBUG
DBG += bar
endif DEBUG

The behaviour which is probably desired in this situation can be obtained using a temporary variable:

if DEBUG
TMP_DBG = bar
endif DEBUG
DBG = foo $(TMP_DBG)

More information can be found in the online manual.

Nesting configure projects

Deep packages have a configure.ac in each subdirectory, and it looks very much like an aggregate of programs which just happen to be distributed together.

For example, suppose you want to include a project in your project tree that already has a configure.ac. This is what you'll have to add to your files:

  • In your configure.ac you just point to all directories that have another one:

    AC_CONFIG_SUBDIRS([anotherConfigProject])

  • In your root Makefile.am you add the others project folder to the subdirectory variable:

    SUBDIRS = mySubfolder anotherConfigProject

Other useful stuff

pkg-config

pkg-config is a system for managing library compile and link flags that works with automake and autoconf.
Examples:

pkg-config cppunit --libs outputs -lcppunit

pkg-config gsoap++ --cflags outputs -DWITH_DOM -lgsoap++

pkg-config ACE --modversion outputs 5.4.7

This information can be directly used in the configure.ac script:

PKG_CHECK_MODULES([ACE], [ACE >= 5.4.4])
dnl PKG_CHECK_MODULES([ACE], [ACE = 5.4.7])

AC_SUBST([ACE_CFLAGS])
AC_SUBST([ACE_LIBS])

You can then use this information in the Makefile.am like this:

AM_CPPFLAGS = @ACE_CFLAGS@
AM_LDFLAGS = @ACE_LIBS@

Useful links

Document generated by Atlassian Confluence, last changed on jun 20, 2007 by Sven Rieke