From e08fb7886abe97cb253b98d7d94b1d3db4095b4f Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Mon, 6 May 2002 06:51:05 +0000 Subject: [PATCH] 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. --- ChangeLog | 15 +++++++++ NEWS | 4 ++- TODO | 91 ------------------------------------------------------- automake.in | 80 +++++++++++++++++++++++++++++++++++++++++++++++- automake.texi | 38 +++-------------------- tests/Makefile.am | 3 +- tests/Makefile.in | 3 +- tests/cond21.test | 65 +++++++++++++++++++++++++++++++++++++++ tests/condd.test | 12 ++++++++ 9 files changed, 183 insertions(+), 128 deletions(-) create mode 100755 tests/cond21.test diff --git a/ChangeLog b/ChangeLog index 96ad6f7..f6bc9aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2002-05-06 Alexandre Duret-Lutz + + 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 * automake.texi (Program and Library Variables): Mention _LFLAGS. diff --git a/NEWS b/NEWS index dac1f75..1af7979 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,11 @@ 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. New in 1.6: diff --git a/TODO b/TODO index fc96666..3fb9ce3 100644 --- a/TODO +++ b/TODO @@ -173,97 +173,6 @@ Alex Hornby 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 diff --git a/automake.in b/automake.in index 7712b68..cde6166 100755 --- a/automake.in +++ b/automake.in @@ -608,6 +608,11 @@ my %require_file_found = (); # 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. ## ## --------------------------------- ## @@ -746,6 +751,8 @@ sub initialize_per_input () %require_file_found = (); %subobjvar = (); + + %appendvar = (); } @@ -5590,6 +5597,18 @@ sub conditional_ambiguous_p ($$) 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) { @@ -5649,7 +5668,9 @@ sub macro_define ($$$$$$) $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}) @@ -5664,6 +5685,63 @@ sub macro_define ($$$$$$) } $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 diff --git a/automake.texi b/automake.texi index 837ed19..0781af3 100644 --- a/automake.texi +++ b/automake.texi @@ -238,10 +238,6 @@ supported. This operator appends its right hand argument to the macro 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? @@ -2015,17 +2011,17 @@ When using conditionals like this you don't need to use the @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 @@ -4460,30 +4456,6 @@ endif !DEBUG @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 diff --git a/tests/Makefile.am b/tests/Makefile.am index 54685aa..2cf6d14 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ ## 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 \ @@ -81,6 +81,7 @@ cond17.test \ cond18.test \ cond19.test \ cond20.test \ +cond21.test \ condd.test \ condincl.test \ condincl2.test \ diff --git a/tests/Makefile.in b/tests/Makefile.in index 612defc..f15f02e 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -84,7 +84,7 @@ sharedstatedir = @sharedstatedir@ 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 \ @@ -165,6 +165,7 @@ cond17.test \ cond18.test \ cond19.test \ cond20.test \ +cond21.test \ condd.test \ condincl.test \ condincl2.test \ diff --git a/tests/cond21.test b/tests/cond21.test new file mode 100755 index 0000000..05b07c7 --- /dev/null +++ b/tests/cond21.test @@ -0,0 +1,65 @@ +#! /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' diff --git a/tests/condd.test b/tests/condd.test index 7e828a1..8918de5 100755 --- a/tests/condd.test +++ b/tests/condd.test @@ -5,6 +5,7 @@ . $srcdir/defs || exit 1 cat >> configure.in << 'END' +AC_PROG_CC AM_CONDITIONAL(COND1, true) END @@ -13,7 +14,18 @@ SUBDIRS = foo 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 -- 2.7.4