(使用GNU make)
我有Makefile
默认目标负责“编译”代码。我没有run_test
目标执行测试,但会在需要时重新编译。
我希望在运行任何编译步骤之前清除的日志文件,但是只有在运行编译步骤时才,所以如果只运行测试则不行。我定义了一个reset_log
目标来清除日志。我想要的行为是:
make all
当所有都是最新的 - 没有运行,日志未清除make all
当不最新时 - 日志已清除,然后运行相应的编译规则make run_test
当所有都是最新的 - 没有编译,日志未清除,测试运行make run_test
当不最新时 - 清除日志,然后运行适当的编译规则,然后运行测试如何在必须进行编译时,但在任何依赖关系配方运行之前,才能使reset_log
目标(或等效命令)运行?这里简化了Makefile
:
LOG_FILE = file.log
all: compile
compile: final.out
reset_log:
-rm -f $(LOG_FILE)
final.out: final.in reset_log 1.out 2.out
cp -v final.in final.out | tee -a $(LOG_FILE)
1.out: 1.in
cp -v 1.in 1.out | tee -a $(LOG_FILE)
2.out: 2.in
cp -v 2.in 2.out | tee -a $(LOG_FILE)
run_test: compile
@echo "======= Run Test Here ======="
clean:
-rm *.out $(LOG_FILE)
.PHONY: local_target reset_log run_test clean
注意:此示例不起作用(reset_log
和final.out
目标每次都会重新运行,因为reset_log
是一个final.out
的依赖关系本身没有依赖关系),但演示了我希望reset_log
运行的位置。
一种可能的解决方案是在运行依赖项配方之前,有办法为目标运行过时的配方。
更新2016-10-18
基于user657267的解决方案(以及我在评论中建议的小改进),这里是上面例子的重新编码,即我需要的最终解决方案:
LOG = file.log
all: compile
compile: $(LOG)
$(LOG): final.out
mv $@.tmp $@ || ( echo "WARNING: $< not found. Creating dummy $@ to allow make to run" > $@ )
final.out: 1.out 2.out
%.out: %.in
cp -v $< $@ | tee -a $(LOG).tmp
run_test: compile
@echo "======= Run Test Here ======="
clean:
-rm *.out $(LOG)
.PHONY: run_test clean compile
答案 0 :(得分:1)
使用第二个临时日志文件
log := file.log
out := final.out 1.out 2.out
.PHONY: run_test clean
$(log): $(out)
mv $@.tmp $@
run_test: $(log)
@echo "======= Run Test Here ======="
clean:
$(RM) $(out) $(log)
%.out: %.in
cp -v $< $@ | tee -a $(log).tmp