From 9cc6f8946be0b773e5afe00aceb3370fc366ed66 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Wed, 24 Apr 2002 07:35:56 +0000 Subject: [PATCH] Fix PR automake/315: * automake.in (subobjname): Rewrite to generate variable name unique for each content. (%substnums): Remove. (%subobjvar): New hash. (initialize_per_input): Clear %subobjvar. (define_objects_from_sources): Return the name of the variable defined, in addition to the linker. Call subobjname only once the content of the variable to define is known. (handle_source_transform): Adjust call to define_objects_from_sources. * tests/specflags8.test: Mention PR 315. * tests/subobjname.test: New file. * tests/Makefile.am (XFAIL_TESTS): Remove specflags8.test. (TESTS): Add subobjname.test. --- ChangeLog | 17 +++++++ THANKS | 1 + automake.in | 111 +++++++++++++++++++++++------------------- tests/Makefile.am | 3 +- tests/Makefile.in | 3 +- tests/specflags8.test | 1 + tests/subobjname.test | 58 ++++++++++++++++++++++ 7 files changed, 143 insertions(+), 51 deletions(-) create mode 100755 tests/subobjname.test diff --git a/ChangeLog b/ChangeLog index 2ba160f7..a82fe451 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2002-04-24 Alexandre Duret-Lutz + + Fix PR automake/315: + * automake.in (subobjname): Rewrite to generate variable name + unique for each content. + (%substnums): Remove. + (%subobjvar): New hash. + (initialize_per_input): Clear %subobjvar. + (define_objects_from_sources): Return the name of the variable + defined, in addition to the linker. Call subobjname only once + the content of the variable to define is known. + (handle_source_transform): Adjust call to define_objects_from_sources. + * tests/specflags8.test: Mention PR 315. + * tests/subobjname.test: New file. + * tests/Makefile.am (XFAIL_TESTS): Remove specflags8.test. + (TESTS): Add subobjname.test. + 2002-04-23 Alexandre Duret-Lutz * m4/depout.m4 (_AM_OUTPUT_DEPENDENCY_COMMANDS): Grep diff --git a/THANKS b/THANKS index 49edf618..c5032c7f 100644 --- a/THANKS +++ b/THANKS @@ -58,6 +58,7 @@ Gord Matzigkeit gord@gnu.ai.mit.edu Gordon Sadler gbsadler1@lcisp.com Greg A. Woods woods@most.weird.com Guido Draheim guidod@gmx.de +Gustavo Carneiro gjc@inescporto.pt H.J. Lu hjl@lucon.org Harlan Stenn Harlan.Stenn@pfcs.com Henrik Frystyk Nielsen frystyk@w3.org diff --git a/automake.in b/automake.in index d8a73e31..930d582b 100755 --- a/automake.in +++ b/automake.in @@ -599,16 +599,14 @@ my @substfroms; # force. my @substtos; -# Associates a variable name, together with a list of substitutions to be -# performed on it, with a number. Used to provide unique names for generated -# variables. -my %substnums = (); - # If a file name appears as a key in this hash, then it has already # been checked for. This variable is local to the "require file" # functions. my %require_file_found = (); +# This keeps track of all variables defined by subobjname. +# The key is the variable _content_, and the value is the variable name. +my %subobjvar = (); ## --------------------------------- ## ## Forward subroutine declarations. ## @@ -746,6 +744,8 @@ sub initialize_per_input () %libtool_clean_directories = ('.' => 1); %require_file_found = (); + + %subobjvar = (); } @@ -2135,15 +2135,18 @@ sub handle_single_transform_list ($$$$@) # # Arguments are: # $VAR is the name of the _SOURCES variable -# $OBJVAR is the name of the _OBJECTS +# $OBJVAR is the name of the _OBJECTS variable if known (otherwise +# it will be generated and returned). # $NODEFINE is a boolean: if true, $OBJVAR will not be defined (but -# work done to determine the linker will be). +# work done to determine the linker will be). # $ONE_FILE is the canonical (transformed) name of object to build # $OBJ is the object extension (ie either `.o' or `.lo'). # $PARENT is the variable in which $VAR is used, or $VAR if not applicable. # $TOPPARENT is the _SOURCES variable being processed. # -# Result is a boolean, true if a linker is needed to deal with the objects. +# Result is a pair ($LINKER, $OBJVAR): +# $LINKER is a boolean, true if a linker is needed to deal with the objects, +# $OBJVAR is the name of the variable defined to hold the objects. # # %linkers_used, %vars_scanned, @substfroms and @substtos should be cleared # before use: @@ -2191,12 +2194,12 @@ sub define_objects_from_sources ($$$$$$$) push @substfroms, $from; push @substtos, $to; - my $subobjvar = subobjname ($subvar); - push (@result, '$('. $subobjvar . ')'); + my ($temp, $varname) + = define_objects_from_sources ($subvar, undef, + $nodefine, $one_file, + $obj, $var, $topparent); - my $temp = define_objects_from_sources ($subvar, $subobjvar, - $nodefine, $one_file, - $obj, $var, $topparent); + push (@result, '$('. $varname . ')'); $needlinker ||= $temp; pop @substfroms; @@ -2219,53 +2222,62 @@ sub define_objects_from_sources ($$$$$$$) } } + # Find an name for the variable, unless imposed. + $objvar = subobjname (@result) unless defined $objvar; # Define _OBJECTS conditionally. define_pretty_variable ($objvar, $cond, (@result)) - unless $nodefine; + unless $nodefine; } delete $vars_scanned{$var}; - return $needlinker; + return ($needlinker, $objvar); } -# $OBJNAME -# subobjname ($VARNAME) +# $VARNAME +# subobjname (@OBJECTS) # --------------------- -# Return a name for an object variable. +# Return a name for an object variable that holds @OBJECTS. # -# Arguments are: -# $VARNAME is the name of the variable the object variable is being -# generated from. +# If we already have an object variable containing @OBJECTS, reuse it. +# This way, we avoid combinatorial explosion of the generated +# variables. Especially, in a Makefile such as: # -# This function also looks at @substfroms and @substtos to determine any -# substitutions to be performed on the object variable. +# | if FOO1 +# | A1=1 +# | endif +# | +# | if FOO2 +# | A2=2 +# | endif +# | +# | ... +# | +# | if FOON +# | AN=N +# | endif +# | +# | B=$(A1) $(A2) ... $(AN) +# | +# | c_SOURCES=$(B) +# | d_SOURCES=$(B) # -# The name returned is unique for the combination of $varname and -# substitutions to be performed. -sub subobjname ($) +# The generated c_OBJECTS and d_OBJECTS will share the same variable +# definitions. +# +# This setup can be the case of a testsuite containing lots (>100) of +# small C programs, all testing the same set of source files. +my $subobjnamenum = 0; +sub subobjname (@) { - my ($varname) = @_; - my $key = $varname; - my $substnum=$#substfroms; - while ($substnum >= 0) - { - if (defined $substfroms[$substnum] && - ($substfroms[$substnum] || $substtos[$substnum])) - { - $key .= ":" . $substfroms[$substnum] . "=" . $substtos[$substnum]; - } - $substnum -= 1; - } + my $key = "@_"; - my $num = $substnums{$key}; - if (! $num) - { - $num = keys(%substnums) + 1; - $substnums{$key} = $num; - } + return $subobjvar{$key} if exists $subobjvar{$key}; - return "am__objects_$num"; + ++$subobjnamenum; + my $name = "am__objects_${subobjnamenum}"; + $subobjvar{$key} = $name; + return $name; } @@ -2318,10 +2330,11 @@ sub handle_source_transform @substfroms = (); @substtos = (); %vars_scanned = (); - my $temp = define_objects_from_sources ($var, - $xpfx . $one_file . '_OBJECTS', - $prefix =~ /EXTRA_/, - $one_file, $obj, $var, $var); + my ($temp, $objvar) = + define_objects_from_sources ($var, + $xpfx . $one_file . '_OBJECTS', + $prefix =~ /EXTRA_/, + $one_file, $obj, $var, $var); $needlinker ||= $temp; } if ($needlinker) diff --git a/tests/Makefile.am b/tests/Makefile.am index e9a8ba4d..4f8c4b8d 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 specflags8.test +XFAIL_TESTS = condd.test subdir5.test auxdir2.test cond17.test TESTS = \ acinclude.test \ @@ -320,6 +320,7 @@ subobj6.test \ subobj7.test \ subobj8.test \ subobj9.test \ +subobjname.test \ subst.test \ substref.test \ substtarg.test \ diff --git a/tests/Makefile.in b/tests/Makefile.in index 280033f1..51062fdc 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 specflags8.test +XFAIL_TESTS = condd.test subdir5.test auxdir2.test cond17.test TESTS = \ acinclude.test \ @@ -404,6 +404,7 @@ subobj6.test \ subobj7.test \ subobj8.test \ subobj9.test \ +subobjname.test \ subst.test \ substref.test \ substtarg.test \ diff --git a/tests/specflags8.test b/tests/specflags8.test index e3d2dd92..64016675 100755 --- a/tests/specflags8.test +++ b/tests/specflags8.test @@ -2,6 +2,7 @@ # Like the ctags/etags example from the manual, # with one extra indirection in the sources. +# PR 315. . $srcdir/defs || exit 1 diff --git a/tests/subobjname.test b/tests/subobjname.test new file mode 100755 index 00000000..1f94a94a --- /dev/null +++ b/tests/subobjname.test @@ -0,0 +1,58 @@ +#! /bin/sh + +# Make sure we reuse variables whenever possible, to limit +# combinational explosion. (This test is named after the &subobjname +# sub in Automake). + +. $srcdir/defs || exit 1 + +set -e + +cat >> configure.in << 'END' +AC_PROG_CC +AM_CONDITIONAL([FOO1], [some test]) +AM_CONDITIONAL([FOO2], [some test]) +AM_CONDITIONAL([FOO3], [some test]) +AC_OUTPUT +END + +cat > Makefile.am << 'END' +noinst_PROGRAMS = c d + +if FOO1 +A1=a1.c +endif + +if FOO2 +A2=a2.c +endif + +if FOO3 +A3=a3.c +endif + +B=$(A1) $(A2) $(A3) + +c_SOURCES=$(B) +d_SOURCES=$(B) +END + +$ACLOCAL +$AUTOMAKE -a + +# Sanity check: make sure am_c_OBJECTS and am_d_OBJECTS are used +# in the Makefile. (This is an internal detail, so better make +# sure we update this test if the naming changes in the future.) +grep '^am_c_OBJECTS = ' Makefile.in +grep '^am_d_OBJECTS = ' Makefile.in + +# Now the actual test. Are both values equal? +cobj=`sed -n '/^am_c_OBJECTS = / { + s/.* = \(.*\)$/\1/ + p + }' Makefile.in` +dobj=`sed -n '/^am_d_OBJECTS = / { + s/^.* = \(.*\)$/\1/ + p + }' Makefile.in` +test "$cobj" = "$dobj" -- 2.43.5