]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 54233] Preserve higher command_state values on also_make targets.
authorPaul Smith <psmith@gnu.org>
Sat, 4 Aug 2018 23:07:59 +0000 (19:07 -0400)
committerPaul Smith <psmith@gnu.org>
Sat, 4 Aug 2018 23:07:59 +0000 (19:07 -0400)
If multiple pattern rules have the same pattern as also-make targets
and we attempt to run them at the same time, we might downgrade the
command state from 'running' to 'deps_running'; this will prevent
that also_make from being considered complete causing make to wait
forever for it to finish.

Ensure that set_command_state never downgrades the state of a target.

* src/file.c (set_command_state): Don't downgrade command_state.
* src/filedef.h (struct file): Document the order prerequisite.
* test/scripts/features/patternrules: Test the behavior.

src/file.c
src/filedef.h
tests/scripts/features/patternrules

index 4835e4f856c97a6e7ff19b97fea7bd224c6ff29b..925ce8d8eb4d185d9925f2c11780977f1472ada7 100644 (file)
@@ -788,7 +788,9 @@ snap_deps (void)
 #endif
 }
 \f
-/* Set the 'command_state' member of FILE and all its 'also_make's.  */
+/* Set the 'command_state' member of FILE and all its 'also_make's.
+   Don't decrease the state of also_make's (e.g., don't downgrade a 'running'
+   also_make to a 'deps_running' also_make).  */
 
 void
 set_command_state (struct file *file, enum cmd_state state)
@@ -798,7 +800,8 @@ set_command_state (struct file *file, enum cmd_state state)
   file->command_state = state;
 
   for (d = file->also_make; d != 0; d = d->next)
-    d->file->command_state = state;
+    if (state > d->file->command_state)
+      d->file->command_state = state;
 }
 \f
 /* Convert an external file timestamp to internal form.  */
index 8af562a1284e3d74ffc15c593337f72736fa7104..9d4b816fe3118332c82d71cb84895701aefd5b81 100644 (file)
@@ -68,7 +68,7 @@ struct file
         us_question,            /* Needs to be updated (-q is is set).  */
         us_failed               /* Update failed.  */
       } update_status ENUM_BITFIELD (2);
-    enum cmd_state              /* State of the commands.  */
+    enum cmd_state              /* State of commands.  ORDER IS IMPORTANT!  */
       {
         cs_not_started = 0,     /* Not yet started.  Must be 0!  */
         cs_deps_running,        /* Dep commands running.  */
index f76724eba07155c285d4407c692da25031828a64..177bb32c1a9d026b80b27f2032adacff5fc35b23 100644 (file)
@@ -220,6 +220,22 @@ all: foo.x foo-mt.x
 
 1;
 
+# Test pattern rules building the same targets
+# See SV 54233.  Rely on our standard test timeout to break the loop
+
+touch('a.c');
+
+run_make_test(q!
+all: a.elf a.dbg
+
+%.elf %.lnk: %.c ; : $*.elf $*.lnk
+
+%.elf %.dbg: %.lnk ; : $*.elf $*.dbg
+!,
+    '-j2', ": a.elf a.lnk\n: a.elf a.dbg\n");
+
+unlink('a.c');
+
 # This tells the test driver that the perl test script executed properly.
 1;