automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FYI: fix for PR/352 & combinatorial explosion in append_exeext


From: Alexandre Duret-Lutz
Subject: FYI: fix for PR/352 & combinatorial explosion in append_exeext
Date: Wed, 29 Jan 2003 00:24:17 +0100
User-agent: Gnus/5.090008 (Oort Gnus v0.08) Emacs/21.2 (i386-pc-linux-gnu)

I'm installing the following patch on HEAD.

Fixing PR/352 (cond30.test) also cures the slowness
(combinatorial explosion) of append_exeext that many people
noticed while doing conditional definitions of bin_PROGRAMS
(such as in cond29.test.).

Also while I adjusted exeext.test to use ./configure and make
instead of just grepping the Makefile.in, I found out that
`bin_PROGRAMS = maude$(EXEEXT)' never worked: Automake define
`maude__EXEEXT_SOURCES = maude$(EXEEXT).c' which causes problem
with dependencies (as with all filenames containing variables,
see PR/325).  This patch fixes this too, although I saw no point
in mentioning this in NEWS.


2003-01-28  Alexandre Duret-Lutz  <address@hidden>

        Fix for PR automake/352:
        * automake.in (transform_variable_recursively): If the destination
        and the source variables are the same, delete the source variable
        before defining the destination variable.
        (handle_programs): Strip any $(EXEEXT) suffix from $one_file,
        or this will confuse handle_source_transform.
        (append_exeext): Rewrite using transform_variable_recursively.
        * tests/cond29.test, tests/cond30.test: New files.
        * tests/exeext.test: Run ./configure and make, this uncovered
        the above handle_programs issue.
        * tests/Makefile.am (TESTS): Add cond29.test and cond20.test.

Index: NEWS
===================================================================
RCS file: /cvs/automake/automake/NEWS,v
retrieving revision 1.201
diff -u -r1.201 NEWS
--- NEWS        21 Jan 2003 18:02:33 -0000      1.201
+++ NEWS        28 Jan 2003 23:12:01 -0000
@@ -1,18 +1,52 @@
 New in 1.7a:
+* The NEWS file is more verbose.
+
+* Defining programs conditionally using Automake conditionals
+  no longer leads to a combinatorial explosion.  The following
+  construct used to be troublesome when used with dozens
+  of conditions.
+
+    bin_PROGRAMS = a
+    if COND1
+      bin_PROGRAMS += a1
+    endif
+    if COND2
+      bin_PROGRAMS += a2
+    endif
+    if COND3
+      bin_PROGRAMS += a3
+    endif
+    ...
+
+* It is now allowed to define bin_PROGRAMS (or any *_PROGRAMS variable)
+  in several conditions.  As in
+
+    if COND1
+      bin_PROGRAMS = a1
+    endif
+    if COND2
+      bin_PROGRAMS = a2
+    endif
+
+* install-sh now understands --version and --help.
+
 * Cleanup the definitions of $(distdir) and $(top_distdir).
   $(top_distdir) now points to the root of the distribution directory
   created during `make dist', as it did in Automake 1.4, not to the
   root of the build tree as it did in intervening versions.
   Furthermore these two variables are now only defined in the top
   level Makefile, and passed to sub-directories when running `make dist'.
+
 * elisp sources are compiled all at once, instead of one by one.
-  This allows interdependencies and speed up compilation.
+  This allows interdependencies and speeds up compilation.
+
 * AM_PROG_CC_STDC is now empty.  The content of this macro was
   merged in AC_PROG_CC.  If your code uses $am_cv_prog_cc_stdc,
   you should adjust it to use $ac_cv_prog_cc_stdc instead.
   (This renaming should be safe, even if you have to support several,
   versions of Automake, because AC_PROG_CC defines this variable since
   Autoconf 2.54.)
+
 
 New in 1.7:
 * Autoconf 2.54 is required.
Index: automake.in
===================================================================
RCS file: /cvs/automake/automake/automake.in,v
retrieving revision 1.1420
diff -u -r1.1420 automake.in
--- automake.in 28 Jan 2003 20:59:59 -0000      1.1420
+++ automake.in 28 Jan 2003 23:12:06 -0000
@@ -2756,6 +2756,11 @@
        # Define the variable if required.
        unless ($nodefine)
         {
+          # If the new variable is the source variable, we assume
+          # we are trying to override a user variable.  Delete
+          # the old variable first.
+          macro_delete ($varname) if $varname eq $var;
+          # Define for all conditions.
           foreach my $pair (@$allresults)
             {
               my ($cond, @result) = @$pair;
@@ -3217,6 +3222,10 @@
       $where->push_context ("while processing program `$one_file'");
       $where->set (INTERNAL->get);
 
+      # Strip any $(EXEEXT) suffix the user might have added, or this
+      # will confuse &handle_source_transform.  We'll add $(EXEEXT) back
+      # later anyway.
+      $one_file =~ s/\$\(EXEEXT\)$//;
       my $linker = &handle_source_transform ($xname, $one_file, $obj, $where);
 
       my $xt = '';
@@ -3267,18 +3276,13 @@
       # make sure this directory will exist.
       my $dirstamp = require_build_directory_maybe ($one_file);
 
-      # Don't add $(EXEEXT) if user already did.
-      my $extension = ($one_file !~ /\$\(EXEEXT\)$/
-                      ? "\$(EXEEXT)"
-                      : '');
-
       $output_rules .= &file_contents ('program',
                                       $where,
                                       PROGRAM  => $one_file,
                                       XPROGRAM => $xname,
                                       XLINK    => $xlink,
                                       DIRSTAMP => $dirstamp,
-                                      EXEEXT   => $extension);
+                                      EXEEXT   => '$(EXEEXT)');
 
       if ($seen_libobjs || $seen_global_libobjs)
        {
@@ -8175,46 +8179,15 @@
   prog_error "append_exeext ($macro)"
     unless $macro =~ /_PROGRAMS$/;
 
-  # FIXME: we should use traverse_variable_recursively to fix PR/352.
-  my @conds = variable_conditions_recursive ($macro)->conds;
-
-  my @condvals;
-  foreach my $cond (@conds)
-    {
-      my @one_binlist = ();
-      my @condval = variable_value_as_list_recursive ($macro, $cond);
-      foreach my $rcurs (@condval)
-       {
-         # Skip autoconf substs.  Also skip if the user
-         # already applied $(EXEEXT).
-         if ($rcurs =~ /address@hidden@$/ || $rcurs =~ /\$\(EXEEXT\)$/)
-           {
-             push (@one_binlist, $rcurs);
-           }
-         else
-           {
-             push (@one_binlist, $rcurs . '$(EXEEXT)');
-           }
-       }
-
-      push (@condvals, $cond);
-      push (@condvals, "@one_binlist");
-    }
-
-  # FIXME: Currently it's a bit hard to chose a condition becose the
-  # set of input condition is different from the set of ouput
-  # conditions.  See also PR/352.   So we just pick the first one.
-  my $cond = variable_conditions ($macro)->one_cond;
-  my $where = $var_location{$macro}{$cond};
-
-  macro_delete ($macro);
-  while (@condvals)
-    {
-      my $cond = shift (@condvals);
-      my @val = split (' ', shift (@condvals));
-      define_pretty_variable ($macro, $cond, $where, @val);
-    }
- }
+  transform_variable_recursively
+    ($macro, $macro, 'am__EXEEXT', 0, INTERNAL,
+     sub {
+       my ($subvar, $val, @cond_stack) = @_;
+       # Append $(EXEEXT) unless the user did it already.
+       $val .= '$(EXEEXT)' unless $val =~ /\$\(EXEEXT\)$/;
+       return $val;
+     });
+}
 
 
 # @PREFIX
Index: tests/Makefile.am
===================================================================
RCS file: /cvs/automake/automake/tests/Makefile.am,v
retrieving revision 1.464
diff -u -r1.464 Makefile.am
--- tests/Makefile.am   13 Jan 2003 19:17:53 -0000      1.464
+++ tests/Makefile.am   28 Jan 2003 23:12:06 -0000
@@ -98,6 +98,8 @@
 cond26.test \
 cond27.test \
 cond28.test \
+cond29.test \
+cond30.test \
 condd.test \
 condinc.test \
 condinc2.test \
Index: tests/cond29.test
===================================================================
RCS file: tests/cond29.test
diff -N tests/cond29.test
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ tests/cond29.test   28 Jan 2003 23:12:06 -0000
@@ -0,0 +1,47 @@
+#!/bin/sh
+# Copyright (C) 2003  Free Software Foundation, Inc.
+#
+# This file is part of GNU Automake.
+#
+# GNU Automake is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Automake is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Automake; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# Check that many conditions do not lead to combinatorial explosion.
+# (This is related to PR/352.)
+#
+# On this test, Automake 1.7.x would compute all 2**22 = 4194304 possible
+# combinations of conditionals, eating all memory, swap, or cpu time it can
+# found.  Although this test wont print `FAIL' if it fails, it will take
+# long enough so it can't go unnoticed.
+
+. ./defs
+
+set -e
+
+echo AC_PROG_CC >>configure.in
+
+echo 'bin_PROGRAMS = a' > Makefile.am
+
+for i in 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22; do
+cat >>Makefile.am <<EOF
+if C$i
+bin_PROGRAMS += a$i
+endif C$i
+EOF
+echo "AM_CONDITIONAL([C$i], [:])" >>configure.in
+done
+
+$ACLOCAL
+$AUTOMAKE
Index: tests/cond30.test
===================================================================
RCS file: tests/cond30.test
diff -N tests/cond30.test
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ tests/cond30.test   28 Jan 2003 23:12:06 -0000
@@ -0,0 +1,58 @@
+#!/bin/sh
+# Copyright (C) 2003  Free Software Foundation, Inc.
+#
+# This file is part of GNU Automake.
+#
+# GNU Automake is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# GNU Automake is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Automake; see the file COPYING.  If not, write to
+# the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# For PR/352: make sure we support bin_PROGRAMS being defined conditionally.
+
+. ./defs
+
+set -e
+
+cat >>configure.in <<'EOF'
+AC_PROG_CC
+AM_CONDITIONAL(C1, [test -z "$two"])
+AM_CONDITIONAL(C2, [test -n "$two"])
+AC_OUTPUT
+EOF
+
+cat >>Makefile.am <<'EOF'
+if C1
+bin_PROGRAMS = a
+endif
+if C2
+bin_PROGRAMS = b
+endif
+
+print:
+       @echo 'BEG: $(bin_PROGRAMS) :END'
+EOF
+
+$ACLOCAL
+$AUTOCONF
+$AUTOMAKE
+
+./configure
+EXEEXT=.foo $MAKE -e print > stdout
+cat stdout
+grep 'BEG: a.foo :END' stdout
+
+./configure two=yes
+EXEEXT=.foo $MAKE -e print > stdout
+cat stdout
+grep 'BEG: b.foo :END' stdout
Index: tests/exeext.test
===================================================================
RCS file: /cvs/automake/automake/tests/exeext.test,v
retrieving revision 1.3
diff -u -r1.3 exeext.test
--- tests/exeext.test   19 Jan 2003 15:19:26 -0000      1.3
+++ tests/exeext.test   28 Jan 2003 23:12:06 -0000
@@ -21,13 +21,15 @@
 # Test to make sure `.' in an exe name doesn't fool us.
 # Report from Robert Collins.
 # Also make sure we rewrite conditionals variables.
+# Also check for PR/352.
 
 . ./defs || exit 1
 
 cat >> configure.in << 'END'
 AC_PROG_CC
-AM_CONDITIONAL([WANT_MT], [:])
-AM_CONDITIONAL([WANT_RMT], [:])
+AM_CONDITIONAL([WANT_MT], [test -z "$revert"])
+AM_CONDITIONAL([WANT_RMT], [test -z "$revert"])
+AC_OUTPUT
 END
 
 cat > Makefile.am << 'END'
@@ -44,24 +46,42 @@
 if WANT_RMT
   libexec_PROGRAMS = rmt
 endif
+
+print:
+       @echo 1BEG: $(bin_PROGRAMS) :END1
+       @echo 2BEG: $(sbin_PROGRAMS) :END2
+       @echo 3BEG: $(check_PROGRAMS) :END3
+       @echo 4BEG: $(libexec_PROGRAMS) :END4
 END
 
 set -e
 
 $ACLOCAL
+$AUTOCONF
 $AUTOMAKE
 
 grep '^maude$(EXEEXT):' Makefile.in
-grep 'bin_PROGRAMS =.*maude$(EXEEXT)' Makefile.in
-
 grep '^maude\.static$(EXEEXT):' Makefile.in
-grep 'sbin_PROGRAMS =.*maude\.static$(EXEEXT)' Makefile.in
-
 grep '^maude3$(EXEEXT):' Makefile.in
-grep 'check_PROGRAMS =.*maude3$(EXEEXT)' Makefile.in
-
 grep '^mt$(EXEEXT):' Makefile.in
-grep '@address@hidden =.* mt$(EXEEXT)' Makefile.in
-
 grep '^rmt$(EXEEXT):' Makefile.in
-grep '@address@hidden =.*rmt$(EXEEXT)' Makefile.in
+
+./configure
+
+EXEEXT=.foo $MAKE -e print > stdout
+cat stdout
+
+grep '1BEG: maude.foo mt.foo :END1' stdout
+grep '2BEG: maude.static.foo :END2' stdout
+grep '3BEG: maude3.foo :END3' stdout
+grep '4BEG: rmt.foo :END4' stdout
+
+./configure revert=yes
+
+EXEEXT=.foo $MAKE -e print > stdout
+cat stdout
+
+grep '1BEG: maude.foo :END1' stdout
+grep '2BEG: maude.static.foo :END2' stdout
+grep '3BEG: maude3.foo :END3' stdout
+grep '4BEG: :END4' stdout


-- 
Alexandre Duret-Lutz





reply via email to

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