[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6. The top-level `Makefile.am'


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.1 Recursing subdirectories

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.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2 Conditional subdirectories

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. (3)

There are two ways to setup a project like this. You can use Automake conditionals (see section 20. Conditionals) or use Autoconf AC_SUBST variables (see section `Setting Output Variables' in The Autoconf Manual). Using Automake conditionals is the preferred solution.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2.1 Conditional subdirectories with 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] [ ? ]

6.2.2 Conditional subdirectories with 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.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.2.3 How 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.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Jeff Bailey on December, 24 2002 using texi2html