diff --git a/src/implicit.c b/src/implicit.c index 4abd1ce9..c65aec66 100644 --- a/src/implicit.c +++ b/src/implicit.c @@ -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; diff --git a/tests/scripts/features/implicit_search b/tests/scripts/features/implicit_search index 32c9a716..745423d8 100644 --- a/tests/scripts/features/implicit_search +++ b/tests/scripts/features/implicit_search @@ -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;