[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: '... | Avoiding implicit rule recursion for rule '%/dir: %'. | ...'
From: |
Dmitry Goncharov |
Subject: |
Re: '... | Avoiding implicit rule recursion for rule '%/dir: %'. | ...' |
Date: |
Thu, 7 Nov 2024 23:41:13 -0500 |
On Thu, Nov 7, 2024 at 3:49 AM WaitronCharm via Bug reports and
discussion for GNU make <bug-make@gnu.org> wrote:
> > all: hello.tsk
> > %.tsk: %.o; $(info hello.tsk)
> > %.o: %.c %.tsk; $(info hello.c)
> Wouldn't this result anyway in a cyclic graph due to '%.tsk'?
This is a legal makefile. Make drops the circular dependency and
successfully builds hello.tsk.
> What I meant in my earlier email is that protecting from infinite recursion
> should not happen by forbidding recursion completely.
As i said earlier, the authors probably had other reasons.
Given that we mostly deal with files like hello.o, rather than
hello.o.o, one obvious question is why do you even want to do this?
> Would this be then (1) check out the code, (2) add a new special target, (3)
> instead of 'break' simply continue around line 'Avoiding implicit rule
> recursion for rule', (4) compile and see the result?
(5) add tests, (6) update the manual.
> What I meant by complications is whether the implementation uses the pattern
> rule name as some 'identifier' in any structures and multiples of the same
> pattern rule name (per target) would cause mess. (New 'identifier' could
> change to the combination of pattern rule name and instance no. of applying
> that rule).
No.
> I am not familiar with the 'make' code and did not look into it yet. Want to
> just estimate how much work would this be.
i posted a diff below that you can use. This diff achieves the
behavior you desire. You can see, the change is small. The hard part
here, is not the size of the changeset. The hard part is to convince
yourself that, with this change, make still does the minimal necessary
amount of implicit searches.
regards, Dmitry
diff --git a/src/file.c b/src/file.c index 6f816c8a..c8017e34 100644
--- a/src/file.c +++ b/src/file.c @@ -911,6 +911,10 @@ snap_deps
(void) d2->wait_here = 1; } + f = lookup_file
(".ALLOW_RECURSIVE_CHAINS"); + if (f != 0 && f->is_target) +
allow_recursive_chains = 1; + { struct dep *prereqs =
expand_extra_prereqs (lookup_variable
(STRING_SIZE_TUPLE(".EXTRA_PREREQS"))); diff --git a/src/implicit.c
b/src/implicit.c index 134e3fef..2bd2b90e 100644 --- a/src/implicit.c
+++ b/src/implicit.c @@ -297,7 +297,7 @@ pattern_search (struct file
*file, int archive, /* If this rule is in use by a parent
pattern_search, don't use it here. */ - if (rule->in_use) + if
(rule->in_use && !allow_recursive_chains) { DBS (DB_IMPLICIT,
(_("Avoiding implicit rule recursion for rule '%s'.\n"), diff --git
a/src/main.c b/src/main.c index 78084d09..5333df5f 100644 ---
a/src/main.c +++ b/src/main.c @@ -193,6 +193,10 @@ static int
old_builtin_variables_flag; int export_all_variables = 0; +/* Nonzero
means a chain of implicit rules can have a rule multiple times. */ +
+int allow_recursive_chains; + /* Nonzero means keep going even if
remaking some file fails (-k). */ int keep_going_flag; diff --git
a/src/makeint.h b/src/makeint.h index 61c78229..27a269ed 100644 ---
a/src/makeint.h +++ b/src/makeint.h @@ -736,6 +736,7 @@ extern int
print_version_flag, check_symlink_flag, posix_pedantic; extern int
not_parallel, second_expansion, clock_skew_detected; extern int
rebuilding_makefiles, one_shell, output_sync, verify_flag; extern int
export_all_variables; +extern int allow_recursive_chains; extern
unsigned long command_count; extern const char *default_shell;