* automake.in (%appendvar): New.
(initialize_per_input): Clear it.
(macro_define): Handle += for variable defined in another condition.
* automake.texi (Conditional Sources): Use conditional += in
the example.
(General Operation, Conditionals): Remove note about broken +=.
* tests/cond21.test: New file.
* tests/condd.test: Also test conditional append to a _SOURCE
variable. Create missing directories.
* tests/Makefile.am (TESTS): Add cond21.test.
(XFAILS): Remove condd.test.
+2002-05-06 Alexandre Duret-Lutz <duret_g@epita.fr>
+
+ Fix for condd.test (conditional `+='):
+ * automake.in (%appendvar): New.
+ (initialize_per_input): Clear it.
+ (macro_define): Handle += for variable defined in another condition.
+ * automake.texi (Conditional Sources): Use conditional += in
+ the example.
+ (General Operation, Conditionals): Remove note about broken +=.
+ * tests/cond21.test: New file.
+ * tests/condd.test: Also test conditional append to a _SOURCE
+ variable. Create missing directories.
+ * tests/Makefile.am (TESTS): Add cond21.test.
+ (XFAILS): Remove condd.test.
+
2002-05-05 Tom Tromey <tromey@redhat.com>
* automake.texi (Program and Library Variables): Mention _LFLAGS.
New in 1.6a:
+* `+=' can be used in conditionals, even if the augmented variable
+ was defined for another condition.
* It is no longuer a requirement to use AM_CONFIG_HEADER instead of
AC_CONFIG_HEADERS. AM_CONFIG_HEADER is obsolete.
* Use Autoconf's --trace interface to inspect configure.ac and get
a more accurate view of it.
-* automake --output-dir is deprecated
+* automake --output-dir is deprecated.
* Many bug fixes.
\f
New in 1.6:
stamp-h.in must be in dir with h.in file
stamp-h must be in dir with output file
-* conditionals and macros
- Our current scheme cause combinatoric explosion.
-
- In fact, to be honest, I no longer understand very well why we perform
- such a closure. I mean, as is, Automake transforms (this is
- cond3.test)
-
- | bin_PROGRAMS = targ
- |
- | if ONE
- | SONE = one.c
- | else
- | SONE =
- | endif
- |
- | if TWO
- | STWO = two.c
- | else
- | STWO =
- | endif
- |
- | if THREE
- | STHREE = three.c
- | else
- | STHREE =
- | endif
- |
- | targ_SOURCES = $(SONE) $(STWO) $(STHREE)
-
- into
-
- | @ONE_FALSE@@THREE_FALSE@@TWO_TRUE@am_targ_OBJECTS = two.$(OBJEXT)
- | @ONE_FALSE@@THREE_FALSE@@TWO_FALSE@am_targ_OBJECTS =
- | @ONE_FALSE@@THREE_TRUE@@TWO_TRUE@am_targ_OBJECTS = two.$(OBJEXT) \
- | @ONE_FALSE@@THREE_TRUE@@TWO_TRUE@ three.$(OBJEXT)
- | @ONE_FALSE@@THREE_TRUE@@TWO_FALSE@am_targ_OBJECTS = three.$(OBJEXT)
- | @ONE_TRUE@@THREE_FALSE@@TWO_TRUE@am_targ_OBJECTS = one.$(OBJEXT) \
- | @ONE_TRUE@@THREE_FALSE@@TWO_TRUE@ two.$(OBJEXT)
- | @ONE_TRUE@@THREE_FALSE@@TWO_FALSE@am_targ_OBJECTS = one.$(OBJEXT)
- | @ONE_TRUE@@THREE_TRUE@@TWO_TRUE@am_targ_OBJECTS = one.$(OBJEXT) \
- | @ONE_TRUE@@THREE_TRUE@@TWO_TRUE@ two.$(OBJEXT) three.$(OBJEXT)
- | @ONE_TRUE@@THREE_TRUE@@TWO_FALSE@am_targ_OBJECTS = one.$(OBJEXT) \
- | @ONE_TRUE@@THREE_TRUE@@TWO_FALSE@ three.$(OBJEXT)
-
- why don't we just output
-
- | @ONE_TRUE@am_SONE_OBJECTS = one.$(OBJEXT)
- | @ONE_FALSE@am_SONE_OBJECTS =
- |
- | @TWO_TRUE@am_STWO_OBJECTS = two.$(OBJEXT)
- | @TWO_FALSE@am_STWO_OBJECTS =
- |
- | @THREE_TRUE@am_STHREE_OBJECTS = three.$(OBJEXT)
- | @THREE_FALSE@am_STHREE_OBJECTS =
- |
- | am_targ_OBJECTS = $(am_SONE_OBJECTS) $(am_STWO_OBJECTS) $(am_STHREE_OBJECTS)
-
- which means also, why do we look for the closure of PROGRAMS, instead
- of just adding $(EXEEXT) to all its components and sub components
- (i.e., inside sub vars such as $(SONE) above being a sub var of
- targ_SOURCES)?
-
-
- Aaaaaaaaaaah! I think I know... Must be because of `+='.
-
- Hm... No. Indeed we transform
-
- | FOO = foo
- | if BAR
- | FOO += BAR
- | endif
-
- into
-
- | @BAR_TRUE@FOO = foo bar
- | @BAR_FALSE@FOO = foo
-
- but this seems good to me too?
-
- | FOO = foo $(BAR_FOO)
- | @BAR_TRUE@BAR_FOO = bar
- | @BAR_FALSE@BAR_FOO =
-
-
-* foo=bar
- if cond
- foo += joe
- endif
- ... this ought to work. The fix is probably complicated, but might
- come for free when we rewrite the handling of conditionals.
-
* `distcheck' and `dist' should depend on `all'
* Add code to generate foo-config script like gnome, gtk
# The key is the variable _content_, and the value is the variable name.
my %subobjvar = ();
+# This hash records helper variables used to implement '+=' in conditionals.
+# Keys have the form "VAR:CONDITIONS". The value associated to a key is
+# the named of the helper variable used to append to VAR in CONDITIONS.
+my %appendvar = ();
+
## --------------------------------- ##
## Forward subroutine declarations. ##
## --------------------------------- ##
%require_file_found = ();
%subobjvar = ();
+
+ %appendvar = ();
}
my ($var, $cond) = @_;
foreach my $vcond (keys %{$var_value{$var}})
{
+ # Note that these rules doesn't consider the following
+ # example as ambiguous.
+ #
+ # if COND1
+ # FOO = foo
+ # endif
+ # if COND2
+ # FOO = bar
+ # endif
+ #
+ # It's up to the user to not define COND1 and COND2
+ # simultaneously.
my $message;
if ($vcond eq $cond)
{
$value =~ s/\\$//mg
if $type eq '+' && $var_is_am;
- # Differentiate the first assignment (including with `+=').
+ # Differentiate assignment types.
+
+ # 1. append (+=) to a variable defined for current condition
if ($type eq '+' && defined $var_value{$var}{$cond})
{
if (chomp $var_value{$var}{$cond})
}
$var_value{$var}{$cond} .= $value;
}
+ # 2. append (+=) to a variable defined for *another* condition
+ elsif ($type eq '+' && keys %{$var_value{$var}})
+ {
+ # * Generally, $cond is not TRUE. For instance:
+ # FOO = foo
+ # if COND
+ # FOO += bar
+ # endif
+ # In this case, we declare an helper variable conditionally,
+ # and append it to FOO:
+ # FOO = foo $(am__append_1)
+ # @COND_TRUE@am__append_1 = bar
+ # Of course if FOO is defined under several conditions, we add
+ # $(am__append_1) to each definitions.
+ #
+ # * If $cond is TRUE, we don't need the helper variable. E.g., in
+ # if COND1
+ # FOO = foo1
+ # else
+ # FOO = foo2
+ # endif
+ # FOO += bar
+ # we can add bar directly to all definition of FOO, and output
+ # @COND_TRUE@FOO = foo1 bar
+ # @COND_FALSE@FOO = foo2 bar
+
+ # Do we need an helper variable?
+ if ($cond ne 'TRUE')
+ {
+ # Does the helper variable already exists?
+ my $key = "$var:$cond";
+ if (exists $appendvar{$key})
+ {
+ # Yes, let's simply append to it.
+ $var = $appendvar{$key};
+ $var_is_am = 1;
+ }
+ else
+ {
+ # No, create it.
+ my $num = 1 + keys (%appendvar);
+ my $hvar = "am__append_$num";
+ $appendvar{$key} = $hvar;
+ ¯o_define ($hvar, 1, '+', $cond, $value, $where);
+ push @var_list, $hvar;
+ # Now HVAR is to be added to VAR.
+ $value = "\$($hvar)";
+ }
+ }
+
+ # Add VALUE to all definitions of VAR.
+ foreach my $vcond (keys %{$var_value{$var}})
+ {
+ ¯o_define ($var, $var_is_am, '+', $vcond, $value, $where);
+ }
+ }
+ # 3. first assignment (=, :=, or +=)
else
{
# The first assignment to a macro sets its location. Ideally I
specified on the left. Automake will translate the operator into
an ordinary @samp{=} operator; @samp{+=} will thus work with any make program.
-Note that it is only valid to append to a macro in the same conditional
-context as the macro was originally defined. @xref{Conditional Append}, for
-more information.
-
Automake tries to group comments with adjoining targets and macro
definitions in an intelligent way.
@c FIXME: What does this imply practically?
@samp{EXTRA_} variable, because Automake will examine the contents of
each variable to construct the complete list of source files.
-If your program uses a lot of files, you will probably prefer to use an
-intermediate variable to hold conditional sources.
+If your program uses a lot of files, you will probably prefer a
+conditional @code{+=}.
@example
bin_PROGRAMS = hello
+hello_SOURCES = hello-common.c
if LINUX
-hello_cond = hello-linux.c
+hello_cond += hello-linux.c
else
-hello_cond = hello-generic.c
+hello_cond += hello-generic.c
endif
-hello_SOURCES = hello-common.c $(hello_cond)
@end example
@node Conditional Programs, , Conditional Sources, A Program
@noindent
Unbalanced conditions are errors.
-@anchor{Conditional Append}
-Conditionals do not interact very smoothly with the append operator.
-In particular, an append must happen in the same conditional context as
-the original assignment. This means that the following will not work:
-
-@example
-DBG = foo
-if DEBUG
-DBG += bar
-endif DEBUG
-@end example
-
-The behaviour which is probably desired in this situation can be obtained
-using a temporary variable:
-
-@example
-if DEBUG
-TMP_DBG = bar
-endif DEBUG
-DBG = foo $(TMP_DBG)
-@end example
-
-This restriction may be lifted in future versions of automake.
-
Note that conditionals in Automake are not the same as conditionals in
GNU Make. Automake conditionals are checked at configure time by the
@file{configure} script, and affect the translation from
## Process this file with automake to create Makefile.in
-XFAIL_TESTS = condd.test subdir5.test auxdir2.test cond17.test
+XFAIL_TESTS = subdir5.test auxdir2.test cond17.test
TESTS = \
acinclude.test \
cond18.test \
cond19.test \
cond20.test \
+cond21.test \
condd.test \
condincl.test \
condincl2.test \
sysconfdir = @sysconfdir@
target_alias = @target_alias@
-XFAIL_TESTS = condd.test subdir5.test auxdir2.test cond17.test
+XFAIL_TESTS = subdir5.test auxdir2.test cond17.test
TESTS = \
acinclude.test \
cond18.test \
cond19.test \
cond20.test \
+cond21.test \
condd.test \
condincl.test \
condincl2.test \
--- /dev/null
+#! /bin/sh
+
+# Check for use of = and += in different conditions.
+
+. $srcdir/defs || exit 1
+
+cat >> configure.in << 'END'
+AC_PROG_CC
+AM_CONDITIONAL(COND1, true)
+AM_CONDITIONAL(COND2, true)
+AM_CONDITIONAL(COND3, true)
+AC_OUTPUT
+END
+
+cat > Makefile.am << 'END'
+
+FOO = foo
+if COND1
+ FOO += foo1
+else
+ FOO += foon1
+endif
+if COND2
+ FOO += foo2
+else
+ FOO += foon2
+endif
+## Note that we add `foo1b' after `foo2'; however because it is appended in
+## the same condition as `foo1', it should use the same helper variable
+## and thus appear right after `foo1' in the output.
+if COND1
+ FOO += foo1b
+else
+ FOO += foon1b
+endif
+
+if COND1
+if COND2
+ BAR = bar12
+else
+ BAR = bar1n2
+endif
+else
+ BAR = barn1
+endif
+
+BAR += bar
+
+if COND3
+ BAR += bar3
+endif
+
+test:
+ @echo BAR: $(BAR) :BAR
+ @echo FOO: $(FOO) :FOO
+END
+
+set -e
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE -a
+./configure
+$MAKE test | fgrep 'BAR: bar12 bar bar3 :BAR'
+$MAKE test | fgrep 'FOO: foo foo1 foo1b foo2 :FOO'
. $srcdir/defs || exit 1
cat >> configure.in << 'END'
+AC_PROG_CC
AM_CONDITIONAL(COND1, true)
END
if COND1
SUBDIRS += bar
endif
+
+# Small example from the manual
+bin_PROGRAMS = hello
+hello_SOURCES = hello-common.c
+if COND1
+hello_SOURCES += hello-cond1.c
+else
+hello_SOURCES += hello-generic.c
+endif
END
+mkdir foo bar
+
$ACLOCAL || exit 1
$AUTOMAKE