| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If you are new to Automake, maybe you know that it is part of a set of tools called The Autotools. Maybe you've already delved into a package full of files named `configure', `configure.ac', `Makefile.in', `Makefile.am', `aclocal.m4', …, some of them claiming to be generated by Autoconf or Automake. But the exact purpose of these files and their relations is probably fuzzy. The goal of this chapter is to introduce you to this machinery, to show you how it works and how powerful it is. If you've never installed or seen such a package, do not worry: this chapter will walk you through it.
If you need some teaching material, more illustrations, or a less
automake-centered continuation, some slides for this
introduction are available in Alexandre Duret-Lutz's
Autotools Tutorial.
This chapter is the written version of the first part of his tutorial.
| 2.1 Introducing the GNU Build System | ||
| 2.2 Use Cases for the GNU Build System | ||
| 2.3 How Autotools Help | ||
| 2.4 A Small Hello World | A Small Hello World Package |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is a truth universally acknowledged, that a developer in possession of a new package, must be in want of a build system.
In the Unix world, such a build system is traditionally achieved using
the command make (see (make)Top section `Overview' in The GNU Make Manual). The developer expresses the recipe to build his package in
a `Makefile'. This file is a set of rules to build the files in
the package. For instance the program `prog' may be built by
running the linker on the files `main.o', `foo.o', and
`bar.o'; the file `main.o' may be built by running the
compiler on `main.c'; etc. Each time make is run, it
reads `Makefile', checks the existence and modification time of
the files mentioned, decides what files need to be built (or rebuilt),
and runs the associated commands.
When a package needs to be built on a different platform than the one
it was developed on, its `Makefile' usually needs to be adjusted.
For instance the compiler may have another name or require more
options. In 1991, David J. MacKenzie got tired of customizing
`Makefile' for the 20 platforms he had to deal with. Instead, he
handcrafted a little shell script called `configure' to
automatically adjust the `Makefile' (see (autoconf)Genesis section `Genesis' in The Autoconf Manual). Compiling his package was now
as simple as running ./configure && make.
Today this process has been standardized in the GNU project. The GNU
Coding Standards (see The Release Process: (standards)Managing Releases section `Managing Releases' in The GNU Coding Standards) explains how each package of the
GNU project should have a `configure' script, and the minimal
interface it should have. The `Makefile' too should follow some
established conventions. The result? A unified build system that
makes all packages almost indistinguishable by the installer. In its
simplest scenario, all the installer has to do is to unpack the
package, run ./configure && make && make install, and repeat
with the next package to install.
We call this build system the GNU Build System, since it was grown out of the GNU project. However it is used by a vast number of other packages: following any existing convention has its advantages.
The Autotools are tools that will create a GNU Build System for your package. Autoconf mostly focuses on `configure' and Automake on `Makefile's. It is entirely possible to create a GNU Build System without the help of these tools. However it is rather burdensome and error-prone. We will discuss this again after some illustration of the GNU Build System in action.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In this section we explore several use cases for the GNU Build System. You can replay all these examples on the `amhello-1.0.tar.gz' package distributed with Automake. If Automake is installed on your system, you should find a copy of this file in `prefix/share/doc/automake/amhello-1.0.tar.gz', where prefix is the installation prefix specified during configuration (prefix defaults to `/usr/local', however if Automake was installed by some GNU/Linux distribution it most likely has been set to `/usr'). If you do not have a copy of Automake installed, you can find a copy of this file inside the `doc/' directory of the Automake package.
Some of the following use cases present features that are in fact extensions to the GNU Build System. Read: they are not specified by the GNU Coding Standards, but they are nonetheless part of the build system created by the Autotools. To keep things simple, we do not point out the difference. Our objective is to show you many of the features that the build system created by the Autotools will offer to you.
| 2.2.1 Basic Installation | Common installation procedure | |
| 2.2.2 Standard `Makefile' Targets | A list of standard Makefile targets | |
| 2.2.3 Standard Directory Variables | A list of standard directory variables | |
| 2.2.4 Standard Configuration Variables | Using configuration variables | |
| 2.2.5 Overriding Default Configuration Setting with `config.site' | Using a config.site file | |
| 2.2.6 Parallel Build Trees (a.k.a. VPATH Builds) | Parallel build trees | |
| 2.2.7 Two-Part Installation | Installing data and programs separately | |
| 2.2.8 Cross-Compilation | Building for other architectures | |
| 2.2.9 Renaming Programs at Install Time | Renaming programs at install time | |
| 2.2.10 Building Binary Packages Using DESTDIR | Building binary packages with DESTDIR | |
| 2.2.11 Preparing Distributions | Rolling out tarballs | |
| 2.2.12 Automatic Dependency Tracking | Automatic dependency tracking | |
| 2.2.13 Nested Packages | The GNU Build Systems can be nested |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The most common installation procedure looks as follows.
~ % tar zxf amhello-1.0.tar.gz ~ % cd amhello-1.0 ~/amhello-1.0 % ./configure … config.status: creating Makefile config.status: creating src/Makefile … ~/amhello-1.0 % make … ~/amhello-1.0 % make check … ~/amhello-1.0 % su Password: /home/adl/amhello-1.0 # make install … /home/adl/amhello-1.0 # exit ~/amhello-1.0 % make installcheck … |
The user first unpacks the package. Here, and in the following
examples, we will use the non-portable tar zxf command for
simplicity. On a system without GNU tar installed, this
command should read gunzip -c amhello-1.0.tar.gz | tar xf -.
The user then enters the newly created directory to run the `configure' script. This script probes the system for various features, and finally creates the `Makefile's. In this toy example there are only two `Makefile's, but in real-world projects, there may be many more, usually one `Makefile' per directory.
It is now possible to run make. This will construct all the
programs, libraries, and scripts that need to be constructed for the
package. In our example, this compiles the `hello' program.
All files are constructed in place, in the source tree; we will see
later how this can be changed.
make check causes the package's tests to be run. This step is
not mandatory, but it is often good to make sure the programs that
have been built behave as they should, before you decide to install
them. Our example does not contain any tests, so running make
check is a no-op.
After everything has been built, and maybe tested, it is time to
install it on the system. That means copying the programs,
libraries, header files, scripts, and other data files from the
source directory to their final destination on the system. The
command make install will do that. However, by default
everything will be installed in subdirectories of `/usr/local':
binaries will go into `/usr/local/bin', libraries will end up in
`/usr/local/lib', etc. This destination is usually not writable
by any user, so we assume that we have to become root before we can
run make install. In our example, running make install
will copy the program `hello' into `/usr/local/bin'
and `README' into `/usr/local/share/doc/amhello'.
A last and optional step is to run make installcheck. This
command may run tests on the installed files. make check tests
the files in the source tree, while make installcheck tests
their installed copies. The tests run by the latter can be different
from those run by the former. For instance, there are tests that
cannot be run in the source tree. Conversely, some packages are set
up so that make installcheck will run the very same tests as
make check, only on different files (non-installed
vs. installed). It can make a difference, for instance when the
source tree's layout is different from that of the installation.
Furthermore it may help to diagnose an incomplete installation.
Presently most packages do not have any installcheck tests
because the existence of installcheck is little known, and its
usefulness is neglected. Our little toy package is no better: make
installcheck does nothing.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
So far we have come across four ways to run make in the GNU
Build System: make, make check, make install, and
make installcheck. The words check, install, and
installcheck, passed as arguments to make, are called
targets. make is a shorthand for make all,
all being the default target in the GNU Build System.
Here is a list of the most useful targets that the GNU Coding Standards specify.
make allBuild programs, libraries, documentation, etc. (same as make).
make installInstall what needs to be installed, copying the files from the package's tree to system-wide directories.
make install-stripSame as make install, then strip debugging symbols. Some
users like to trade space for useful bug reports....
make uninstallThe opposite of make install: erase the installed files.
(This needs to be run from the same build tree that was installed.)
make cleanErase from the build tree the files built by make all.
make distcleanAdditionally erase anything ./configure created.
make checkRun the test suite, if any.
make installcheckCheck the installed programs or libraries, if supported.
make distRecreate `package-version.tar.gz' from all the source files.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The GNU Coding Standards also specify a hierarchy of variables to denote installation directories. Some of these are:
Directory variable | Default value |
|---|---|
| |
| |
| |
| |
… | |
| |
| |
| |
| |
| |
| |
… |
Each of these directories has a role which is often obvious from its
name. In a package, any installable file will be installed in one of
these directories. For instance in amhello-1.0, the program
`hello' is to be installed in bindir, the directory for
binaries. The default value for this directory is
`/usr/local/bin', but the user can supply a different value when
calling configure. Also the file `README' will be
installed into docdir, which defaults to
`/usr/local/share/doc/amhello'.
A user who wishes to install a package on his own account could proceed as follows:
~/amhello-1.0 % ./configure --prefix ~/usr … ~/amhello-1.0 % make … ~/amhello-1.0 % make install … |
This would install `~/usr/bin/hello' and `~/usr/share/doc/amhello/README'.
The list of all such directory options is shown by
./configure --help.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The GNU Coding Standards also define a set of standard configuration variables used during the build. Here are some:
CCC compiler command
CFLAGSC compiler flags
CXXC++ compiler command
CXXFLAGSC++ compiler flags
LDFLAGSlinker flags
CPPFLAGSC/C++ preprocessor flags
configure usually does a good job at setting appropriate
values for these variables, but there are cases where you may want to
override them. For instance you may have several versions of a
compiler installed and would like to use another one, you may have
header files installed outside the default search path of the
compiler, or even libraries out of the way of the linker.
Here is how one would call configure to force it to use
gcc-3 as C compiler, use header files from
`~/usr/include' when compiling, and libraries from
`~/usr/lib' when linking.
~/amhello-1.0 % ./configure --prefix ~/usr CC=gcc-3 \ CPPFLAGS=-I$HOME/usr/include LDFLAGS=-L$HOME/usr/lib |
Again, a full list of these variables appears in the output of
./configure --help.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When installing several packages using the same setup, it can be
convenient to create a file to capture common settings.
If a file named `prefix/share/config.site' exists,
configure will source it at the beginning of its execution.
Recall the command from the previous section:
~/amhello-1.0 % ./configure --prefix ~/usr CC=gcc-3 \ CPPFLAGS=-I$HOME/usr/include LDFLAGS=-L$HOME/usr/lib |
Assuming we are installing many package in `~/usr', and will
always want to use these definitions of CC, CPPFLAGS, and
LDFLAGS, we can automate this by creating the following
`~/usr/share/config.site' file:
test -z "$CC" && CC=gcc-3 test -z "$CPPFLAGS" && CPPFLAGS=-I$HOME/usr/include test -z "$LDFLAGS" && LDFLAGS=-L$HOME/usr/lib |
Now, any time a `configure' script is using the `~/usr' prefix, it will execute the above `config.site' and define these three variables.
~/amhello-1.0 % ./configure --prefix ~/usr configure: loading site script /home/adl/usr/share/config.site … |
See (autoconf)Site Defaults section `Setting Site Defaults' in The Autoconf Manual, for more information about this feature.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The GNU Build System distinguishes two trees: the source tree, and the build tree.
The source tree is rooted in the directory containing `configure'. It contains all the sources files (those that are distributed), and may be arranged using several subdirectories.
The build tree is rooted in the directory in which `configure' was run, and is populated with all object files, programs, libraries, and other derived files built from the sources (and hence not distributed). The build tree usually has the same subdirectory layout as the source tree; its subdirectories are created automatically by the build system.
If `configure' is executed in its own directory, the source and build trees are combined: derived files are constructed in the same directories as their sources. This was the case in our first installation example (see section Basic Installation).
A common request from users is that they want to confine all derived files to a single directory, to keep their source directories uncluttered. Here is how we could run `configure' to build everything in a subdirectory called `build/'.
~ % tar zxf ~/amhello-1.0.tar.gz ~ % cd amhello-1.0 ~/amhello-1.0 % mkdir build && cd build ~/amhello-1.0/build % ../configure … ~/amhello-1.0/build % make … |
These setups, where source and build trees are different, are often
called parallel builds or VPATH builds. The expression
parallel build is misleading: the word parallel is a
reference to the way the build tree shadows the source tree, it is not
about some concurrency in the way build commands are run. For this
reason we refer to such setups using the name VPATH builds in
the following. VPATH is the name of the make feature
used by the `Makefile's to allow these builds (see (make)General Search section `VPATH: Search Path for All Prerequisites' in The GNU Make Manual).
VPATH builds have other interesting uses. One is to build the same sources with multiple configurations. For instance:
~ % tar zxf ~/amhello-1.0.tar.gz ~ % cd amhello-1.0 ~/amhello-1.0 % mkdir debug optim && cd debug ~/amhello-1.0/debug % ../configure CFLAGS='-g -O0' … ~/amhello-1.0/debug % make … ~/amhello-1.0/debug % cd ../optim ~/amhello-1.0/optim % ../configure CFLAGS='-O3 -fomit-frame-pointer' … ~/amhello-1.0/optim % make … |
With network file systems, a similar approach can be used to build the
same sources on different machines. For instance, suppose that the
sources are installed on a directory shared by two hosts: HOST1
and HOST2, which may be different platforms.
~ % cd /nfs/src /nfs/src % tar zxf ~/amhello-1.0.tar.gz |
On the first host, you could create a local build directory:
[HOST1] ~ % mkdir /tmp/amh && cd /tmp/amh [HOST1] /tmp/amh % /nfs/src/amhello-1.0/configure ... [HOST1] /tmp/amh % make && sudo make install ... |
(Here we assume that the installer has configured sudo so it
can execute make install with root privileges; it is more convenient
than using su like in Basic Installation).
On the second host, you would do exactly the same, possibly at the same time:
[HOST2] ~ % mkdir /tmp/amh && cd /tmp/amh [HOST2] /tmp/amh % /nfs/src/amhello-1.0/configure ... [HOST2] /tmp/amh % make && sudo make install ... |
In this scenario, nothing forbids the `/nfs/src/amhello-1.0' directory from being read-only. In fact VPATH builds are also a means of building packages from a read-only medium such as a CD-ROM. (The FSF used to sell CD-ROM with unpacked source code, before the GNU project grew so big.)
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In our last example (see section Parallel Build Trees (a.k.a. VPATH Builds)), a source tree was shared by two hosts, but compilation and installation were done separately on each host.
The GNU Build System also supports networked setups where part of the installed files should be shared amongst multiple hosts. It does so by distinguishing architecture-dependent files from architecture-independent files, and providing two `Makefile' targets to install each of these classes of files.
These targets are install-exec for architecture-dependent files
and install-data for architecture-independent files.
The command we used up to now, make install, can be thought of
as a shorthand for make install-exec install-data.
From the GNU Build System point of view, the distinction between
architecture-dependent files and architecture-independent files is
based exclusively on the directory variable used to specify their
installation destination. In the list of directory variables we
provided earlier (see section Standard Directory Variables), all the
variables based on exec-prefix designate architecture-dependent
directories whose files will be installed by make install-exec.
The others designate architecture-independent directories and will
serve files installed by make install-data. See section The Two Parts of Install, for more details.
Here is how we could revisit our two-host installation example, assuming that (1) we want to install the package directly in `/usr', and (2) the directory `/usr/share' is shared by the two hosts.
On the first host we would run
[HOST1] ~ % mkdir /tmp/amh && cd /tmp/amh [HOST1] /tmp/amh % /nfs/src/amhello-1.0/configure --prefix /usr ... [HOST1] /tmp/amh % make && sudo make install ... |
On the second host, however, we need only install the architecture-specific files.
[HOST2] ~ % mkdir /tmp/amh && cd /tmp/amh [HOST2] /tmp/amh % /nfs/src/amhello-1.0/configure --prefix /usr ... [HOST2] /tmp/amh % make && sudo make install-exec ... |
In packages that have installation checks, it would make sense to run
make installcheck (see section Basic Installation) to verify that
the package works correctly despite the apparent partial installation.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
To cross-compile is to build on one platform a binary that will
run on another platform. When speaking of cross-compilation, it is
important to distinguish between the build platform on which
the compilation is performed, and the host platform on which the
resulting executable is expected to run. The following
configure options are used to specify each of them:
The system on which the package is built.
The system where built programs and libraries will run.
When the `--host' is used, configure will search for
the cross-compiling suite for this platform. Cross-compilation tools
commonly have their target architecture as prefix of their name. For
instance my cross-compiler for MinGW32 has its binaries called
i586-mingw32msvc-gcc, i586-mingw32msvc-ld,
i586-mingw32msvc-as, etc.
Here is how we could build amhello-1.0 for
i586-mingw32msvc on a GNU/Linux PC.
~/amhello-1.0 % ./configure --build i686-pc-linux-gnu --host i586-mingw32msvc checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for gawk... gawk checking whether make sets $(MAKE)... yes checking for i586-mingw32msvc-strip... i586-mingw32msvc-strip checking for i586-mingw32msvc-gcc... i586-mingw32msvc-gcc checking for C compiler default output file name... a.exe checking whether the C compiler works... yes checking whether we are cross compiling... yes checking for suffix of executables... .exe checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether i586-mingw32msvc-gcc accepts -g... yes checking for i586-mingw32msvc-gcc option to accept ANSI C... … ~/amhello-1.0 % make … ~/amhello-1.0 % cd src; file hello.exe hello.exe: MS Windows PE 32-bit Intel 80386 console executable not relocatable |
The `--host' and `--build' options are usually all we need for cross-compiling. The only exception is if the package being built is itself a cross-compiler: we need a third option to specify its target architecture.
When building compiler tools: the system for which the tools will create output.
For instance when installing GCC, the GNU Compiler Collection, we can use `--target=TARGET' to specify that we want to build GCC as a cross-compiler for TARGET. Mixing `--build' and `--target', we can actually cross-compile a cross-compiler; such a three-way cross-compilation is known as a Canadian cross.
See (autoconf)Specifying Names section `Specifying the System Type' in The Autoconf Manual, for more information about these configure
options.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The GNU Build System provides means to automatically rename
executables and manpages before they are installed (see section Man Pages).
This is especially convenient
when installing a GNU package on a system that already has a
proprietary implementation you do not want to overwrite. For instance,
you may want to install GNU tar as gtar so you can
distinguish it from your vendor's tar.
This can be done using one of these three configure options.
Prepend PREFIX to installed program names.
Append SUFFIX to installed program names.
Run sed PROGRAM on installed program names.
The following commands would install `hello' as `/usr/local/bin/test-hello', for instance.
~/amhello-1.0 % ./configure --program-prefix test- … ~/amhello-1.0 % make … ~/amhello-1.0 % sudo make install … |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The GNU Build System's make install and make uninstall
interface does not exactly fit the needs of a system administrator
who has to deploy and upgrade packages on lots of hosts. In other
words, the GNU Build System does not replace a package manager.
Such package managers usually need to know which files have been
installed by a package, so a mere make install is
inappropriate.
The DESTDIR variable can be used to perform a staged
installation. The package should be configured as if it was going to
be installed in its final location (e.g., --prefix /usr), but
when running make install, the DESTDIR should be set to
the absolute name of a directory into which the installation will be
diverted. From this directory it is easy to review which files are
being installed where, and finally copy them to their final location
by some means.
For instance here is how we could create a binary package containing a snapshot of all the files to be installed.
~/amhello-1.0 % ./configure --prefix /usr … ~/amhello-1.0 % make … ~/amhello-1.0 % make DESTDIR=$HOME/inst install … ~/amhello-1.0 % cd ~/inst ~/inst % find . -type f -print > ../files.lst ~/inst % tar zcvf ~/amhello-1.0-i686.tar.gz `cat ../files.lst` ./usr/bin/hello ./usr/share/doc/amhello/README |
After this example, amhello-1.0-i686.tar.gz is ready to be
uncompressed in `/' on many hosts. (Using `cat ../files.lst`
instead of `.' as argument for tar avoids entries for
each subdirectory in the archive: we would not like tar to
restore the modification time of `/', `/usr/', etc.)
Note that when building packages for several architectures, it might
be convenient to use make install-data and make
install-exec (see section Two-Part Installation) to gather
architecture-independent files in a single package.
See section What Gets Installed, for more information.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
We have already mentioned make dist. This target collects all
your source files and the necessary parts of the build system to
create a tarball named `package-version.tar.gz'.
Another, more useful command is make distcheck. The
distcheck target constructs
`package-version.tar.gz' just as well as dist,
but it additionally ensures most of the use cases presented so far
work:
make, make check, make install, as well as
make installcheck, and even make dist,
make clean, make distclean, and make
uninstall do not omit any file (see section Standard `Makefile' Targets),
DESTDIR installations work (see section Building Binary Packages Using DESTDIR).
All of these actions are performed in a temporary subdirectory, so that no root privileges are required.
Releasing a package that fails make distcheck means that one of
the scenarios we presented will not work and some users will be
disappointed. Therefore it is a good practice to release a package
only after a successful make distcheck. This of course does
not imply that the package will be flawless, but at least it will
prevent some of the embarrassing errors you may find in packages
released by people who have never heard about distcheck (like
DESTDIR not working because of a typo, or a distributed file
being erased by make clean, or even VPATH builds not
working).
See section Creating `amhello-1.0.tar.gz', to recreate `amhello-1.0.tar.gz' using
make distcheck. See section Checking the Distribution, for more
information about distcheck.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Dependency tracking is performed as a side-effect of compilation.
Each time the build system compiles a source file, it computes its
list of dependencies (in C these are the header files included by the
source being compiled). Later, any time make is run and a
dependency appears to have changed, the dependent files will be
rebuilt.
When configure is executed, you can see it probing each
compiler for the dependency mechanism it supports (several mechanisms
can be used):
~/amhello-1.0 % ./configure --prefix /usr … checking dependency style of gcc... gcc3 … |
Because dependencies are only computed as a side-effect of the
compilation, no dependency information exists the first time a package
is built. This is OK because all the files need to be built anyway:
make does not have to decide which files need to be rebuilt.
In fact, dependency tracking is completely useless for one-time builds
and there is a configure option to disable this:
Speed up one-time builds.
Some compilers do not offer any practical way to derive the list of
dependencies as a side-effect of the compilation, requiring a separate
run (maybe of another tool) to compute these dependencies. The
performance penalty implied by these methods is important enough to
disable them by default. The option `--enable-dependency-tracking'
must be passed to configure to activate them.
Do not reject slow dependency extractors.
See section Dependency Tracking in Automake, for some discussion about the different dependency tracking schemes used by Automake over the years.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Although nesting packages isn't something we would recommend to someone who is discovering the Autotools, it is a nice feature worthy of mention in this small advertising tour.
Autoconfiscated packages (that means packages whose build system have been created by Autoconf and friends) can be nested to arbitrary depth.
A typical setup is that package A will distribute one of the libraries
it needs in a subdirectory. This library B is a complete package with
its own GNU Build System. The configure script of A will
run the configure script of B as part of its execution,
building and installing A will also build and install B. Generating a
distribution for A will also include B.
It is possible to gather several package like this. GCC is a heavy user of this feature. This gives installers a single package to configure, build and install, while it allows developers to work on subpackages independently.
When configuring nested packages, the configure options
given to the top-level configure are passed recursively to
nested configures. A package that does not understand an
option will ignore it, assuming it is meaningful to some other
package.
The command configure --help=recursive can be used to display
the options supported by all the included packages.
See section Nesting Packages, for an example setup.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
There are several reasons why you may not want to implement the GNU Build System yourself (read: write a `configure' script and `Makefile's yourself).
The GNU Autotools take all this burden off your back and provide:
Yet there also exist reasons why you may want NOT to use the Autotools.... For instance you may be already using (or used to) another incompatible build system. Autotools will only be useful if you do accept the concepts of the GNU Build System. People who have their own idea of how a build system should work will feel frustrated by the Autotools.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In this section we recreate the `amhello-1.0' package from scratch. The first subsection shows how to call the Autotools to instantiate the GNU Build System, while the second explains the meaning of the `configure.ac' and `Makefile.am' files read by the Autotools.
| 2.4.1 Creating `amhello-1.0.tar.gz' | Create `amhello-1.0.tar.gz' from scratch | |
| 2.4.2 `amhello-1.0' Explained | `configure.ac' and `Makefile.am' explained |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Here is how we can recreate `amhello-1.0.tar.gz' from scratch. The package is simple enough so that we will only need to write 5 files. (You may copy them from the final `amhello-1.0.tar.gz' that is distributed with Automake if you do not want to write them.)
Create the following files in an empty directory.
~/amhello % cat src/main.c
#include <config.h>
#include <stdio.h>
int
main (void)
{
puts ("Hello World!");
puts ("This is " PACKAGE_STRING ".");
return 0;
}
|
~/amhello % cat README This is a demonstration package for GNU Automake. Type `info Automake' to read the Automake manual. |
~/amhello % cat src/Makefile.am bin_PROGRAMS = hello hello_SOURCES = main.c ~/amhello % cat Makefile.am SUBDIRS = src dist_doc_DATA = README |
configure script.
~/amhello % cat configure.ac AC_INIT([amhello], [1.0], [bug-automake@gnu.org]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ Makefile src/Makefile ]) AC_OUTPUT |
Once you have these five files, it is time to run the Autotools to
instantiate the build system. Do this using the autoreconf
command as follows:
~/amhello % autoreconf --install configure.ac: installing `./install-sh' configure.ac: installing `./missing' src/Makefile.am: installing `./depcomp' |
At this point the build system is complete.
In addition to the three scripts mentioned in its output, you can see
that autoreconf created four other files: `configure',
`config.h.in', `Makefile.in', and `src/Makefile.in'.
The latter three files are templates that will be adapted to the
system by configure under the names `config.h',
`Makefile', and `src/Makefile'. Let's do this:
~/amhello % ./configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking for gcc... gcc checking for C compiler default output file name... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ISO C89... none needed checking for style of include used by make... GNU checking dependency style of gcc... gcc3 configure: creating ./config.status config.status: creating Makefile config.status: creating src/Makefile config.status: creating config.h config.status: executing depfiles commands |
You can see `Makefile', `src/Makefile', and `config.h'
being created at the end after configure has probed the
system. It is now possible to run all the targets we wish
(see section Standard `Makefile' Targets). For instance:
~/amhello % make … ~/amhello % src/hello Hello World! This is amhello 1.0. ~/amhello % make distcheck … ============================================= amhello-1.0 archives ready for distribution: amhello-1.0.tar.gz ============================================= |
Note that running autoreconf is only needed initially when
the GNU Build System does not exist. When you later change some
instructions in a `Makefile.am' or `configure.ac', the
relevant part of the build system will be regenerated automatically
when you execute make.
autoreconf is a script that calls autoconf,
automake, and a bunch of other commands in the right order.
If you are beginning with these tools, it is not important to figure
out in which order all these tools should be invoked and why. However,
because Autoconf and Automake have separate manuals, the important
point to understand is that autoconf is in charge of
creating `configure' from `configure.ac', while
automake is in charge of creating `Makefile.in's from
`Makefile.am's and `configure.ac'. This should at least
direct you to the right manual when seeking answers.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Let us begin with the contents of `configure.ac'.
AC_INIT([amhello], [1.0], [bug-automake@gnu.org]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ Makefile src/Makefile ]) AC_OUTPUT |
This file is read by both autoconf (to create
`configure') and automake (to create the various
`Makefile.in's). It contains a series of M4 macros that will be
expanded as shell code to finally form the `configure' script.
We will not elaborate on the syntax of this file, because the Autoconf
manual has a whole section about it (see (autoconf)Writing Autoconf Input section `Writing `configure.ac'' in The Autoconf Manual).
The macros prefixed with AC_ are Autoconf macros, documented
in the Autoconf manual (see (autoconf)Autoconf Macro Index section `Autoconf Macro Index' in The Autoconf Manual). The macros that start with
AM_ are Automake macros, documented later in this manual
(see section Macro Index).
The first two lines of `configure.ac' initialize Autoconf and
Automake. AC_INIT takes in as parameters the name of the package,
its version number, and a contact address for bug-reports about the
package (this address is output at the end of ./configure
--help, for instance). When adapting this setup to your own package,
by all means please do not blindly copy Automake's address: use the
mailing list of your package, or your own mail address.
The argument to AM_INIT_AUTOMAKE is a list of options for
automake (see section Changing Automake's Behavior). `-Wall' and
`-Werror' ask automake to turn on all warnings and
report them as errors. We are speaking of Automake warnings
here, such as dubious instructions in `Makefile.am'. This has
absolutely nothing to do with how the compiler will be called, even
though it may support options with similar names. Using `-Wall
-Werror' is a safe setting when starting to work on a package: you do
not want to miss any issues. Later you may decide to relax things a
bit. The `foreign' option tells Automake that this package
will not follow the GNU Standards. GNU packages should always
distribute additional files such as `ChangeLog', `AUTHORS',
etc. We do not want automake to complain about these
missing files in our small example.
The AC_PROG_CC line causes the configure script to
search for a C compiler and define the variable CC with its
name. The `src/Makefile.in' file generated by Automake uses the
variable CC to build `hello', so when configure
creates `src/Makefile' from `src/Makefile.in', it will define
CC with the value it has found. If Automake is asked to create
a `Makefile.in' that uses CC but `configure.ac' does
not define it, it will suggest you add a call to AC_PROG_CC.
The AC_CONFIG_HEADERS([config.h]) invocation causes the
configure script to create a `config.h' file gathering
`#define's defined by other macros in `configure.ac'. In our
case, the AC_INIT macro already defined a few of them. Here
is an excerpt of `config.h' after configure has run:
… /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "bug-automake@gnu.org" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "amhello 1.0" … |
As you probably noticed, `src/main.c' includes `config.h' so
it can use PACKAGE_STRING. In a real-world project,
`config.h' can grow really big, with one `#define' per
feature probed on the system.
The AC_CONFIG_FILES macro declares the list of files that
configure should create from their `*.in' templates.
Automake also scans this list to find the `Makefile.am' files it must
process. (This is important to remember: when adding a new directory
to your project, you should add its `Makefile' to this list,
otherwise Automake will never process the new `Makefile.am' you
wrote in that directory.)
Finally, the AC_OUTPUT line is a closing command that actually
produces the part of the script in charge of creating the files
registered with AC_CONFIG_HEADERS and AC_CONFIG_FILES.
When starting a new project, we suggest you start with such a simple
`configure.ac', and gradually add the other tests it requires.
The command autoscan can also suggest a few of the tests
your package may need (see (autoconf)autoscan Invocation section `Using autoscan to Create `configure.ac'' in The Autoconf Manual).
We now turn to `src/Makefile.am'. This file contains Automake instructions to build and install `hello'.
bin_PROGRAMS = hello hello_SOURCES = main.c |
A `Makefile.am' has the same syntax as an ordinary
`Makefile'. When automake processes a
`Makefile.am' it copies the entire file into the output
`Makefile.in' (that will be later turned into `Makefile' by
configure) but will react to certain variable definitions
by generating some build rules and other variables.
Often `Makefile.am's contain only a list of variable definitions as
above, but they can also contain other variable and rule definitions that
automake will pass along without interpretation.
Variables that end with _PROGRAMS are special variables
that list programs that the resulting `Makefile' should build.
In Automake speak, this _PROGRAMS suffix is called a
primary; Automake recognizes other primaries such as
_SCRIPTS, _DATA, _LIBRARIES, etc. corresponding
to different types of files.
The `bin' part of the bin_PROGRAMS tells
automake that the resulting programs should be installed in
bindir. Recall that the GNU Build System uses a set of variables
to denote destination directories and allow users to customize these
locations (see section Standard Directory Variables). Any such directory
variable can be put in front of a primary (omitting the dir
suffix) to tell automake where to install the listed files.
Programs need to be built from source files, so for each program
prog listed in a _PROGRAMS variable,
automake will look for another variable named
prog_SOURCES listing its source files. There may be more
than one source file: they will all be compiled and linked together.
Automake also knows that source files need to be distributed when
creating a tarball (unlike built programs). So a side-effect of this
hello_SOURCES declaration is that `main.c' will be
part of the tarball created by make dist.
Finally here are some explanations regarding the top-level `Makefile.am'.
SUBDIRS = src dist_doc_DATA = README |
SUBDIRS is a special variable listing all directories that
make should recurse into before processing the current
directory. So this line is responsible for make building
`src/hello' even though we run it from the top-level. This line
also causes make install to install `src/hello' before
installing `README' (not that this order matters).
The line dist_doc_DATA = README causes `README' to be
distributed and installed in docdir. Files listed with the
_DATA primary are not automatically part of the tarball built
with make dist, so we add the dist_ prefix so they get
distributed. However, for `README' it would not have been
necessary: automake automatically distributes any
`README' file it encounters (the list of other files
automatically distributed is presented by automake --help).
The only important effect of this second line is therefore to install
`README' during make install.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on July, 20 2009 using texi2html 1.76.