[SV 65006] Allow secondary expansion of .EXTRA_PREREQS

* src/rule.c (snap_implicit_rules): Set need_2nd_expansion of each
  prerequisite of global .EXTRA_PREREQS.
* src/file.c (snap_file):  Set need_2nd_expansion of each prerequisite
  of target-specific .EXTRA_PREREQS.
* tests/scripts/variables/EXTRA_PREREQS: Add tests.

Reported by Daniel Gerber <dg@atufi.org>.
This commit is contained in:
Dmitry Goncharov 2024-01-06 17:39:43 -05:00 committed by Paul Smith
parent 89bea82af3
commit 33932663b0
3 changed files with 51 additions and 3 deletions

View file

@ -722,6 +722,7 @@ snap_file (const void *item, void *arg)
{
struct file *f = (struct file*)item;
struct dep *prereqs = NULL;
struct dep *d;
/* If we're not doing second expansion then reset updating. */
if (!second_expansion)
@ -741,14 +742,22 @@ snap_file (const void *item, void *arg)
/* If .EXTRA_PREREQS is set, add them as ignored by automatic variables. */
if (f->variables)
prereqs = expand_extra_prereqs (lookup_variable_in_set (STRING_SIZE_TUPLE(".EXTRA_PREREQS"), f->variables->set));
{
prereqs = expand_extra_prereqs (lookup_variable_in_set (
STRING_SIZE_TUPLE(".EXTRA_PREREQS"), f->variables->set));
if (second_expansion)
for (d = prereqs; d; d = d->next)
{
if (!d->name)
d->name = xstrdup (d->file->name);
d->need_2nd_expansion = 1;
}
}
else if (f->is_target)
prereqs = copy_dep_chain (arg);
if (prereqs)
{
struct dep *d;
for (d = prereqs; d; d = d->next)
if (streq (f->name, dep_name (d)))
/* Skip circular dependencies. */

View file

@ -140,6 +140,12 @@ snap_implicit_rules (void)
const char *d = dep_name (dep);
size_t l = strlen (d);
if (second_expansion)
{
if (!dep->name)
dep->name = xstrdup (dep->file->name);
dep->need_2nd_expansion = 1;
}
if (dep->need_2nd_expansion)
/* When pattern_search allocates a buffer, allow 5 bytes per each % to
substitute each % with $(*F) while avoiding realloc. */

View file

@ -145,7 +145,40 @@ tick tack: ; @echo $@
',
'all', "tack\ntick\ntack tick\n");
# SV 65006. Second expansion of global .EXTRA_PREQREQS.
run_make_test('
.SECONDEXPANSION:
extradep:=tick tack
.EXTRA_PREREQS=$$(extradep)
%.x:; @echo $@
',
'hello.x', "hello.x\n");
unlink('tick', 'tack');
# SV 65006. Second expansion of a target-specific .EXTRA_PREQREQS.
run_make_test('
.SECONDEXPANSION:
all: hello.x;
extradep=tick tack
hello.x: .EXTRA_PREREQS=$$(extradep)
%.x:; @echo $@
tick tack:; @echo $@
',
'', "tick\ntack\nhello.x\n");
# SV 65006. Second expansion of a target-specific .EXTRA_PREQREQS.
# The value of .EXTRA_PREQREQS contains automatic variables.
run_make_test('
.SECONDEXPANSION:
all: hello.x world.x
hello.x world.x: .EXTRA_PREREQS=$$@.d
%.x:; @echo $@
%.d:; @echo $@
',
'', "hello.x.d\nhello.x\nworld.x.d\nworld.x\n");
# This tells the test driver that the perl test script executed properly.
1;