[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: possible fix for PR/315
From: |
Alexandre Duret-Lutz |
Subject: |
Re: possible fix for PR/315 |
Date: |
23 Apr 2002 21:20:08 +0200 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 |
Here is the patch that change subobjname to generate object
variable names which are unique for each *content*. So this
should solve PR/315 while still improving variable reuse (BTW,
this adds Richard's previous example as subobjname.test).
I'm going to commit this tomorrow unless told otherwise.
Index: ChangeLog
===================================================================
RCS file: /cvs/automake/automake/ChangeLog,v
retrieving revision 1.1825
diff -u -r1.1825 ChangeLog
--- ChangeLog 23 Apr 2002 16:59:56 -0000 1.1825
+++ ChangeLog 23 Apr 2002 19:11:35 -0000
@@ -1,5 +1,22 @@
2002-04-23 Alexandre Duret-Lutz <address@hidden>
+ 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 <address@hidden>
+
* m4/depout.m4 (_AM_OUTPUT_DEPENDENCY_COMMANDS): Grep
the whole file for 'generated by automake', not only the
first line. This accounts for post-processed Makefile.in's.
Index: THANKS
===================================================================
RCS file: /cvs/automake/automake/THANKS,v
retrieving revision 1.168
diff -u -r1.168 THANKS
--- THANKS 22 Apr 2002 18:39:45 -0000 1.168
+++ THANKS 23 Apr 2002 19:11:37 -0000
@@ -58,6 +58,7 @@
Gordon Sadler address@hidden
Greg A. Woods address@hidden
Guido Draheim address@hidden
+Gustavo Carneiro address@hidden
H.J. Lu address@hidden
Harlan Stenn address@hidden
Henrik Frystyk Nielsen address@hidden
Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1292
diff -u -r1.1292 automake.in
--- automake.in 19 Apr 2002 20:53:56 -0000 1.1292
+++ automake.in 23 Apr 2002 19:11:57 -0000
@@ -599,16 +599,14 @@
# 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 @@
%libtool_clean_directories = ('.' => 1);
%require_file_found = ();
+
+ %subobjvar = ();
}
@@ -2135,15 +2135,18 @@
#
# 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 @@
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 @@
}
}
+ # 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 ($)
-{
- 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 $num = $substnums{$key};
- if (! $num)
- {
- $num = keys(%substnums) + 1;
- $substnums{$key} = $num;
- }
-
- return "am__objects_$num";
+# 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 $key = "@_";
+
+ return $subobjvar{$key} if exists $subobjvar{$key};
+
+ ++$subobjnamenum;
+ my $name = "am__objects_${subobjnamenum}";
+ $subobjvar{$key} = $name;
+ return $name;
}
@@ -2318,10 +2330,11 @@
@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)
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/automake/automake/tests/Makefile.am,v
retrieving revision 1.391
diff -u -r1.391 Makefile.am
--- tests/Makefile.am 23 Apr 2002 16:59:57 -0000 1.391
+++ tests/Makefile.am 23 Apr 2002 19:11:59 -0000
@@ -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 @@
subobj7.test \
subobj8.test \
subobj9.test \
+subobjname.test \
subst.test \
substref.test \
substtarg.test \
Index: tests/Makefile.in
===================================================================
RCS file: /cvs/automake/automake/tests/Makefile.in,v
retrieving revision 1.507
diff -u -r1.507 Makefile.in
--- tests/Makefile.in 23 Apr 2002 16:59:57 -0000 1.507
+++ tests/Makefile.in 23 Apr 2002 19:12:00 -0000
@@ -84,7 +84,7 @@
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 @@
subobj7.test \
subobj8.test \
subobj9.test \
+subobjname.test \
subst.test \
substref.test \
substtarg.test \
Index: tests/specflags8.test
===================================================================
RCS file: /cvs/automake/automake/tests/specflags8.test,v
retrieving revision 1.2
diff -u -r1.2 specflags8.test
--- tests/specflags8.test 2 Apr 2002 16:20:15 -0000 1.2
+++ tests/specflags8.test 23 Apr 2002 19:12:00 -0000
@@ -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
Index: tests/subobjname.test
===================================================================
RCS file: tests/subobjname.test
diff -N tests/subobjname.test
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/subobjname.test 23 Apr 2002 19:12:00 -0000
@@ -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"
--
Alexandre Duret-Lutz