From 33932663b031e128200a45818a19fe0620ccb50f Mon Sep 17 00:00:00 2001 From: Dmitry Goncharov Date: Sat, 6 Jan 2024 17:39:43 -0500 Subject: [PATCH] [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 . --- src/file.c | 15 +++++++++--- src/rule.c | 6 +++++ tests/scripts/variables/EXTRA_PREREQS | 33 +++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/file.c b/src/file.c index dc2ea2ae..c3f60046 100644 --- a/src/file.c +++ b/src/file.c @@ -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. */ diff --git a/src/rule.c b/src/rule.c index bdf04e19..51e0500e 100644 --- a/src/rule.c +++ b/src/rule.c @@ -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. */ diff --git a/tests/scripts/variables/EXTRA_PREREQS b/tests/scripts/variables/EXTRA_PREREQS index 57ad597e..2f72be30 100644 --- a/tests/scripts/variables/EXTRA_PREREQS +++ b/tests/scripts/variables/EXTRA_PREREQS @@ -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;