[SV 48643] Preserve target-specific variables on intermediate files

Target-specific variables used to define the target as "ought to
exist" so they could never be intermediate.  Now they can be, so
merge the target-specific variables from the intermediate target
so they're not lost.

* src/implicit.c (pattern_search): Use merge_variable_set_lists
to merge target-specific variables.
* tests/scripts/features/implicit_search: Add tests of target-
specific variable assignments and implicit rules.
This commit is contained in:
Dmitry Goncharov 2021-12-29 14:26:40 -05:00 committed by Paul Smith
parent 8aba33a8bd
commit f2b130bda8
2 changed files with 68 additions and 1 deletions

View File

@ -975,7 +975,11 @@ pattern_search (struct file *file, int archive,
f->deps = imf->deps;
f->cmds = imf->cmds;
f->stem = imf->stem;
f->variables = imf->variables;
/* Setting target specific variables for a file causes the file to be
* entered to the database as a prerequisite. Implicit search then
* treats this file as explicitly mentioned. Preserve target specific
* variables of this file. */
merge_variable_set_lists(&f->variables, imf->variables);
f->pat_variables = imf->pat_variables;
f->pat_searched = imf->pat_searched;
f->also_make = imf->also_make;

View File

@ -423,5 +423,68 @@ unrelated: bye.o
unlink('hello.f', 'hello.z', 'hello.xx', 'bye.xx');
# A target specific variable causes the file to be entered to the database as a
# prerequisite. Implicit search then treats this file as explicitly mentioned.
# Test that implicit search keeps target specific variables of this file intact.
# In this series of tests prerequisite 'hello.x' has a target specific variable
# and is built as an intermediate. Implicit search treats 'hello.x' as
# explicitly mentioned, but 'hello.x' does not qualify as ought-to-exist.
unlink('hello.x', 'hello.tsk');
# 'hello.x' is mentioned explicitly on the same implicit rule.
run_make_test(q!
all: hello.tsk
%.tsk: hello.x; $(info $@)
%.x:; $(flags)
hello.x: flags:=true
!, '', "true\nhello.tsk\n");
# Similar to the one above, but this time 'hello.x' is derived from the stem.
run_make_test(q!
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x:; $(flags)
hello.x: flags:=true
!, '', "true\nhello.tsk\n");
# Similar to the one above, this time 'hello.x' is also mentioned explicitly on
# an unrelated rule.
run_make_test(q!
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x:; $(flags)
hello.x: flags:=true
unrelated: hello.x
!, '', "true\nhello.tsk\n");
# 'hello.x' has a pattern specific variable.
run_make_test(q!
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x:; $(flags)
%.x: flags:=true
!, '', "true\nhello.tsk\n");
# 'hello.x' has a target specific variable and a pattern specific variable.
run_make_test(q!
all: hello.tsk
%.tsk: %.x; $(info $@)
%.x:; $(flags)
hello.x: flags+=good
%.x: flags:=true
!, '', "true good\nhello.tsk\n");
# Intermediate prerequisite 'hello.x' has a target specific variable, a pattern
# specfic variable, matches on both rules '%.tsk: %.x' and 'big_%.tsk: %.x'.
run_make_test(q!
all: hello.tsk big_hello.tsk
%.tsk: %.x; $(info $@)
big_%.tsk: %.x; $(info $@)
%.x:; $(flags)
hello.x: flags+=good
%.x: flags:=true
!, '', "true good\nhello.tsk\nbig_hello.tsk\n");
# This tells the test driver that the perl test script executed properly.
1;