]> git.ipfire.org Git - thirdparty/automake.git/commitdiff
Merge branch 'master' into ng/master
authorStefano Lattarini <stefano.lattarini@gmail.com>
Sat, 21 Apr 2012 08:42:27 +0000 (10:42 +0200)
committerStefano Lattarini <stefano.lattarini@gmail.com>
Sat, 21 Apr 2012 08:42:27 +0000 (10:42 +0200)
* master:
  refactor: processing of input makefile rules
  automake: refactor pre-processing of makefile fragments
  docs: remove obsolete references to Autoconf 2.13
  tests: fix spurious failure with non-ANSI terminals

Signed-off-by: Stefano Lattarini <stefano.lattarini@gmail.com>
1  2 
automake.in
doc/automake.texi
lib/Automake/Rule.pm
t/ax/tap-summary-aux.sh

diff --cc automake.in
Simple merge
Simple merge
index 43c395664205fb8d2c9ab210879546a4465de982,3f17daa599c4fd734984f6f554bb263dbe735279..f7bf5454d03e3547a87f61941c80ab997fdd96dd
@@@ -619,160 -599,213 +597,208 @@@ sub _rule_defn_with_exeext_awareness ($
               partial => 1);
          msg ('obsolete', $where, "target '$target' was defined here");
        }
-       # Don't 'return ()' now, as this might hide target clashes
-       # detected below.
      }
+     return $tdef;
+ }
  
-   # Diagnose target redefinitions.
-   if ($tdef)
+ sub _maybe_warn_about_duplicated_target ($$$$$$)
+ {
+   my ($target, $tdef, $source, $owner, $cond, $where) = @_;
+   my $oldowner  = $tdef->owner;
+   # Ok, it's the name target, but the name maybe different because
+   # 'foo$(EXEEXT)' and 'foo' have the same key in our table.
+   my $oldname = $tdef->name;
+   # Don't mention true conditions in diagnostics.
+   my $condmsg =
+     $cond == TRUE ? '' : (" in condition '" . $cond->human . "'");
+   if ($owner == RULE_USER)
      {
-       my $oldowner  = $tdef->owner;
-       # Ok, it's the name target, but the name maybe different because
-       # 'foo$(EXEEXT)' and 'foo' have the same key in our table.
-       my $oldname = $tdef->name;
+       if ($oldowner == RULE_USER)
+         {
+           # Ignore '%'-style pattern rules.  We'd need the
+           # dependencies to detect duplicates, and they are
+           # already diagnosed as unportable by -Wportability.
+           if ($target !~ /^[^%]*%[^%]*$/)
+             {
+               ## FIXME: Presently we can't diagnose duplicate user rules
+               ## because we don't distinguish rules with commands
+               ## from rules that only add dependencies.  E.g.,
+               ##   .PHONY: foo
+               ##   .PHONY: bar
+               ## is legitimate. (This is phony.test.)
+               # msg ('syntax', $where,
+               #      "redefinition of '$target'$condmsg ...", partial => 1);
+               # msg_cond_rule ('syntax', $cond, $target,
+               #                "... '$target' previously defined here");
+             }
+         }
+       else
+         {
+           # Since we parse the user Makefile.am before reading
+           # the Automake fragments, this condition should never happen.
+           prog_error ("user target '$target'$condmsg seen after Automake's"
+                       . " definition\nfrom " . $tdef->source);
+         }
+     }
+   else # $owner == RULE_AUTOMAKE
+     {
+       if ($oldowner == RULE_USER)
+         {
+           # -am targets listed in %dependencies support a -local
+           # variant.  If the user tries to override TARGET or
+           # TARGET-am for which there exists a -local variant,
+           # just tell the user to use it.
+           my $hint = 0;
+           my $noam = $target;
+           $noam =~ s/-am$//;
+           if (exists $dependencies{"$noam-am"})
+             {
+               $hint = "consider using $noam-local instead of $target";
+             }
+           msg_cond_rule ('override', $cond, $target,
+                          "user target '$target' defined here"
+                          . "$condmsg ...", partial => 1);
+           msg ('override', $where,
+                "... overrides Automake target '$oldname' defined here",
+                partial => $hint);
+           msg_cond_rule ('override', $cond, $target, $hint)
+             if $hint;
+         }
+       else # $oldowner == RULE_AUTOMAKE
+         {
+           # Automake should ignore redefinitions of its own
+           # rules if they came from the same file.  This makes
+           # it easier to process a Makefile fragment several times.
+           # However it's an error if the target is defined in many
+           # files.  E.g., the user might be using bin_PROGRAMS = ctags
+           # which clashes with our 'ctags' rule.
+           # (It would be more accurate if we had a way to compare
+           # the *content* of both rules.  Then $targets_source would
+           # be useless.)
+           my $oldsource = $tdef->source;
+           if (not ($source eq $oldsource && $target eq $oldname))
+             {
+                msg ('syntax',
+                     $where, "redefinition of '$target'$condmsg ...",
+                     partial => 1);
+                msg_cond_rule ('syntax', $cond, $target,
+                               "... '$oldname' previously defined here");
+             }
+         }
+     }
+ }
  
-       # Don't mention true conditions in diagnostics.
-       my $condmsg =
-       $cond == TRUE ? '' : " in condition '" . $cond->human . "'";
+ # Return the list of conditionals in which the rule was defined.  In case
+ # an ambiguous conditional definition is detected, return the empty list.
+ sub _conditionals_for_rule ($$$$)
+ {
+   my ($rule, $owner, $cond, $where) = @_;
+   my $target = $rule->name;
+   my @conds;
+   my ($message, $ambig_cond) = $rule->conditions->ambiguous_p ($target, $cond);
  
-       if ($owner == RULE_USER)
-       {
-         if ($oldowner == RULE_USER)
-           {
-             # Ignore '%'-style pattern rules.  We'd need the
-             # dependencies to detect duplicates.
-             if ($target !~ /^[^%]*%[^%]*$/)
-               {
-                 ## FIXME: Presently we can't diagnose duplicate user rules
-                 ## because we don't distinguish rules with commands
-                 ## from rules that only add dependencies.  E.g.,
-                 ##   .PHONY: foo
-                 ##   .PHONY: bar
-                 ## is legitimate. (This is phony.test.)
-                 # msg ('syntax', $where,
-                 #      "redefinition of '$target'$condmsg ...", partial => 1);
-                 # msg_cond_rule ('syntax', $cond, $target,
-                 #                "... '$target' previously defined here");
-               }
-             # Return so we don't redefine the rule in our tables,
-             # don't check for ambiguous condition, etc.  The rule
-             # will be output anyway because &read_am_file ignore the
-             # return code.
-             return ();
-           }
-         else
-           {
-             # Since we parse the user Makefile.am before reading
-             # the Automake fragments, this condition should never happen.
-             prog_error ("user target '$target'$condmsg seen after Automake's"
-                         . " definition\nfrom " . $tdef->source);
-           }
-       }
-       else # $owner == RULE_AUTOMAKE
-       {
-         if ($oldowner == RULE_USER)
-           {
-             # -am targets listed in %dependencies support a -local
-             # variant.  If the user tries to override TARGET or
-             # TARGET-am for which there exists a -local variant,
-             # just tell the user to use it.
-             my $hint = 0;
-             my $noam = $target;
-             $noam =~ s/-am$//;
-             if (exists $dependencies{"$noam-am"})
-               {
-                 $hint = "consider using $noam-local instead of $target";
-               }
+   return $cond if !$message; # No ambiguity.
  
-             msg_cond_rule ('override', $cond, $target,
-                            "user target '$target' defined here"
-                            . "$condmsg ...", partial => 1);
-             msg ('override', $where,
-                  "... overrides Automake target '$oldname' defined here",
-                  partial => $hint);
-             msg_cond_rule ('override', $cond, $target, $hint)
-               if $hint;
-             # Don't overwrite the user definition of TARGET.
-             return ();
-           }
-         else # $oldowner == RULE_AUTOMAKE
-           {
-             # Automake should ignore redefinitions of its own
-             # rules if they came from the same file.  This makes
-             # it easier to process a Makefile fragment several times.
-             # However it's an error if the target is defined in many
-             # files.  E.g., the user might be using bin_PROGRAMS = ctags
-             # which clashes with our 'ctags' rule.
-             # (It would be more accurate if we had a way to compare
-             # the *content* of both rules.  Then $targets_source would
-             # be useless.)
-             my $oldsource = $tdef->source;
-             return () if $source eq $oldsource && $target eq $oldname;
-             msg ('syntax', $where, "redefinition of '$target'$condmsg ...",
-                  partial => 1);
-             msg_cond_rule ('syntax', $cond, $target,
-                            "... '$oldname' previously defined here");
-             return ();
-           }
-       }
-       # Never reached.
-       prog_error ("unreachable place reached");
+   if ($owner == RULE_USER)
+     {
+       # For user rules, just diagnose the ambiguity.
+       msg 'syntax', $where, "$message ...", partial => 1;
+       msg_cond_rule ('syntax', $ambig_cond, $target,
+                      "... '$target' previously defined here");
+       return ();
      }
  
-   # Conditions for which the rule should be defined.
-   my @conds = $cond;
+   # FIXME: for Automake rules, we can't diagnose ambiguities yet.
+   # The point is that Automake doesn't propagate conditions
+   # everywhere.  For instance &handle_PROGRAMS doesn't care if
+   # bin_PROGRAMS was defined conditionally or not.
+   # On the following input
+   #   if COND1
+   #   foo:
+   #           ...
+   #   else
+   #   bin_PROGRAMS = foo
+   #   endif
+   # &handle_PROGRAMS will attempt to define a 'foo:' rule
+   # in condition TRUE (which conflicts with COND1).  Fixing
+   # this in &handle_PROGRAMS and siblings seems hard: you'd
+   # have to explain &file_contents what to do with a
+   # condition.  So for now we do our best *here*.  If 'foo:'
+   # was already defined in condition COND1 and we want to define
+   # it in condition TRUE, then define it only in condition !COND1.
+   # (See cond14.test and cond15.test for some test cases.)
+   @conds = $rule->not_always_defined_in_cond ($cond)->conds;
+   # No conditions left to define the rule.
+   # Warn, because our workaround is meaningless in this case.
+   if (scalar @conds == 0)
+     {
+       msg 'syntax', $where, "$message ...", partial => 1;
+       msg_cond_rule ('syntax', $ambig_cond, $target,
+                      "... '$target' previously defined here");
+       return ();
+     }
+   return @conds;
+ }
  
-   # Check ambiguous conditional definitions.
-   my $rule = _crule $target;
-   my ($message, $ambig_cond) = $rule->conditions->ambiguous_p ($target, $cond);
-   if ($message)                       # We have an ambiguity.
+ =item C<@conds = define ($rulename, $source, $owner, $cond, $where)>
+ Define a new rule.  C<$rulename> is the list of targets.  C<$source>
+ is the filename the rule comes from.  C<$owner> is the owner of the
+ rule (C<RULE_AUTOMAKE> or C<RULE_USER>).  C<$cond> is the
+ C<Automake::Condition> under which the rule is defined.  C<$where> is
+ the C<Automake::Location> where the rule is defined.
+ Returns a (possibly empty) list of C<Automake::Condition>s where the
+ rule's definition should be output.
+ =cut
+ sub define ($$$$$)
+ {
+   my ($target, $source, $owner, $cond, $where) = @_;
+   prog_error "$where is not a reference"
+     unless ref $where;
+   prog_error "$cond is not a reference"
+     unless ref $cond;
+   # Don't even think about defining a rule in condition FALSE.
+   return () if $cond == FALSE;
+   my $tdef = _rule_defn_with_exeext_awareness ($target, $cond, $where);
 -  # A GNU make-style pattern rule has a single "%" in the target name.
 -  msg ('portability', $where,
 -       "'%'-style pattern rules are a GNU make extension")
 -    if $target =~ /^[^%]*%[^%]*$/;
 -
+   # See whether this is a duplicated target declaration.
+   if ($tdef)
      {
-       if ($owner == RULE_USER)
-       {
-         # For user rules, just diagnose the ambiguity.
-         msg 'syntax', $where, "$message ...", partial => 1;
-         msg_cond_rule ('syntax', $ambig_cond, $target,
-                        "... '$target' previously defined here");
-         return ();
-       }
-       else
-       {
-         # FIXME: for Automake rules, we can't diagnose ambiguities yet.
-         # The point is that Automake doesn't propagate conditions
-         # everywhere.  For instance &handle_PROGRAMS doesn't care if
-         # bin_PROGRAMS was defined conditionally or not.
-         # On the following input
-         #   if COND1
-         #   foo:
-         #           ...
-         #   else
-         #   bin_PROGRAMS = foo
-         #   endif
-         # &handle_PROGRAMS will attempt to define a 'foo:' rule
-         # in condition TRUE (which conflicts with COND1).  Fixing
-         # this in &handle_PROGRAMS and siblings seems hard: you'd
-         # have to explain &file_contents what to do with a
-         # condition.  So for now we do our best *here*.  If 'foo:'
-         # was already defined in condition COND1 and we want to define
-         # it in condition TRUE, then define it only in condition !COND1.
-         # (See cond14.test and cond15.test for some test cases.)
-         @conds = $rule->not_always_defined_in_cond ($cond)->conds;
-         # No conditions left to define the rule.
-         # Warn, because our workaround is meaningless in this case.
-         if (scalar @conds == 0)
-           {
-             msg 'syntax', $where, "$message ...", partial => 1;
-             msg_cond_rule ('syntax', $ambig_cond, $target,
-                            "... '$target' previously defined here");
-             return ();
-           }
-       }
+       # Diagnose invalid target redefinitions, if any.  Note that some
+       # target redefinitions are valid (e.g., for multiple-targets
+       # pattern rules).
+       _maybe_warn_about_duplicated_target ($target, $tdef, $source,
+                                            $owner, $cond, $where);
+       # Return so we don't redefine the rule in our tables, don't check
+       # for ambiguous condition, etc.  The rule will be output anyway
+       # because '&read_am_file' ignores the return code.
+       return ();
      }
  
+   my $rule = _crule $target;
+   # Conditions for which the rule should be defined.  Due to some
+   # complications in the automake internals, this aspect is not as
+   # obvious as it might be, and in come cases this list must contain
+   # other entries in addition to '$cond'.  See the comments in
+   # '_conditionals_for_rule' for a rationale.
+   my @conds = _conditionals_for_rule ($rule, $owner, $cond, $where);
+   # Stop if we had ambiguous conditional definitions.
+   return unless @conds;
    # Finally define this rule.
    for my $c (@conds)
      {
index 2e2ac4c7db975298ecd89efc27c7e836adba4c5c,6e6a74abceb1538912c706d3df528c1414bf5e16..49b86f28731a96e0b3457b37be4e367bbeae43fc
@@@ -56,7 -56,7 +56,7 @@@ do_check (
    cat all.test
    st=0
    if test $use_colors = yes; then
-     make_cmd="$MAKE AM_COLOR_TESTS=always"
 -    make_cmd="env TERM=ansi AM_COLOR_TESTS=always $MAKE -e"
++    make_cmd="$MAKE TERM=ansi AM_COLOR_TESTS=always"
    else
      make_cmd=$MAKE
    fi