[bug #48643] Irrelevant targets can confuse make on which pattern rule to select.

2021-02-10 Thread Steven Simpson
Additional Item Attachment, bug #48643 (project make):

File name: fix-17752-48643.patch  Size:4 KB




___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/




[bug #60036] Incorrect MAKEFLAGS after $(shell) function call

2021-02-10 Thread анонимный
URL:
  

 Summary: Incorrect MAKEFLAGS after $(shell) function call
 Project: make
Submitted by: None
Submitted on: Ср 10 фев 2021 19:33:22
Severity: 3 - Normal
  Item Group: Bug
  Status: None
 Privacy: Public
 Assigned to: None
 Open/Closed: Open
 Discussion Lock: Any
   Component Version: 4.3
Operating System: MS Windows
   Fixed Release: None
   Triage Status: None

___

Details:

After recursive make call if top-level Makefile set -Otarget and sub-make has
$(shell) function call then MAKEFLAGS exposes all internal values hidden from
user (-j and --jobserver-auth for example). It leads to false warning message
as if -j option specified in Makefile.
It happens because $(shell) function handler invokes define_makeflags(1, 0):

1. define_makeflags()
2. prepare_mutex_handle_string()
3. sync_init()
4. setup_tmpfile()
5. output_start()
6. func_shell_base()

Looks like MAKEFLAGS variable takes its full contents too early. I'm not
familiar with make internals but does it really necessary to do output_start()
in func_shell_base()?

Example Makefile:

start_time := $(shell echo %time%)
MAKEFLAGS += --no-print-directory
MAKEFLAGS += --output-sync=target

.PHONY: all
all:
$(MAKE) build-$@

.PHONY: build-all
build-all:
@echo $@

Output of 'make -j8':

make build-all
make[1]: warning: -j8 forced in makefile: resetting jobserver mode.
build-all





___

Reply to this item at:

  

___
  Сообщение отправлено по Savannah
  https://savannah.gnu.org/




[bug #48643] Irrelevant targets can confuse make on which pattern rule to select.

2021-02-10 Thread Steven Simpson
Follow-up Comment #4, bug #48643 (project make):

Here's a patch that restores the is_target test, and counts the %: rules on
the stack, permitting at most one.  This should fix this bug, without bug
#17752 returning, as features/patternrules test 6 still passes, though perhaps
its explanation should be changed:


# TEST 6: Make sure that non-target files are still eligible to be created
# as part of implicit rule chaining.  Savannah bug #17752.


The problem was not that the intermediate file was not a target, but that it
matched a pattern with no suffix.


diff --git a/src/implicit.c b/src/implicit.c
index b281a17..4223d0f 100644
--- a/src/implicit.c
+++ b/src/implicit.c
@@ -24,7 +24,8 @@ this program.  If not, see . 
*/
 #include "commands.h" /* set_file_variables */
 
 static int pattern_search (struct file *file, int archive,
-   unsigned int depth, unsigned int recursions);
+   unsigned int depth, unsigned int recursions,
+   unsigned int anydepth);
 
 /* For a FILE which has no commands specified, try to figure out some
from the implicit pattern rules.
@@ -42,7 +43,7 @@ try_implicit_rule (struct file *file, unsigned int depth)
  (the archive search omits the archive name), it is more specific and
  should come first.  */
 
-  if (pattern_search (file, 0, depth, 0))
+  if (pattern_search (file, 0, depth, 0, 0))
 return 1;
 
 #ifndef NO_ARCHIVES
@@ -52,7 +53,7 @@ try_implicit_rule (struct file *file, unsigned int depth)
 {
   DBF (DB_IMPLICIT,
_("Looking for archive-member implicit rule for '%s'.\n"));
-  if (pattern_search (file, 1, depth, 0))
+  if (pattern_search (file, 1, depth, 0, 0))
 return 1;
 }
 #endif
@@ -173,6 +174,9 @@ struct tryrule
 
 /* Nonzero if the LASTSLASH logic was used in matching this rule. */
 char checked_lastslash;
+
+/* True if the rule would match anything. */
+char anyrule;
   };
 
 int
@@ -200,7 +204,8 @@ stemlen_compare (const void *v1, const void *v2)
 
 static int
 pattern_search (struct file *file, int archive,
-unsigned int depth, unsigned int recursions)
+unsigned int depth, unsigned int recursions,
+unsigned int anydepth)
 {
   /* Filename we are searching for a rule for.  */
   const char *filename = archive ? strchr (file->name, '(') : file->name;
@@ -317,12 +322,20 @@ pattern_search (struct file *file, int archive,
   const char *target = rule->targets[ti];
   const char *suffix = rule->suffixes[ti];
   char check_lastslash;
+  char anyrule = 0;
 
   /* Rules that can match any filename and are not terminal
- are ignored if we're recursing, so that they cannot be
- intermediate files.  */
-  if (recursions > 0 && target[1] == '\0' && !rule->terminal)
-continue;
+ must not be allowed to nest very deeply.  Record whether
+ we have such a rule, so that if a further level of
+ recursion is required as a result of matching this rule,
+ we can increment the number of such rules we're nested
+ in.  */
+  if (target[1] == '\0' && !rule->terminal)
+{
+  if (anydepth > 0)
+continue;
+  anyrule = 1;
+}
 
   if (rule->lens[ti] > namelen)
 /* It can't possibly match.  */
@@ -395,6 +408,7 @@ pattern_search (struct file *file, int archive,
  target in MATCHES.  If several targets of the same rule match,
  that rule will be in TRYRULES more than once.  */
   tryrules[nrules].rule = rule;
+  tryrules[nrules].anyrule = anyrule;
   tryrules[nrules].matches = ti;
   tryrules[nrules].stemlen = stemlen + (check_lastslash ? pathlen :
0);
   tryrules[nrules].order = nrules;
@@ -704,6 +718,7 @@ pattern_search (struct file *file, int archive,
   /* Go through the nameseq and handle each as a prereq name. 
*/
   for (d = dl; d != 0; d = d->next)
 {
+  struct file *f;
   struct dep *expl_d;
   int is_rule = d->name == dep_name (dep);
 
@@ -753,7 +768,7 @@ pattern_search (struct file *file, int archive,
  FILENAME's directory), so it might actually exist.  */
 
   /* @@ dep->changed check is disabled. */
-  if (lookup_file (d->name) != 0
+  if (((f = lookup_file (d->name)) != 0 && f->is_target)
   /*|| ((!dep->changed || check_lastslash) && */
   || file_exists_p (d->name))
 {
@@ -794,7 +809,8 @@ pattern_search (struct file *file, int archive,
   if (pattern_search (int_file,
   0,