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

2021-11-14 Thread Steven Simpson
Follow-up Comment #16, bug #48643 (project make):

[comment #15 comment #15:]
> If patch-v1 is applied and released, then users will start writing
> makefiles which depend on this feature.  This will slow down make,
> including for those users who do not even use this feature.
Okay.

> Once this feature is released, it will be very difficult to undo.
Agreed.

> Let us say hello.c and hello.tsk are missing and consider the
> following example.
> 
> Example 5.
> 
> all: hello.tsk
> %.tsk: %.c; gcc -o $@ $<
> .DEFAULT:; echo 'int main() {}' > $@
> unrelated: hello.c
> 
> Here, make chooses rule '%.tsk: %.c' to build hello.tsk, because
> hello.c is mentioned on an unrelated rule.  Make then finds the
> default rule to build hello.c. Both make-4.3 and dgfix support example
> 5. Patch-v1 fails example 5.
This seems more compelling.

> I attempted to modify the search algorithm to support all the possible
> use cases and concluded that the most reliable and the simplest is the
> algorithm that performs compatibility search, presented above.
> We can reason that the compatibility search supports all uses cases
> that make-4.3 supports, because compatibility search is the same as
> the current search of make-4.3.

> i hope, this demonstrates that there are other differences.
It does.  You've convinced me that accepting 'unrelated' rules needs to
continue to be supported, and your patch does that.  Thanks!

___

Reply to this item at:

  

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




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

2021-11-11 Thread Steven Simpson
Follow-up Comment #14, bug #48643 (project make):

I've got three implementations of Make lined up.  One is master, one has my
recent changes applied to master from last month (ssfix; patch included), and
one is master with your sv48643_fix.diff applied (dgfix).  I've attached a
script to compare these on the examples you've provided (and a couple more),
and the output with these three implementations.  The comments below refer to
this output.

[comment #12 comment #12:]
> Let us say hello.c is missing, hello.f is present in the filesystem and
> consider the following example
> 
> Example 1.
> 
> all: hello.tsk
> %.tsk: %.c; $(info $@ from $<)
> %.tsk: %.f; $(info $@ from $<)
> unrelated: hello.c
> 
> The current behavior is to choose rule '%.tsk: %.c' because 'hello.c' is
> mentioned explicitly on an unrelated rule.
> The desired behavior is to skip '%.tsk: %.c' rule and choose '%.tsk: %.f'
rule.
> 
> This desired behavior alone could be achieved by eliminating
ought-to-exist.
For this example, all three Makes fail when no source is provided, but
make-dgfix and master report no rule for 'hello.c', while make-ssfix reports
no rule for 'hello.tsk'.  When 'hello.f' is present but 'hello.c' is not,
master finds no rule for 'hello.c', while make-dgfix and make-ssfix correctly
build from 'hello.f'.  In the other two circumstances, they are identical.

For further comparison, I also dropped the 'unrelated' line, and all three
implementations produce the same results in all circumstances.  Note that
make-ssfix generates the same error in the no-source case, regardless of the
presence or absence of the 'unrelated' line, so it is treating it as
unrelated.

> However, let us consider the following example which demonstrates that
> ought-to-exist concept has to stay.
To be clear, I agree that ought-to-exist has to stay, but the documented and
implemented definitions are too broad, as you say.

> i think, a good change is to restrict ought-to-exist as this
> 
> "If a file name is mentioned in the makefile as a target or as an explicit
> prerequisite of the current target, then we say it ought to exist."
> 
Sounds good.

> Example 2.
> 
> all: hello.tsk
> hello.tsk: hello.c
> %.tsk: %.c; $(info $@ from $<)
> %.tsk: %.f; $(info $@ from $<)
> 
For this one, all three Makes are identical in all circumstances, so
make-ssfix _has not got rid of_ this part of the ought-to-exist definition.

> Example 3.
> 
> all: hello.tsk
> %.tsk: %; $(info $@ from $<)
> unrelated: hello
> 
(Aside: Is the lack of a suffix significant?)

> In this example rule '%.tsk: %' is chosen to build hello.tsk, because
'hello'
> is mentioned explicitly on an unrelated rule.
Are you saying that this also should be the correct behaviour?

With no 'hello' file, master and make-dgfix complain of no rule for 'hello',
while make-ssfix complains for 'hello.tsk'.  All three Makes behave
identically when 'hello' exists.

With the 'unrelated' line removed, all three Makes are identical in both
cases.

As with Example 1, make-ssfix's behaviour is consistent whether the
'unrelated' line is present or not, especially in the case where source is
absent, i.e., the error message is the same.

There's only a difference between the implementations when the Makefile isn't
going to work anyway, i.e., when 'hello' doesn't exist.  If there's a way to
build 'hello' too, it must appear as a target, so I don't think Example 3
demonstrates a case where the broader behaviour is required.


(file #52238, file #52239, file #52240)
___

Additional Item Attachment:

File name: fix-48643-simpsons-v2.diff Size:1 KB
   


File name: ss-trials.sh   Size:2 KB


File name: ss-trials-out.txt  Size:6 KB




___

Reply to this item at:

  

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




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

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

I saw a couple of tests in targets/NOTINTERMEDIATE failing, 2 and 10. 
Preserving an already set notintermediate flag (in the same way that
intermediate is preserved) allows the tests to pass.  This
(src/implicit.c#919):

  f->notintermediate = imf->notintermediate;
  f->intermediate = !(pat->is_explicit || f->notintermediate);

...becomes:

  f->notintermediate = f->notintermediate || imf->notintermediate;
  f->intermediate = f->intermediate ||
!(pat->is_explicit || f->notintermediate);

It's almost the same issue as before.  Without the f->is_target test, the
deplist entry is set at around line 777, the branch at 892 fails, so the lines
above are avoided.  With it, the entry is set at 821, and the branch at 892
passes.


[comment #6 comment #6:]
> I'm seeing some failures after applying this patch.
Now [make check] reports no failures, although features/guile and vms/library
are N/A, and options/dash-I warns of non-numeric arguments.  Were you seeing
any others?
> That is, pattern rule trees are searched "width first", not "depth first".
(By "width first" do you mean "breadth-first"?  I think the point might be
moot, though, since depth-vs-breadth affects the order of solutions, but we're
talking about whether foo:bar is a solution at all when looking for bar.)
> In the example we have:
> 
> default: a.foo
> %.foo: %.correct ; @echo $@ from $<
> %.foo: %.mislead ; @echo $@ from $<
> 
[snip]
> 
> misleading_target: a.mislead
> 
> It's true that it's a prerequisite of some completely different target, and
we're not even trying to build that target, but that doesn't matter.  The rule
5.3 in the above page says that it matches if all the prerequisites "exists or
*ought to exist*".  As can be seen in the rule statement, the definition of
"ought to exist" is simply, "is mentioned in the makefile as a target or as an
explicit prerquisite".
You're right - it's there in black and white.  But it seems to me an odd
definition of "ought to exist" for the purpose.  (So, yes, I seem to have a
similar position to Boris's.)  If you've tentatively identified that a.foo
could be built from a.mislead, you want to be looking next for a rule that
*targets* a.mislead, not merely one that mentions it.  Otherwise, you're not
forming a chain A:B, B:C, C:D, etc.  Furthermore, having failed the (f =
lookup_file) test, execution shortly goes on to look for another pattern rule
(by the recursive call to pattern_search), and it will be matching against the
target side of the rule, not the prerequisite side (right?).

I'm not certain of this, so I'd be interested in seeing other cases where the
broader definition is required.

___

Reply to this item at:

  

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




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

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

[comment #9 comment #9:]
> Unfortunately it's exactly the is_target test that causes the problems.  The
rest of the changes, without that, don't seem to have any issues.
Okay, thanks.

I hope to get round to the documentation issue.  For now, I've had a look at
targets/INTERMEDIATE test 8, which is using this:


all: hello.z
%.z: test.x; touch $@
%.x: ;
.INTERMEDIATE: test.x


It then pre-creates hello.z, and asserts that nothing will be rebuilt, because
test.x is intermediate.

With the is_target test in place, execution reaches src/implicit.c line ~920:

  f->intermediate = !(pat->is_explicit || f->notintermediate);

f is pointing at the entry for "test.x", which already has its intermediate
flag set, but this line cancels it.  Later, the file struct is looked up
again:

  dep->file = lookup_file (s);

And so the file is seen as non-intermediate in src/remake.c:

  if (d_mtime == NONEXISTENT_MTIME && !d->file->intermediate)
/* We must remake if this dep does not
   exist and is not intermediate.  */
must_make = 1;


Without is_target, pat->file is null, so the f->intermediate assignment is
never carried out.  When the file is looked up later, f->intermediate hasn't
been reset, so test.x's intermediacy is preserved.

f->intermediate could be preserved like this:

  f->intermediate = f->intermediate || !(pat->is_explicit ||
f->notintermediate);


Then, without is_target, we get:

$ ~/Works/make/make -rRd
GNU Make 4.3.90
[snip]
Considering target file 'all'.
 File 'all' does not exist.
 Looking for an implicit rule for 'all'.
 No implicit rule found for 'all'.
  Considering target file 'hello.z'.
   Looking for an implicit rule for 'hello.z'.
   Trying pattern rule with stem 'hello'.
   Trying rule prerequisite 'test.x'.
   Found an implicit rule for 'hello.z'.
Looking for an implicit rule for 'test.x'.
Trying pattern rule with stem 'test'.
Found an implicit rule for 'test.x'.
   Finished prerequisites of target file 'hello.z'.
   Prerequisite 'test.x' of target 'hello.z' does not exist.
  No need to remake target 'hello.z'.
 Finished prerequisites of target file 'all'.
Must remake target 'all'.
Successfully remade target file 'all'.
make: Nothing to be done for 'all'.


With is_target:

$ ~/Works/make/make -rRd
GNU Make 4.3.90
[snip]
Considering target file 'all'.
 File 'all' does not exist.
 Looking for an implicit rule for 'all'.
 No implicit rule found for 'all'.
  Considering target file 'hello.z'.
   Looking for an implicit rule for 'hello.z'.
   Trying pattern rule with stem 'hello'.
   Trying rule prerequisite 'test.x'.
   Trying pattern rule with stem 'hello'.
   Trying rule prerequisite 'test.x'.
   Looking for a rule with explicit file 'test.x'.
Avoiding implicit rule recursion.
Trying pattern rule with stem 'test'.
   Found an implicit rule for 'hello.z'.
   Finished prerequisites of target file 'hello.z'.
   Prerequisite 'test.x' of target 'hello.z' does not exist.
  No need to remake target 'hello.z'.
 Finished prerequisites of target file 'all'.
Must remake target 'all'.
Successfully remade target file 'all'.
make: Nothing to be done for 'all'.


So either way, test 8 passes.

In summary, the lack of is_target causes the .INTERMEDIATE rule to be mistaken
for a 'real' rule about test.x, and avoids the execution path that would reset
the intermediate flag.

___

Reply to this item at:

  

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




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

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

[comment #6 comment #6:]
> I'm seeing some failures after applying this patch.
Just to narrow down the investigation, it might help to split this patch into
two.  The is_target test and the supporting declaration of f would be the
primary patch.  The rest is really just about allowing features/patternrules
test 6 to continue to pass with the primary in place, so perhaps that test
should be temporarily disabled while seeing whether the primary alone is still
the cause of these failures.

(Looking at your other points, meanwhile...)

___

Reply to this item at:

  

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




[bug #47880] Allow updates to .INCLUDE_DIRS to change search path

2021-05-07 Thread Steven Simpson
Follow-up Comment #14, bug #47880 (project make):

> when a user writes a makefile he should not have to know that
> 
> depfiles:=$(obj:.o=.d)
> include $(depfiles)
> 
> is less efficient than
> 
> depfiles:=$(obj:.o=.d)
> depfiles:=$(addprefix $(CURDIR)/,$(depfiles))
> include $(depfiles)

Perhaps he should, specifically since the issue has been raised.

(Incidentally, $(abspath) achieves largely the same thing as prefixing
CURDIR.)

Anyway, the various suggestions are not mutually exclusive:

* Add -I- to allow the invoker to reset the search path.  (This is what I
meant by a "switch analogous to -r/-R", in case I wasn't clear.)
* Add includelocal to allow an author to indicate when he definitely doesn't
want to use the search path for specific files.  (He could use abspath/CURDIR,
but if the included files are also targets, those rules have to be changed
too.)
* Allow effective modifications to .INCLUDE_DIRS.


___

Reply to this item at:

  

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




[bug #47880] Allow updates to .INCLUDE_DIRS to change search path

2021-04-26 Thread Steven Simpson
Follow-up Comment #12, bug #47880 (project make):

> > include $(CURDIR)/foo.mk
> 
> This indeed suppresses the lookup.
> 
> My opinion is that the users should not have to know this detail.

I didn't realize you were wearing your 'user' hat!  To me, this is a problem
ideally for the author to solve.  However, I'm not against an option to either
reset the include path or disable its initial population, allowing a user to
work around the issue.

> Also, most (as far as i can tell) existing makefiles do not do this.

(Indeed, I only found out about CURDIR yesterday!  I had thought prefixing ./
was enough, and I shall be modifying my makefiles accordingly.)

> > this might be better considered a question of disabling the search path on
a per-include basis
> 
> Is there a need for such flexibility?

Yes, from the author's perspective.  Since you report that using $(CURDIR)
allows the author to resolve the issue, my suggestions such as includelocal or
making a special case for ./-prefixed paths are redundant.

> A command line switch or +I  get the job done and relieve the users from
having to change the makefiles.

I'm not against such user-oriented solutions.  :-)  Sorry if you got that
impression.

___

Reply to this item at:

  

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




[bug #47880] Allow updates to .INCLUDE_DIRS to change search path

2021-04-25 Thread Steven Simpson
Follow-up Comment #10, bug #47880 (project make):

> One trouble of this default is, when your dep files are missing, make does a
fs access per default directory for each missing dep file.

Are these always cases where you know you want a local file?  Can you use
this?:


include $(CURDIR)/foo.mk


(Or does the full path cause more accesses?)

In terms of new features, this might be better considered a question of
disabling the search path on a per-include basis, when you know you want a
local file.  The '*include' directives are implemented with a call to
eval_makefile, which has an RM_INCLUDED option to enable the search path, it
seems.  Perhaps a leading '.' on the filename should suppress it (just as '/'
does), or a new directive '*includelocal' would call without RM_INCLUDED.

___

Reply to this item at:

  

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




[bug #47880] Allow updates to .INCLUDE_DIRS to change search path

2021-04-24 Thread Steven Simpson
Follow-up Comment #7, bug #47880 (project make):

> Regarding removing default directories, I wonder what people think of using
something like "-I-" to mean "delete all known include directories up to here
and start over with a fresh set"?  So if you used "make -I- -I/foo -I/bar" the
include directories would be "/foo" and "/bar" with no defaults; if you use
"make -I/foo -I- -I/bar" then the include path would just be "/bar".

I've written makefiles that are installed and used like libraries.  They are
installed by default in /usr/local/include so that users can find them without
any extra configuration, so it would be inconvenient to lose the notion of
default include directories.  A switch analogous to -r/-R seems like a more
backward-compatible option than removing them all by default.

___

Reply to this item at:

  

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




Re: Possible GNU Make 4.3 bug

2021-03-20 Thread Steven Simpson

Hi Eldred,

On 15/03/2021 22:25, Eldred HABERT wrote:


The bug is the following two lines:

   Must remake target 'res/tpnk_dev_logo_tiles.2bpp.pb16.size'.
   Successfully remade target file 
'res/tpnk_dev_logo_tiles.2bpp.pb16.size'.




This .size file appears to be a generated header for assembly source, 
and the assembler has generated rules for it:


obj/starting_screen.o dep/starting_screen.mk : 
res/tpnk_dev_logo_tiles.2bpp.pb16.size
res/tpnk_dev_logo_tiles.2bpp.pb16.size:

I understand the need for the second rule, but it also defines an empty 
recipe, and this one doesn't apply:


$(RESDIR)/%.pb16.size: $(RESDIR)/%
@$(MKDIR_P) $(@D)
$(call filesize,$<,16) > $(RESDIR)/$*.pb16.size

...because the prerequisite res/tpnk_dev_logo_tiles.2bpp doesn't exist, 
and no rule exists to create it.


There is a 
src/res/starting_screen/tpnk_dev_logo/tpnk_dev_logo_tiles.2bpp, and you 
have VPATH set to src, but I don't think VPATH is supposed to 
recursively search subdirectories.  A solution would have to identify 
these subdirectories somehow, e.g.:


SRCDIRS := $(shell find $(SRCDIR) -type d)
vpath %.2bpp $(SRCDIRS)

$(RESDIR)/%.2bpp: %.2bpp
@$(MKDIR_P) $(@D)
cp $< $@

That allowed res/tpnk_dev_logo_tiles.2bpp.pb16.size to build for me.

Cheers,

Steven



[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 #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,
 

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

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

With the is_target test restored in implicit.c, "make check" fails:


features/patternrules ... Error running
/home/simpsons/Works/make/tests/../make (expected 0; got 512):
'/home/simpsons/Works/make/tests/../make' '-f'
'work/features/patternrules.mk.6'
FAILED (11/12 passed)


Seems to be in conflict with bug #17752 - the is_target test was removed to
resolve it, I gather.

I adapted a makefile from features/patternrules so that the intermediate can
have a specific suffix:


STEM = xyz
BIN = $(STEM)$(SFX)
COPY = $(STEM).cp
SRC = $(STEM).c
allbroken: $(COPY) $(BIN) ; @echo ok
$(SRC): ; @echo 'main(){}'
%.cp: %$(SFX) ; @echo $@ from $<
%$(SFX) : %.c ; @echo $@ from $<


Used with no builtin rules, if $(SFX) is non-empty, this works in 3.80, 3.81
and 4.3.  If $(SFX) is empty, only 3.81 fails.

So a %.sfx:%.c rule works, but %:%.c doesn't, because the target lacks a
suffix.  It seems this test eliminates the rule from the candidates:


  /* 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;


This suggests that the test case in bug #17752 is a 'feature', as it tries to
use a rule "that can match any filename" to build an intermediate,
specifically, a builtin rule %:%.c.  The in_use flag prevents these repeating,
as in foo.c.c.c, but with umpteen builtin rules of this sort, every
arrangement of every subset of suffixes in these rules is tried, and that
takes a long time, which can result in some checks (variables/EXTRA_PREREQS)
being aborted.

I managed to introduce a new parameter to pattern_search, unsigned anydepth,
which is incremented on the recursive call only if such a rule is used.  The
test above then becomes:


  char anyrule = 0;
  if (target[1] == '\0' && !rule->terminal)
{
  if (anydepth > 3)
continue;
  anyrule = 1;
}


anyrule is then stored in the tryrules entry, so it can be tested on
recursion:


  if (pattern_search (int_file,
  0,
  depth + 1,
  recursions + 1,
  anydepth + !!tryrules[ri].anyrule))


This allows %:%.X rules to be applied at any depth, but limits the total
number on the stack.

For me, "make check" passes with the anydepth limit set to 0, 1, 2 or 3, but 4
took too long on the variables/EXTRA_PREREQS tests.

___

Reply to this item at:

  

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




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

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

I think the problem might be in src/implicit.c.

>From 3.81 code:


  /* The DEP->changed flag says that this dependency resides in a
 nonexistent directory.  So we normally can skip looking for
 the file.  However, if CHECK_LASTSLASH is set, then the
 dependency file we are actually looking for is in a
different
 directory (the one gotten by prepending FILENAME's
directory),
 so it might actually exist.  */

  /* @@ dep->changed check is disabled. */
  if (((f = lookup_file (name)) != 0 && f->is_target)
  /*|| ((!dep->changed || check_lastslash) && */
  || file_exists_p (name))
continue;


The corresponding check in 4.3:


  if (lookup_file (d->name) != 0
  /*|| ((!dep->changed || check_lastslash) && */
  || file_exists_p (d->name))


There's no check for f->is_target on the result of lookup_file, so I presume
it is picking up the name as a dependency.  Perhaps it should read:


  if (((f = lookup_file (d->name)) != 0 && f->is_target)
  /*|| ((!dep->changed || check_lastslash) && */
  || file_exists_p (d->name))


f is a [struct file *], not declared in 4.3.

___

Reply to this item at:

  

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




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

2016-08-23 Thread Steven Simpson
Follow-up Comment #1, bug #48643 (project make):

According to what I wrote in
, this
behaviour is present in 3.82, 4.1 and 4.2.1, but not 3.81.

___

Reply to this item at:

  

___
  Message sent via/by Savannah
  http://savannah.gnu.org/


___
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make