具有非假先决条件的 Makefile .PHONY 目标

Makefile .PHONY target with non-phony prerequisite

考虑以下 Makefile(它不是特别好,但是 MWE):

SRC := $(wildcard *.cpp)
TST := $(addprefix test_, $(SRC:.cpp=))

.PRECIOUS: %.exe

%.o: %.cpp
    g++ -c -o $@ $^

%.exe: %.o
    g++ -o $@ $^

test_%: %.exe
    ./$< "Test"

.PHONY: clean $(TST)

clean:
    rm *.exe

它的目标是测试从同名.cpp 文件构建的.exe 文件。例如,foo.cpp 将被构建为 foo.exe,它将使用测试参数执行,如 ./foo.exe "Test"。测试目标名称是 test_foo for foo.cpp/foo.exe.

如果我将所有测试目标(在变量 $(TST) 中)包含为 .PHONY 目标的依赖项,如上所述,它们会在 bash 中的自动完成期间显示,但是它们不起作用,即 make 始终显示 make: Nothing to be done for 'test_foo'.,即使 foo.cpp 已更改。

相反,如果我从 .PHONY 目标中删除 $(TST),则更改为 foo.cpp 会根据需要触发构建和测试过程。但是,目标在 bash.

中的自动完成期间不显示

我的问题是:有没有办法让 make 相信所有 test_ 目标都是虚假目标,同时又不会失去实际构建和执行测试的能力?根据文档,文件依赖项不应该是非文件目标的先决条件。 make -d test_foo 显示

[..]
Considering target file 'test_foo'.
 File 'test_foo' does not exist.
 Finished prerequisites of target file 'test_foo'.
Must remake target 'test_foo'.
Successfully remade target file 'test_foo'.
make: Nothing to be done for 'test_foo'.

看来make连先决条件都不看。即使我将它们设为顺序优先的先决条件,这也不会改变。有没有办法让 make 像我没有将我的 test_ 目标添加到 .PHONY 时那样处理先决条件?

看起来您需要 static pattern rule 才能使 $(TST) 成为模式规则中目标的明确列表。这有效:

$(TST) : test_%: %.exe
    ./$< "Test"

我猜原因是 – 为 make 声明某些东西 .PHONY 不足以认为它实际上是一个值得匹配模式的目标。不知道 bash-completion.

中的推理是什么