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 (*note Conditionals::) or use Autoconf `AC_SUBST' variables (*note Setting Output Variables: (autoconf)Setting Output Variables.). Using Automake conditionals is the preferred solution.
`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.
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'.
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.Created Mon Nov 8 17:42:02 2004 on tillpc with info_to_html version 0.9.6.