automake
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: conditional subdir handling


From: Alexandre Duret-Lutz
Subject: Re: conditional subdir handling
Date: 27 Aug 2002 20:23:39 +0200
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7

>>> "ttn" == Thien-Thi Nguyen <address@hidden> writes:

 ttn> hi automake folks,
 ttn> i would like to have

 ttn> SUBDIRS = a b c D

 ttn> but control recursion into D via a configure.in "enable_D"
 ttn> var.  any hint would be appreciated.  if there's a
 ttn> recommended way, i'll write it up and submit a doc patch.

Amusingly this topic was discussed here last week, and we
updated the manual while we were at it.  Here is the resulting
section of the manual (this text will go into Automake 1.7, but
it applies to 1.6.x as well).  Fell free to suggest
improvements!


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.

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 (*note Conditionals::) or use Autoconf `AC_SUBST'
variables (*note Setting Output Variables: (autoconf)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.

-- 
Alexandre Duret-Lutz





reply via email to

[Prev in Thread] Current Thread [Next in Thread]