summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS20
-rw-r--r--THANKS1
-rw-r--r--bin/automake.in11
-rw-r--r--lib/Automake/Rule.pm109
-rw-r--r--t/list-of-tests.mk1
-rw-r--r--t/suffix-custom-pr14441.sh56
6 files changed, 133 insertions, 65 deletions
diff --git a/NEWS b/NEWS
index c867385d7..aba7a265e 100644
--- a/NEWS
+++ b/NEWS
@@ -217,7 +217,7 @@ New in 1.13.3:
* Documentation fixes:
- - The documentation no longer mistakenly report that the obsolete
+ - The documentation no longer mistakenly reports that the obsolete
'AM_MKDIR_PROG_P' macro and '$(mkdir_p)' make variable are going
to be removed in Automake 2.0.
@@ -226,11 +226,21 @@ New in 1.13.3:
- Byte-compilation of Emacs lisp files could fail spuriously on Solaris,
when /bin/ksh or /usr/xpg4/bin/sh were used as shell.
+ - The same user-defined suffix being transformed into different
+ Automake-known suffixes in different Makefiles could confuse automake
+ and make it generate inconsistent Makefiles (automake bug#14441).
+ For example, if 'Makefile.am' contained a ".ext.cc:" suffix rule, and
+ 'sub/Makefile.am' contained a ".ext.c:" suffix rule, automake would
+ have mistakenly put into 'Makefile.in' rules to compile *.c files
+ into object files, and into 'sub/Makefile.in' rules to compile *.cc
+ files into object files --- rather than the other way around.
+ This is now fixed.
+
* Testsuite work:
- The test cases no longer have the executable bit set. This should
make it clear that they are not meant to be run directly; as
- explained in t/README, the can only be run through the custom
+ explained in t/README, they can only be run through the custom
'runtest' script, or by a "make check" invocation.
- The testsuite has seen the introduction of a new helper function
@@ -254,14 +264,14 @@ New in 1.13.2:
- The long-deprecated but still supported two-arguments invocation form
of AM_INIT_AUTOMAKE is documented once again. This seems the sanest
- thing to do, given that support for such an usage might need to remain
- in place for a unspecified amount of time in order to cater for people
+ thing to do, given that support for such usage might need to remain
+ in place for an unspecified amount of time in order to cater to people
who want to define the version number for their package dynamically at
configure runtime (unfortunately, Autoconf does not yet support this
scenario, so we cannot delegate the work to it).
- The serial testsuite harness is no longer reported as "deprecated",
- but as "discouraged". We have no plan to remove it, not to make its
+ but as "discouraged". We have no plan to remove it, nor to make its
use cause runtime warnings.
- The parallel testsuite is no longer reported as "experimental"; it
diff --git a/THANKS b/THANKS
index 853c37987..07b8e9f04 100644
--- a/THANKS
+++ b/THANKS
@@ -119,6 +119,7 @@ Esben Haabendal Soerensen bart@kom.aau.dk
Ezra Peisach epeisach@MED-XTAL.BU.EDU
Fabian Alenius fabian.alenius@gmail.com
Federico Simoncelli fsimonce@redhat.com
+Felix Salfelder felix@salfelder.org
Flavien Astraud flav42@yahoo.fr
Florian Briegel briegel@zone42.de
Francesco Salvestrini salvestrini@gmail.com
diff --git a/bin/automake.in b/bin/automake.in
index 8f3fb4878..24ff2a6d6 100644
--- a/bin/automake.in
+++ b/bin/automake.in
@@ -5861,7 +5861,7 @@ sub register_language
# Update the pattern of known extensions.
accept_extensions (@{$lang->extensions});
- # Update the $suffix_rule map.
+ # Update the suffix rules map.
foreach my $suffix (@{$lang->extensions})
{
foreach my $dest ($lang->output_extensions->($suffix))
@@ -5879,12 +5879,11 @@ sub derive_suffix
{
my ($source_ext, $obj) = @_;
- while (! $extension_map{$source_ext}
- && $source_ext ne $obj
- && exists $suffix_rules->{$source_ext}
- && exists $suffix_rules->{$source_ext}{$obj})
+ while (!$extension_map{$source_ext} && $source_ext ne $obj)
{
- $source_ext = $suffix_rules->{$source_ext}{$obj}[0];
+ my $new_source_ext = next_in_suffix_chain ($source_ext, $obj);
+ last if not defined $new_source_ext;
+ $source_ext = $new_source_ext;
}
return $source_ext;
diff --git a/lib/Automake/Rule.pm b/lib/Automake/Rule.pm
index 47f3a9ddc..ac4b71afd 100644
--- a/lib/Automake/Rule.pm
+++ b/lib/Automake/Rule.pm
@@ -30,7 +30,8 @@ require Exporter;
use vars '@ISA', '@EXPORT', '@EXPORT_OK';
@ISA = qw/Automake::Item Exporter/;
@EXPORT = qw (reset register_suffix_rule suffix_rules_count
- suffixes rules $suffix_rules $KNOWN_EXTENSIONS_PATTERN
+ next_in_suffix_chain
+ suffixes rules $KNOWN_EXTENSIONS_PATTERN
depend %dependencies %actions register_action
accept_extensions
reject_rule msg_rule msg_cond_rule err_rule err_cond_rule
@@ -98,12 +99,17 @@ non-object).
my $_SUFFIX_RULE_PATTERN =
'^(\.[a-zA-Z0-9_(){}$+@\-]+)(\.[a-zA-Z0-9_(){}$+@\-]+)' . "\$";
-# Suffixes found during a run.
-use vars '@_suffixes';
+my @_suffixes = ();
+my @_known_extensions_list = ();
+my %_rule_dict = ();
-# Same as $suffix_rules (declared below), but records only the
-# default rules supplied by the languages Automake supports.
-use vars '$_suffix_rules_default';
+# See comments in the implementation of the 'next_in_suffix_chain()'
+# variable for details.
+my %_suffix_rules;
+
+# Same as $suffix_rules, but records only the default rules
+# supplied by the languages Automake supports.
+my %_suffix_rules_builtin;
=item C<%dependencies>
@@ -126,36 +132,6 @@ only when keys exists in C<%dependencies>.
use vars '%actions';
-=item <$suffix_rules>
-
-This maps the source extension for all suffix rules seen to
-a C<hash> whose keys are the possible output extensions.
-
-Note that this is transitively closed by construction:
-if we have
- exists $suffix_rules{$ext1}{$ext2}
- && exists $suffix_rules{$ext2}{$ext3}
-then we also have
- exists $suffix_rules{$ext1}{$ext3}
-
-So it's easy to check whether C<.foo> can be transformed to
-C<.$(OBJEXT)> by checking whether
-C<$suffix_rules{'.foo'}{'.$(OBJEXT)'}> exists. This will work even if
-transforming C<.foo> to C<.$(OBJEXT)> involves a chain of several
-suffix rules.
-
-The value of C<$suffix_rules{$ext1}{$ext2}> is a pair
-C<[ $next_sfx, $dist ]> where C<$next_sfx> is target suffix
-for the next rule to use to reach C<$ext2>, and C<$dist> the
-distance to C<$ext2'>.
-
-The content of this variable should be updated via the
-C<register_suffix_rule> function.
-
-=cut
-
-use vars '$suffix_rules';
-
=item C<$KNOWN_EXTENSIONS_PATTERN>
Pattern that matches all know input extensions (i.e. extensions used
@@ -167,9 +143,8 @@ New extensions should be registered with C<accept_extensions>.
=cut
-use vars qw ($KNOWN_EXTENSIONS_PATTERN @_known_extensions_list);
+use vars qw ($KNOWN_EXTENSIONS_PATTERN);
$KNOWN_EXTENSIONS_PATTERN = "";
-@_known_extensions_list = ();
=back
@@ -278,7 +253,6 @@ rules defined so far.)
=cut
-use vars '%_rule_dict';
sub rules ()
{
return values %_rule_dict;
@@ -317,16 +291,7 @@ sub reset()
{
%_rule_dict = ();
@_suffixes = ();
- # The first time we initialize the variables,
- # we save the value of $suffix_rules.
- if (defined $_suffix_rules_default)
- {
- $suffix_rules = $_suffix_rules_default;
- }
- else
- {
- $_suffix_rules_default = $suffix_rules;
- }
+ %_suffix_rules = %_suffix_rules_builtin;
%dependencies =
(
@@ -384,18 +349,33 @@ sub reset()
%actions = ();
}
+=item C<next_in_suffix_chain ($ext1, $ext2)>
+
+Return the target suffix for the next rule to use to reach C<$ext2>
+from C<$ext1>, or C<undef> if no such rule exists.
+
+=cut
+
+sub next_in_suffix_chain ($$)
+{
+ my ($ext1, $ext2) = @_;
+ return undef unless (exists $_suffix_rules{$ext1} and
+ exists $_suffix_rules{$ext1}{$ext2});
+ return $_suffix_rules{$ext1}{$ext2}[0];
+}
+
=item C<register_suffix_rule ($where, $src, $dest)>
Register a suffix rule defined on C<$where> that transforms
files ending in C<$src> into files ending in C<$dest>.
-This upgrades the C<$suffix_rules> variables.
-
=cut
sub register_suffix_rule ($$$)
{
my ($where, $src, $dest) = @_;
+ my $suffix_rules = $where->{'position'} ? \%_suffix_rules
+ : \%_suffix_rules_builtin;
verb "Sources ending in $src become $dest";
push @_suffixes, $src, $dest;
@@ -411,8 +391,29 @@ sub register_suffix_rule ($$$)
# output suffix rules for '.o' or '.obj' ...
$dest = '.$(OBJEXT)' if ($dest eq '.o' || $dest eq '.obj');
- # Reading the comments near the declaration of $suffix_rules might
- # help to understand the update of $suffix_rules that follows ...
+ # ----------------------------------------------------------------------
+ # The $suffix_rules variable maps the source extension for all suffix
+ # rules seen to a hash whose keys are the possible output extensions.
+ #
+ # Note that this is transitively closed by construction:
+ # if we have
+ #
+ # exists $suffix_rules{$ext1}{$ext2}
+ # && exists $suffix_rules{$ext2}{$ext3}
+ #
+ # then we also have
+ #
+ # exists $suffix_rules{$ext1}{$ext3}
+ #
+ # So it's easy to check whether '.foo' can be transformed to
+ # '.$(OBJEXT)' by checking whether $suffix_rules{'.foo'}{'.$(OBJEXT)'}
+ # exists. This will work even if transforming '.foo' to '.$(OBJEXT)'
+ # involves a chain of several suffix rules.
+ #
+ # The value of $suffix_rules{$ext1}{$ext2} is a pair [$next_sfx, $dist]
+ # where $next_sfx is target suffix for the next rule to use to reach
+ # $ext2, and $dist the distance to $ext2.
+ # ----------------------------------------------------------------------
# Register $dest as a possible destination from $src.
# We might have the create the \hash.
@@ -473,7 +474,7 @@ F<Makefile> (excluding predefined suffix rules).
sub suffix_rules_count ()
{
- return (scalar keys %$suffix_rules) - (scalar keys %$_suffix_rules_default);
+ return (scalar keys %_suffix_rules) - (scalar keys %_suffix_rules_builtin);
}
=item C<@list = suffixes>
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index 7f77227dc..5525cfde5 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -1073,6 +1073,7 @@ t/suffix9.sh \
t/suffix10.tap \
t/suffix11.tap \
t/suffix-chain.tap \
+t/suffix-custom-pr14441.sh \
t/suffix-custom-subobj.sh \
t/suffix-custom-subobj-and-specflg.sh \
t/symlink.sh \
diff --git a/t/suffix-custom-pr14441.sh b/t/suffix-custom-pr14441.sh
new file mode 100644
index 000000000..508f2e067
--- /dev/null
+++ b/t/suffix-custom-pr14441.sh
@@ -0,0 +1,56 @@
+#! /bin/sh
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+#
+# This program 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.
+#
+# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Test for bug#14441: the same user-defined suffix being transformed into
+# different automake-known suffixes in different Makefiles was confusing
+# Automake.
+
+. test-init.sh
+
+cat >>configure.ac <<EOF
+AC_PROG_CC
+AC_PROG_CXX
+AC_CONFIG_FILES([sub/Makefile])
+EOF
+
+mkdir sub
+
+cat > Makefile.am <<'END'
+SUBDIRS = sub
+bin_PROGRAMS = one
+one_SOURCES = one.ext
+.ext.cc:
+ whatever
+END
+
+cat > sub/Makefile.am <<'END'
+bin_PROGRAMS = two
+two_SOURCES = two.ext
+.ext.c:
+ do something
+END
+
+$ACLOCAL
+$AUTOMAKE -a
+
+$FGREP '.c' Makefile.in sub/Makefile.in # For debugging.
+
+grep '^\.cc\.o:' Makefile.in
+LC_ALL=C $EGREP '\.c[^a-z]' Makefile.in && exit 1
+grep '^\.c\.o:' sub/Makefile.in
+$FGREP '.cc' sub/Makefile.in && exit 1
+
+: