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

时间:2019-09-05 07:43:18

标签: makefile gnu-make

考虑以下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一样?

1 个答案:

答案 0 :(得分:1)

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

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

我对原因的猜测是–为.PHONY声明make不足以认为它实际上是值得匹配模式的目标。不知道bash完成的原因是什么。