Node: Top level, Next: , Previous: configure, Up: Top



The top-level Makefile.am

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.ams; only Makefiles (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.

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

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.

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.

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.


Footnotes

  1. Don't try seeking a solution where opt/Makefile is created conditionally, this is a lot trickier than the solutions presented here.