Makefile:保存错误并在末尾打印
我有以下Makefile snipt,它运行一些测试:Makefile:保存错误并在末尾打印,makefile,gnu-make,Makefile,Gnu Make,我有以下Makefile snipt,它运行一些测试: MKFILES = $(wildcard $(addprefix $(UNIT_TEST_SRC)/,$(subst $(comma), ,*.mk)))) TESTS = $(MKFILES:.mk=.test) %.test:%.mk @make -f $? run_tests: $(TESTS) 上面的操作很好,但我正在尝试更改它,以便在测试出错时,它不会中止,而是继续并在最后打印出所有失败 FAILURES := %.
MKFILES = $(wildcard $(addprefix $(UNIT_TEST_SRC)/,$(subst $(comma), ,*.mk))))
TESTS = $(MKFILES:.mk=.test)
%.test:%.mk
@make -f $?
run_tests: $(TESTS)
上面的操作很好,但我正在尝试更改它,以便在测试出错时,它不会中止,而是继续并在最后打印出所有失败
FAILURES :=
%.test:%.mk
@make -f $? || $(MAKE) $@.error
.PHONY: %.test.error
%.test.error:
$(eval FAILURES += $@)
run_tests: $(TESTS)
@echo "Failures:" $(FAILURES)
似乎我的eval
在%.test.error
范围内无法生存,如果我将eval
移动到%.test
中,它确实能够生存,尽管这不是我想要的
有办法做到这一点吗?在以下规则的配方中:
%.test:%.mk
@make -f $? || $(MAKE) $@.error
调用make
,并创建另一个新的make
运行实例。正是在这种情况下,eval
才会发生。因此,它对执行上述配方的父make
实例没有影响
相反,当发生错误时,您可以创建true
.test.error
文件:
%.test:%.mk
@make -f $? || touch $@.error
完成后将其移除:
run_tests: $(TESTS)
@echo "Failures:" $(FAILURES)
@$(RM) *.test.error
故障的定义可以是:
FAILURE = $(wildcard *.test.error)
这样,当执行run\u tests
recipe时,FAILURE
将被展开(即:通过使用递归展开的变量进行延迟展开),因此它将包含.test.error
文件(如果有)的列表。当调用$(MAKE)$@.error
,它将调用MAKE的新实例,而功能
在那里设置。新值不会传播到父make
我可能建议使用临时文件/文件夹,如下所示:
.PHONY: prep
prep:
rm -rf failures;
mkdir failures;
%.test:%.mk: | prep
@make -f $? || touch failures/$@.error
run_tests: $(TESTS)
@echo "Failures:"
@cd failures && ls || true
@rm -rf failures
谢谢我想对于您来说,上一个列表的意思是:FAILURES=$(通配符*.test.error)
这实际上会推迟初始化:您是多么正确!这是一个简单的扩展变量(:=
),而递归扩展变量(=
)就是所需要的。谢谢后续问题:当我执行类似于:@echo”Failures:“$(Failures)
的操作时,它会按预期工作,但如果我执行类似于:ifneq($(Failures),)$(error以下测试失败:$(Failures))endif
的操作,则失败
似乎会在开始时进行评估,使用时不会。这是因为在解析makefile时会计算ifneq
,因此失败
也会在开始时展开。您可以创建一个额外的虚假空目标,例如:检查错误
。然后在同一个makefile上递归调用该目标的check errors
,但在命令行上传递FAILURES
变量。即:$(MAKE)check errors FAILURES=“$(FAILURES)”
。这样,第二次解析makefile时,FAILURES
具有您在计算ifneq
时希望它具有的值。