automake-patches
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]