| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
For simple projects that distribute all files in the same directory it is enough to have a single `Makefile.am' that builds everything in place.
In larger projects it is common to organize files in different
directories, in a tree. For instance one directory per program, per
library or per module. The traditional approach is to build these
subdirectories recursively: each directory contains its `Makefile'
(generated from `Makefile.am'), and when make is run
from the top level directory it enters each subdirectory in turn to
build its contents.
| 7.1 Recursing subdirectories | Building subdirectories recursively | |
| 7.2 Conditional Subdirectories | Conditionally not building directories | |
| 7.3 An Alternative Approach to Subdirectories | Subdirectories without recursion | |
| 7.4 Nesting Packages | Nesting packages |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In packages with subdirectories, the top level `Makefile.am' must
tell Automake which subdirectories are to be built. This is done via
the SUBDIRS variable.
The SUBDIRS variable holds a list of subdirectories in which
building of various sorts can occur. The rules for many targets
(e.g., all) in the generated `Makefile' will run commands
both locally and in all specified subdirectories. Note that the
directories listed in SUBDIRS are not required to contain
`Makefile.am's; only `Makefile's (after configuration).
This allows inclusion of libraries from packages that do not use
Automake (such as gettext; see also Third-Party `Makefile's).
In packages that use subdirectories, the top-level `Makefile.am' is often very short. For instance, here is the `Makefile.am' from the GNU Hello distribution:
EXTRA_DIST = BUGS ChangeLog.O README-alpha SUBDIRS = doc intl po src tests |
When Automake invokes make in a subdirectory, it uses the value
of the MAKE variable. It passes the value of the variable
AM_MAKEFLAGS to the make invocation; this can be set in
`Makefile.am' if there are flags you must always pass to
make.
The directories mentioned in SUBDIRS are usually direct
children of the current directory, each subdirectory containing its
own `Makefile.am' with a SUBDIRS pointing to deeper
subdirectories. Automake can be used to construct packages of
arbitrary depth this way.
By default, Automake generates `Makefiles' that work depth-first
in postfix order: the subdirectories are built before the current
directory. However, it is possible to change this ordering. You can
do this by putting `.' into SUBDIRS. For instance,
putting `.' first will cause a prefix ordering of
directories.
Using
SUBDIRS = lib src . test |
will cause `lib/' to be built before `src/', then the current directory will be built, finally the `test/' directory will be built. It is customary to arrange test directories to be built after everything else since they are meant to test what has been constructed.
All clean rules are run in reverse order of build rules.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
It is possible to define the SUBDIRS variable conditionally if,
like in the case of GNU Inetutils, you want to only build a subset of
the entire package.
To illustrate how this works, let's assume we have two directories
`src/' and `opt/'. `src/' should always be built, but we
want to decide in configure whether `opt/' will be built
or not. (For this example we will assume that `opt/' should be
built when the variable `$want_opt' was set to `yes'.)
Running make should thus recurse into `src/' always, and
then maybe in `opt/'.
However `make dist' should always recurse into both `src/' and `opt/'. Because `opt/' should be distributed even if it is not needed in the current configuration. This means `opt/Makefile' should be created unconditionally.
There are two ways to setup a project like this. You can use Automake
conditionals (see section Conditionals) or use Autoconf AC_SUBST
variables (see (autoconf)Setting Output Variables section `Setting Output Variables' in The Autoconf Manual). Using Automake
conditionals is the preferred solution. Before we illustrate these
two possibilities, let's introduce DIST_SUBDIRS.
7.2.1 SUBDIRS vs. DIST_SUBDIRS | Two sets of directories | |
7.2.2 Subdirectories with AM_CONDITIONAL | Specifying conditional subdirectories | |
7.2.3 Subdirectories with AC_SUBST | Another way for conditional recursion | |
| 7.2.4 Unconfigured Subdirectories | Not even creating a `Makefile' |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
SUBDIRS vs. DIST_SUBDIRS Automake considers two sets of directories, defined by the variables
SUBDIRS and DIST_SUBDIRS.
SUBDIRS contains the subdirectories of the current directory
that must be built (see section Recursing subdirectories). It must be defined
manually; Automake will never guess a directory is to be built. As we
will see in the next two sections, it is possible to define it
conditionally so that some directory will be omitted from the build.
DIST_SUBDIRS is used in rules that need to recurse in all
directories, even those that have been conditionally left out of the
build. Recall our example where we may not want to build subdirectory
`opt/', but yet we want to distribute it? This is where
DIST_SUBDIRS comes into play: `opt' may not appear in
SUBDIRS, but it must appear in DIST_SUBDIRS.
Precisely, DIST_SUBDIRS is used by `make
maintainer-clean', `make distclean' and `make dist'. All
other recursive rules use SUBDIRS.
If SUBDIRS is defined conditionally using Automake
conditionals, Automake will define DIST_SUBDIRS automatically
from the possible values of SUBDIRS in all conditions.
If SUBDIRS contains AC_SUBST variables,
DIST_SUBDIRS will not be defined correctly because Automake
does not know the possible values of these variables. In this case
DIST_SUBDIRS needs to be defined manually.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AM_CONDITIONAL `configure' should output the `Makefile' for each directory and define a condition into which `opt/' should be built.
… AM_CONDITIONAL([COND_OPT], [test "$want_opt" = yes]) AC_CONFIG_FILES([Makefile src/Makefile opt/Makefile]) … |
Then SUBDIRS can be defined in the top-level `Makefile.am'
as follows.
if COND_OPT MAYBE_OPT = opt endif SUBDIRS = src $(MAYBE_OPT) |
As you can see, running make will rightly recurse into
`src/' and maybe `opt/'.
As you can't see, running `make dist' will recurse into both
`src/' and `opt/' directories because `make dist', unlike
`make all', doesn't use the SUBDIRS variable. It uses the
DIST_SUBDIRS variable.
In this case Automake will define `DIST_SUBDIRS = src opt'
automatically because it knows that MAYBE_OPT can contain
`opt' in some condition.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
AC_SUBST Another possibility is to define MAYBE_OPT from
`./configure' using AC_SUBST:
… if test "$want_opt" = yes; then MAYBE_OPT=opt else MAYBE_OPT= fi AC_SUBST([MAYBE_OPT]) AC_CONFIG_FILES([Makefile src/Makefile opt/Makefile]) … |
In this case the top-level `Makefile.am' should look as follows.
SUBDIRS = src $(MAYBE_OPT) DIST_SUBDIRS = src opt |
The drawback is that since Automake cannot guess what the possible
values of MAYBE_OPT are, it is necessary to define
DIST_SUBDIRS.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The semantics of DIST_SUBDIRS are often misunderstood by some
users that try to configure and build subdirectories
conditionally. Here by configuring we mean creating the
`Makefile' (it might also involve running a nested
configure script: this is a costly operation that explains
why people want to do it conditionally, but only the `Makefile'
is relevant to the discussion).
The above examples all assume that every `Makefile' is created,
even in directories that are not going to be built. The simple reason
is that we want `make dist' to distribute even the directories
that are not being built (e.g., platform-dependent code), hence
`make dist' must recurse into the subdirectory, hence this
directory must be configured and appear in DIST_SUBDIRS.
Building packages that do not configure every subdirectory is a tricky business, and we do not recommend it to the novice as it is easy to produce an incomplete tarball by mistake. We will not discuss this topic in depth here, yet for the adventurous here are a few rules to remember.
|
In order to prevent recursion in some unconfigured directory you
must therefore ensure that this directory does not appear in
DIST_SUBDIRS (and SUBDIRS). For instance, if you define
SUBDIRS conditionally using AC_SUBST and do not define
DIST_SUBDIRS explicitly, it will be default to
`$(SUBDIRS)'; another possibility is to force DIST_SUBDIRS
= $(SUBDIRS).
Of course, directories that are omitted from DIST_SUBDIRS will
not be distributed unless you make other arrangements for this to
happen (for instance, always running `make dist' in a
configuration where all directories are known to appear in
DIST_SUBDIRS; or writing a dist-hook target to
distribute these directories).
In few packages, unconfigured directories are not even expected to
be distributed. Although these packages do not require the
aforementioned extra arrangements, there is another pitfall. If the
name of a directory appears in SUBDIRS or DIST_SUBDIRS,
automake will make sure the directory exists. Consequently
automake cannot be run on such a distribution when one
directory has been omitted. One way to avoid this check is to use the
AC_SUBST method to declare conditional directories; since
automake does not know the values of AC_SUBST
variables it cannot ensure the corresponding directory exists.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If you've ever read Peter Miller's excellent paper,
Recursive Make Considered Harmful, the preceding sections on the use of
subdirectories will probably come as unwelcome advice. For those who
haven't read the paper, Miller's main thesis is that recursive
make invocations are both slow and error-prone.
Automake provides sufficient cross-directory support (3) to enable you to write a single `Makefile.am' for a complex multi-directory package.
By default an installable file specified in a subdirectory will have its directory name stripped before installation. For instance, in this example, the header file will be installed as `$(includedir)/stdio.h':
include_HEADERS = inc/stdio.h |
However, the `nobase_' prefix can be used to circumvent this path stripping. In this example, the header file will be installed as `$(includedir)/sys/types.h':
nobase_include_HEADERS = sys/types.h |
`nobase_' should be specified first when used in conjunction with either `dist_' or `nodist_' (see section Fine-grained Distribution Control). For instance:
nobase_dist_pkgdata_DATA = images/vortex.pgm sounds/whirl.ogg |
Finally, note that a variable using the `nobase_' prefix can often be replaced by several variables, one for each destination directory (see section The Uniform Naming Scheme). For instance, the last example could be rewritten as follows:
imagesdir = $(pkgdatadir)/images soundsdir = $(pkgdatadir)/sounds dist_images_DATA = images/vortex.pgm dist_sounds_DATA = sounds/whirl.ogg |
This latter syntax makes it possible to change one destination directory without changing the layout of the source tree.
Currently, `nobase_*_LTLIBRARIES' are the only exception to this rule, in that there is no particular installation order guarantee for an otherwise equivalent set of variables without `nobase_' prefix.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In the GNU Build System, packages can be nested to arbitrary depth. This means that a package can embed other packages with their own `configure', `Makefile's, etc.
These other packages should just appear as subdirectories of their
parent package. They must be listed in SUBDIRS like other
ordinary directories. However the subpackage's `Makefile's
should be output by its own `configure' script, not by the
parent's `configure'. This is achieved using the
AC_CONFIG_SUBDIRS Autoconf macro (see AC_CONFIG_SUBDIRS: (autoconf)Subdirectories section `Configuring Other Packages in Subdirectories' in The Autoconf Manual).
Here is an example package for an arm program that links with
a hand library that is a nested package in subdirectory
`hand/'.
arm's `configure.ac':
AC_INIT([arm], [1.0]) AC_CONFIG_AUX_DIR([.]) AM_INIT_AUTOMAKE AC_PROG_CC AC_CONFIG_FILES([Makefile]) # Call hand's ./configure script recursively. AC_CONFIG_SUBDIRS([hand]) AC_OUTPUT |
arm's `Makefile.am':
# Build the library in the hand subdirectory first. SUBDIRS = hand # Include hand's header when compiling this directory. AM_CPPFLAGS = -I$(srcdir)/hand bin_PROGRAMS = arm arm_SOURCES = arm.c # link with the hand library. arm_LDADD = hand/libhand.a |
Now here is hand's `hand/configure.ac':
AC_INIT([hand], [1.2]) AC_CONFIG_AUX_DIR([.]) AM_INIT_AUTOMAKE AC_PROG_CC AC_PROG_RANLIB AC_CONFIG_FILES([Makefile]) AC_OUTPUT |
and its `hand/Makefile.am':
lib_LIBRARIES = libhand.a libhand_a_SOURCES = hand.c |
When `make dist' is run from the top-level directory it will
create an archive `arm-1.0.tar.gz' that contains the arm
code as well as the `hand' subdirectory. This package can be
built and installed like any ordinary package, with the usual
`./configure && make && make install' sequence (the hand
subpackage will be built and installed by the process).
When `make dist' is run from the hand directory, it will create a self-contained `hand-1.2.tar.gz' archive. So although it appears to be embedded in another package, it can still be used separately.
The purpose of the `AC_CONFIG_AUX_DIR([.])' instruction is to
force Automake and Autoconf to search for auxiliary scripts in the
current directory. For instance, this means that there will be two
copies of `install-sh': one in the top-level of the arm
package, and another one in the `hand/' subdirectory for the
hand package.
The historical default is to search for these auxiliary scripts in
the parent directory and the grandparent directory. So if the
`AC_CONFIG_AUX_DIR([.])' line was removed from
`hand/configure.ac', that subpackage would share the auxiliary
script of the arm package. This may looks like a gain in size
(a few kilobytes), but it is actually a loss of modularity as the
hand subpackage is no longer self-contained (`make dist'
in the subdirectory will not work anymore).
Packages that do not use Automake need more work to be integrated this way. See section Third-Party `Makefile's.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on July, 20 2009 using texi2html 1.76.