Makefile.am
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. Many targets (e.g. all
) in
the generated Makefile
will run 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
which do not use Automake (such as gettext
).
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
must be direct children of
the current directory. For instance, you cannot put src/subdir
into SUBDIRS
. Instead you should put SUBDIRS = subdir
into src/Makefile.am
. Automake can be used to construct packages
of arbitrary depth this way.
By default, Automake generates Makefiles
which work depth-first
(postfix
). 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. All clean
targets are run in reverse order of build
targets.
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. 1
There are two ways to setup a project like this. You can use Automake
conditionals (see Conditionals) or use Autoconf AC_SUBST
variables (see Setting Output Variables). Using Automake conditionals is the
preferred solution.
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.
AC_SUBST
Another idea 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
.
DIST_SUBDIRS
is used
As shown in the above examples, DIST_SUBDIRS
is used by targets
that need to recurse in all directories, even those which have been
conditionally left out of the build.
Precisely, DIST_SUBDIRS
is used by make dist
, make
distclean
, and make maintainer-clean
. All other recursive
targets use SUBDIRS
.
Automake will define DIST_SUBDIRS
automatically from the
possibles values of SUBDIRS
in all conditions.
If SUBDIRS
contains AC_SUBST
variables,
DIST_SUBDIRS
will not be defined correctly because Automake
doesn't know the possible values of these variables. In this case
DIST_SUBDIRS
needs to be defined manually.