]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 40657] Reinstate old behavior for suffix rules with prereqs
authorPaul Smith <psmith@gnu.org>
Thu, 16 Jan 2020 18:49:07 +0000 (13:49 -0500)
committerPaul Smith <psmith@gnu.org>
Sun, 19 Jan 2020 22:04:52 +0000 (17:04 -0500)
POSIX says that suffix rules cannot have prerequisites, but after
making this change we observed a number of makefiles "in the wild"
that were relying on this behavior and failed.

For .POSIX: makefiles, obey POSIX.  Otherwise preserve the old
behavior.  However, generate a warning so users know this is a
problem.  In a future version we will change all behavior to be
POSIX-conforming.

* NEWS: describe the change
* src/rule.c (convert_to_pattern): If posix_pedantic don't make a
pattern rule if prereqs exist.  Otherwise show a warning.
* tests/scripts/features/suffixrules: Add tests for the new behavior
including .POSIX vs. non-.POSIX.

NEWS
doc/make.texi
src/rule.c
tests/scripts/features/suffixrules

diff --git a/NEWS b/NEWS
index 283372a7181ca11251351de4fc6f754724622b02..a33254c84afeb3220a261baffc84e242ad2ceb0b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -35,10 +35,18 @@ http://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=108&set
   already contains some value.  Similarly, appending an empty string does not
   add a trailing space.
 
-* WARNING: Backward-incompatibility!
-  Contrary to the documentation, suffix rules with prerequisites were being
-  treated BOTH as simple targets AND as pattern rules.  Behavior now matches
-  the documentation, and pattern rules are no longer created in this case.
+* NOTE: Deprecated behavior.
+  Contrary to the documentation, suffix rules with prerequisites are being
+  treated BOTH as simple targets AND as pattern rules.  Further, the
+  prerequisites are ignored by the pattern rules.  POSIX specifies that in
+  order to be a suffix rule there can be no prerequisites defined.  In this
+  release if POSIX mode is enabled then rules with prerequisites cannot be
+  suffix rules.  If POSIX mode is not enabled then the previous behavior is
+  preserved (a pattern rule with no extra prerequisites is created) AND a
+  warning about this behavior is generated:
+    warning: ignoring prerequisites on suffix rule definition
+  The POSIX behavior will be adopted as the only behavior in a future release
+  of GNU make so please resolve any warnings.
 
 * New feature: Grouped explicit targets
   Pattern rules have always had the ability to generate multiple targets with
index 8be8a3644a3acff282314309c92042bcb91b7e08..560e3b3dfde634396e36ec0ef9b75b197ed2f8a4 100644 (file)
@@ -12731,6 +12731,18 @@ receive only part of the information necessary.  In this case, the child
 will generate this warning message and proceed with its build in a
 sequential manner.
 
+@item warning: ignoring prerequisites on suffix rule definition
+According to POSIX, a suffix rule cannot contain prerequisites.  If a rule
+that could be a suffix rule has prerequisites it is interpreted as a simple
+explicit rule, with an odd target name.  This requirement is obeyed when
+POSIX-conforming mode is enabled (the @code{.POSIX} target is defined).  In
+versions of GNU @code{make} prior to 4.3, no warning was emitted and a
+suffix rule was created, however all prerequisites were ignored and were not
+part of the suffix rule.  Starting with GNU @code{make} 4.3 the behavior is
+the same, and in addition this warning is generated.  In a future version
+the POSIX-conforming behavior will be the only behavior: no rule with a
+prerequisite can be suffix rule and this warning will be removed.
+
 @end table
 
 @node Complex Makefile, GNU Free Documentation License, Error Messages, Top
index f4c117907a1ba474d37b3a4c0847dedf2b4d5e8b..7efca58bc61c74502ce15655502932a9d799e2a5 100644 (file)
@@ -272,11 +272,23 @@ convert_to_pattern (void)
           memcpy (rulename + slen, dep_name (d2), s2len + 1);
           f = lookup_file (rulename);
 
-          /* No target, or no commands, or it has deps: it can't be a
-             suffix rule.  */
-          if (f == 0 || f->cmds == 0 || f->deps != 0)
+          /* No target, or no commands: it can't be a suffix rule.  */
+          if (f == 0 || f->cmds == 0)
             continue;
 
+          /* POSIX says that suffix rules can't have prerequisites.
+             In POSIX mode, don't make this a suffix rule.  Previous versions
+             of GNU make did treat this as a suffix rule and ignored the
+             prerequisites, which is bad.  In the future we'll do the same as
+             POSIX, but for now preserve the old behavior and warn about it.  */
+          if (f->deps != 0)
+            {
+              if (posix_pedantic)
+                continue;
+              error (&f->cmds->fileinfo, 0,
+                     _("warning: ignoring prerequisites on suffix rule definition"));
+            }
+
           if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a')
             /* A suffix rule '.X.a:' generates the pattern rule '(%.o): %.X'.
                It also generates a normal '%.a: %.X' rule below.  */
index a18c3637a5abe5d4b3feff425d73fa0d4b4e13f7..b8f465267db9a96634fb7ad78719bacd18a50413 100644 (file)
@@ -51,7 +51,9 @@ run_make_test(q!
 
 unlink('foo.baz');
 
-# Test #4: Suffix rules with deps are not suffix rules
+# SV 40657: Test #4: "Suffix rules" with deps are normal rules
+
+my $prewarn = 'warning: ignoring prerequisites on suffix rule definition';
 
 touch('foo.bar');
 
@@ -59,20 +61,39 @@ run_make_test(q!
 .SUFFIXES:
 .SUFFIXES: .biz .baz
 
+$X.POSIX:
+
 .baz.biz: foo.bar ; @echo make $@ from $<
 !,
-              '.baz.biz', "make .baz.biz from foo.bar\n");
+              'X=1 .baz.biz', "#MAKEFILE#:7: $prewarn\nmake .baz.biz from foo.bar\n");
+
+# SV 40657: Test #5: In POSIX mode we don't get a warning
+
+run_make_test(undef, 'X= .baz.biz', "make .baz.biz from foo.bar\n");
 
 unlink('foo.bar');
 
-# Test #5: Should not create pattern rules for it either
+# SV 40657: Test #6: In POSIX mode, no pattern rules should be created
 
-touch('foo.baz');
+utouch(-20, 'foo.baz');
 
 run_make_test(undef,
-              'foo.biz', "#MAKE#: *** No rule to make target 'foo.biz'.  Stop.\n", 512);
+              'X= foo.biz', "#MAKE#: *** No rule to make target 'foo.biz'.  Stop.\n", 512);
 
-unlink('foo.baz');
+# SV 40657: Test #7: In Non-POSIX mode, a pattern rule is created
+
+run_make_test(undef,
+              'X=1 foo.biz', "#MAKEFILE#:7: $prewarn\nmake foo.biz from foo.baz\n");
+
+# SV 40657: Test #8: ... but any prerequisites are ignored
+
+utouch(-10, 'foo.biz');
+touch('foo.bar');
+
+run_make_test(undef,
+              'X=1 foo.biz', "#MAKEFILE#:7: $prewarn\n#MAKE#: 'foo.biz' is up to date.\n");
+
+unlink('foo.baz', 'foo.biz', 'foo.bar');
 
 # Complete
 1;