考虑以下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"
)执行。对于foo.cpp / foo.exe,测试目标名称为test_foo。
如果我将所有测试目标(在变量$(TST)
中)作为对.PHONY
目标的依赖关系,如上所述,它们将在bash
的自动完成过程中显示,但它们确实会不起作用,即,即使更改了foo.cpp,make
也始终声明make: Nothing to be done for 'test_foo'.
。
相反,如果我从$(TST)
目标中删除.PHONY
,则对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
一样?
答案 0 :(得分:1)
看起来您需要static pattern rule才能使$(TST)
成为模式规则中目标的明确列表。这可行:
$(TST) : test_%: %.exe
./$< "Test"
我对原因的猜测是–为.PHONY
声明make
不足以认为它实际上是值得匹配模式的目标。不知道bash完成的原因是什么。