From: Alexandre Duret-Lutz Date: Fri, 23 Aug 2002 19:11:31 +0000 (+0000) Subject: * automake.texi (Top level): More words about conditional X-Git-Tag: Release-1-6d~45 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=06e33d46fc2c0bf2d7586f3d087b163d7428299b;p=automake.git * automake.texi (Top level): More words about conditional subdirectories. Don't mention AC_PROG_MAKE_SET. * tests/subdircond2.test, tests/subdircond3.test: New files. * tests/Makefile.am (TESTS): Add them. --- diff --git a/ChangeLog b/ChangeLog index ac54725f..81549fb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2002-08-23 Alexandre Duret-Lutz + * automake.texi (Top level): More words about conditional + subdirectories. Don't mention AC_PROG_MAKE_SET. + * tests/subdircond2.test, tests/subdircond3.test: New files. + * tests/Makefile.am (TESTS): Add them. + For PR automake/347: * automake.in (MACRO_PATTERN): Allow `.' in variable names. (scan_variable_expansions, check_variable_expansions): New functions. diff --git a/automake.texi b/automake.texi index 7ef8fba1..e40a0902 100644 --- a/automake.texi +++ b/automake.texi @@ -1756,6 +1756,8 @@ be @file{$(datadir)/aclocal}). @node Top level, Alternative, configure, Top @chapter The top-level @file{Makefile.am} +@section Recursing subdirectories + @cindex SUBDIRS, explained In packages with subdirectories, the top level @file{Makefile.am} must @@ -1769,10 +1771,7 @@ the generated @file{Makefile} will run both locally and in all specified subdirectories. Note that the directories listed in @code{SUBDIRS} are not required to contain @file{Makefile.am}s; only @file{Makefile}s (after configuration). This allows inclusion of libraries from packages -which do not use Automake (such as @code{gettext}). The directories -mentioned in @code{SUBDIRS} must be direct children of the current -directory. For instance, you cannot put @samp{src/subdir} into -@code{SUBDIRS}. +which do not use Automake (such as @code{gettext}). In packages that use subdirectories, the top-level @file{Makefile.am} is often very short. For instance, here is the @file{Makefile.am} from the @@ -1783,63 +1782,152 @@ EXTRA_DIST = BUGS ChangeLog.O README-alpha SUBDIRS = doc intl po src tests @end example -@cindex SUBDIRS, overriding -@cindex Overriding SUBDIRS +When Automake invokes @code{make} in a subdirectory, it uses the value +of the @code{MAKE} variable. It passes the value of the variable +@code{AM_MAKEFLAGS} to the @code{make} invocation; this can be set in +@file{Makefile.am} if there are flags you must always pass to +@code{make}. +@vindex MAKE +@vindex MAKEFLAGS + +The directories mentioned in @code{SUBDIRS} must be direct children of +the current directory. For instance, you cannot put @samp{src/subdir} +into @code{SUBDIRS}. Instead you should put @code{SUBDIRS = subdir} +into @file{src/Makefile.am}. Automake can be used to construct packages +of arbitrary depth this way. + +By default, Automake generates @file{Makefiles} which work depth-first +(@samp{postfix}). However, it is possible to change this ordering. You +can do this by putting @samp{.} into @code{SUBDIRS}. For instance, +putting @samp{.} first will cause a @samp{prefix} ordering of +directories. All @samp{clean} targets are run in reverse order of build +targets. -It is possible to override the @code{SUBDIRS} variable if, like in the -case of GNU @code{Inetutils}, you want to only build a subset of the -entire package. In your @file{Makefile.am} include: +@section Conditional subdirectories +@cindex Subdirectories, building conditionally +@cindex Conditional subdirectories +@cindex @code{SUBDIRS}, conditional +@cindex Conditional @code{SUBDIRS} + +It is possible to define the @code{SUBDIRS} variable conditionally if, +like in the case of GNU @code{Inetutils}, you want to only build a +subset of the entire package. + +To illustrate how this works, let's assume we have two directories +@file{src/} and @file{opt/}. @file{src/} should always be built, but we +want to decide in @code{./configure} whether @file{opt/} will be built +or not. (For this example we will assume that @file{opt/} should be +built when the variable @code{$want_opt} was set to @code{yes}.) + +Running @code{make} should thus recurse into @file{src/} always, and +then maybe in @file{opt/}. + +However @code{make dist} should always recurse into both @file{src/} and +@file{opt/}. Because @file{opt/} should be distributed even if it is +not needed in the current configuration. This means @file{opt/Makefile} +should be created unconditionally. @footnote{Don't try seeking a +solution where @file{opt/Makefile} is created conditionally, this is a +lot trickier than the solutions presented here.} + +There are two ways to setup a project like this. You can use Automake +conditionals (@pxref{Conditionals}) or use Autoconf @code{AC_SUBST} +variables (@pxref{Setting Output Variables, , Setting Output Variables, +autoconf, The Autoconf Manual}). Using Automake conditionals is the +preferred solution. + +@subsection Conditional subdirectories with @code{AM_CONDITIONAL} +@cindex @code{SUBDIRS} and @code{AM_CONDITIONAL} +@cindex @code{AM_CONDITIONAL} and @code{SUBDIRS} + +@c The test case for the setup described here is +@c test/subdircond2.test +@c Try to keep it in sync. + +@file{configure} should output the @file{Makefile} for each directory +and define a condition into which @file{opt/} should be built. @example -SUBDIRS = @@MY_SUBDIRS@@ +@dots{} +AM_CONDITIONAL([COND_OPT], [test "$want_opt" = yes]) +AC_CONFIG_FILES([Makefile src/Makefile opt/Makefile]) +@dots{} @end example -Then in your @file{configure.in} you can specify: +Then @code{SUBDIRS} can be defined in the top-level @file{Makefile.am} +as follows. @example -MY_SUBDIRS="src doc lib po" -AC_SUBST(MY_SUBDIRS) +if COND_OPT + MAYBE_OPT = opt +endif +SUBDIRS = src $(MAYBE_OPT) @end example -(Note that we don't use the variable name @code{SUBDIRS} in our -@file{configure.in}; that would cause Automake to believe that every -@file{Makefile.in} should recurse into the listed subdirectories.) +As you can see, running @code{make} will rightly recurse into +@file{src/} and maybe @file{opt/}. -The upshot of this is that Automake is tricked into building the package -to take the subdirs, but doesn't actually bind that list until -@code{configure} is run. +@vindex DIST_SUBDIRS +As you can't see, running @code{make dist} will recurse into both +@file{src/} and @file{opt/} directories because @code{make dist}, unlike +@code{make all}, doesn't use the @code{SUBDIRS} variable. It uses the +@code{DIST_SUBDIRS} variable. -Although the @code{SUBDIRS} variable can contain configure substitutions -(e.g. @samp{@@DIRS@@}); Automake itself does not actually examine the -contents of this variable. +In this case Automake will define @code{DIST_SUBDIRS = src opt} +automatically because it knows that @code{MAYBE_OPT} can contain +@code{opt} in some condition. -If @code{SUBDIRS} is defined, then your @file{configure.in} must include -@code{AC_PROG_MAKE_SET}. When Automake invokes @code{make} in a -subdirectory, it uses the value of the @code{MAKE} variable. It passes -the value of the variable @code{AM_MAKEFLAGS} to the @code{make} -invocation; this can be set in @file{Makefile.am} if there are flags you -must always pass to @code{make}. -@vindex MAKE -@vindex MAKEFLAGS +@subsection Conditional subdirectories with @code{AC_SUBST} +@cindex @code{SUBDIRS} and @code{AC_SUBST} +@cindex @code{AC_SUBST} and @code{SUBDIRS} -The use of @code{SUBDIRS} is not restricted to just the top-level -@file{Makefile.am}. Automake can be used to construct packages of -arbitrary depth. +@c The test case for the setup described here is +@c test/subdircond3.test +@c Try to keep it in sync. -By default, Automake generates @file{Makefiles} which work depth-first -(@samp{postfix}). However, it is possible to change this ordering. You -can do this by putting @samp{.} into @code{SUBDIRS}. For instance, -putting @samp{.} first will cause a @samp{prefix} ordering of -directories. All @samp{clean} targets are run in reverse order of build -targets. +Another idea is to define @code{MAYBE_OPT} from @file{./configure} using +@code{AC_SUBST}: + +@example +@dots{} +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]) +@dots{} +@end example + +In this case the top-level @file{Makefile.am} should look as follows. + +@example +SUBDIRS = src $(MAYBE_OPT) +DIST_SUBDIRS = src opt +@end example + +The drawback is that since Automake cannot guess what the possible +values of @code{MAYBE_OPT} are, it is necessary to define +@code{DIST_SUBDIRS}. + +@subsection How @code{DIST_SUBDIRS} is used +@cindex @code{DIST_SUBDIRS}, explained + +As shown in the above examples, @code{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, @code{DIST_SUBDIRS} is used by @code{make dist}, @code{make +distclean}, and @code{make maintainer-clean}. All other recursive +targets use @code{SUBDIRS}. + +Automake will define @code{DIST_SUBDIRS} automatically from the +possibles values of @code{SUBDIRS} in all conditions. -Sometimes, such as when running @code{make dist}, you want all possible -subdirectories to be examined. In this case Automake will use -@code{DIST_SUBDIRS}, instead of @code{SUBDIRS}, to determine where to -recurse. This variable will also be used when the user runs -@code{distclean} or @code{maintainer-clean}. It should be set to the -full list of subdirectories in the project. If this variable is not set, -Automake will attempt to set it for you. +If @code{SUBDIRS} contains @code{AC_SUBST} variables, +@code{DIST_SUBDIRS} will not be defined correctly because Automake +doesn't know the possible values of these variables. In this case +@code{DIST_SUBDIRS} needs to be defined manually. @node Alternative, Rebuilding, Top level, Top diff --git a/stamp-vti b/stamp-vti index cb189c48..2a10e203 100644 --- a/stamp-vti +++ b/stamp-vti @@ -1,4 +1,4 @@ -@set UPDATED 22 August 2002 +@set UPDATED 23 August 2002 @set UPDATED-MONTH August 2002 @set EDITION 1.6c @set VERSION 1.6c diff --git a/tests/Makefile.am b/tests/Makefile.am index 2910477d..8fc12643 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -345,6 +345,8 @@ subdir6.test \ subdir7.test \ subdirbuiltsources.test \ subdircond.test \ +subdircond2.test \ +subdircond3.test \ subobj.test \ subobj2.test \ subobj3.test \ diff --git a/tests/Makefile.in b/tests/Makefile.in index d19ac282..5e1d4dad 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -433,6 +433,8 @@ subdir6.test \ subdir7.test \ subdirbuiltsources.test \ subdircond.test \ +subdircond2.test \ +subdircond3.test \ subobj.test \ subobj2.test \ subobj3.test \ diff --git a/tests/subdircond2.test b/tests/subdircond2.test new file mode 100755 index 00000000..28e6b5a4 --- /dev/null +++ b/tests/subdircond2.test @@ -0,0 +1,77 @@ +#! /bin/sh + +# The for conditional SUBDIRS. +# SUBDIRS + AM_CONDITIONAL setup from the manual. +# Lots of lines here are duplicated in subdircond3.test. + +. $srcdir/defs || exit 1 + +set -e + +cat >>configure.in <<'END' +AM_CONDITIONAL([COND_OPT], [test "$want_opt" = yes]) +AC_CONFIG_FILES([src/Makefile opt/Makefile]) +AC_OUTPUT +END + +cat >Makefile.am << 'END' +if COND_OPT + MAYBE_OPT = opt +endif +SUBDIRS = src $(MAYBE_OPT) + +# Testing targets. +# +# We want to ensure that +# - src/source and opt/source are always distributed. +# - src/result is always built +# - opt/result is built conditionally +# +# We rely on `distcheck' to run `check-local' and use +# `sanity1' and `sanity2' as evidences that test-build was run. + +if COND_OPT +test-build: all + test -f src/result + test -f opt/result + : > $(top_builddir)/../../sanity2 +else +test-build: all + test -f src/result + test ! -f opt/result + : > $(top_builddir)/../../sanity1 +endif + +test-dist: distdir + test -f $(distdir)/src/source + test -f $(distdir)/opt/source + +check-local: test-build test-dist +END + +mkdir src opt +: > src/source +: > opt/source + +cat >src/Makefile.am << 'END' +EXTRA_DIST = source +all-local: result +CLEANFILES = result + +result: source + cp $(srcdir)/source result +END + +# We want in opt/ the same Makefile as in src/. Let's exercize `include'. +cat >opt/Makefile.am << 'END' +include ../src/Makefile.am +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE --add-missing +./configure +$MAKE distcheck +test -f sanity1 +$MAKE DISTCHECK_CONFIGURE_FLAGS=want_opt=yes distcheck +test -f sanity2 diff --git a/tests/subdircond3.test b/tests/subdircond3.test new file mode 100755 index 00000000..d2dc4a7e --- /dev/null +++ b/tests/subdircond3.test @@ -0,0 +1,78 @@ +#! /bin/sh + +# The for conditional SUBDIRS. +# SUBDIRS + AC_SUBST setup from the manual. +# Lots of lines here are duplicated in subdircond2.test. + +. $srcdir/defs || exit 1 + +set -e + +cat >>configure.in <<'END' +if test "$want_opt" = yes; then + MAYBE_OPT=opt +else + MAYBE_OPT= +fi +AC_SUBST([MAYBE_OPT]) +AC_CONFIG_FILES([src/Makefile opt/Makefile]) +AC_OUTPUT +END + +cat >Makefile.am << 'END' +SUBDIRS = src $(MAYBE_OPT) +DIST_SUBDIRS = src opt + +# Testing targets. +# +# We want to ensure that +# - src/source and opt/source are always distributed. +# - src/result is always built +# - opt/result is built conditionally +# +# We rely on `distcheck' to run `check-local' and use +# `sanity1' and `sanity2' as evidences that test-build was run. + +test-build: all + test -f src/result + if test -n "$(MAYBE_OPT)"; then \ + test -f opt/result || exit 1; \ + : > $(top_builddir)/../../sanity2 || exit 1; \ + else \ + test ! -f opt/result || exit 1; \ + : > $(top_builddir)/../../sanity1 || exit 1; \ + fi + +test-dist: distdir + test -f $(distdir)/src/source + test -f $(distdir)/opt/source + +check-local: test-build test-dist +END + +mkdir src opt +: > src/source +: > opt/source + +cat >src/Makefile.am << 'END' +EXTRA_DIST = source +all-local: result +CLEANFILES = result + +result: source + cp $(srcdir)/source result +END + +# We want in opt/ the same Makefile as in src/. Let's exercize `include'. +cat >opt/Makefile.am << 'END' +include ../src/Makefile.am +END + +$ACLOCAL +$AUTOCONF +$AUTOMAKE --add-missing +./configure +$MAKE distcheck +test -f sanity1 +$MAKE DISTCHECK_CONFIGURE_FLAGS=want_opt=yes distcheck +test -f sanity2 diff --git a/version.texi b/version.texi index cb189c48..2a10e203 100644 --- a/version.texi +++ b/version.texi @@ -1,4 +1,4 @@ -@set UPDATED 22 August 2002 +@set UPDATED 23 August 2002 @set UPDATED-MONTH August 2002 @set EDITION 1.6c @set VERSION 1.6c