所以我在Makefile.am
文件(automake)中有这段代码:
RUNNER = \
for asm in $${TEST_ASSEMBLIES}; do \
echo -e "Running tests on $${asm}..."; \
$(ENV_OPTIONS) $(NUNIT_CONSOLE) -nologo -noshadow $$asm; \
echo $$?; \
done
test:
@pushd $(DIR_BIN) &>/dev/null; \
export TEST_ASSEMBLIES="$(TEST_ASSEMBLIES)"; $(RUNNER); \
popd &>/dev/null;
语句echo $$?;
有效:它在测试时打印0,在失败时打印1。
但是我要做的是有一个名为GLOBAL_EXIT_CODE
的全局var或者其他东西,如果所有测试都运行良好则为0,如果任何测试失败则为1 。但是对于我的生活,我甚至无法在变量中捕获$$?
的值。我尝试了很多东西:通过简单的“VAR = $$?”导出,分配,还有+=
运算符......等等什么都没有用! :(
我想拥有变量GLOBAL_EXIT_CODE
的原因是我可以在exit $GLOBAL_EXIT_CODE
目标中执行test
,以防它的值高于零,以便获得命令make test
会返回错误。
答案 0 :(得分:3)
你做不到。你必须记住,配方是在一个shell中运行,它已被调用。这是一个单独的过程,而不是在制作过程中。
shell(子进程)中发生的任何事情都无法改变make(父进程)的任何方面,例如设置make变量。一旦shell退出,它所拥有的所有信息都将丢失。从shell返回的唯一东西是最终的退出代码;这就是make决定命令是成功还是失败的方法。
执行此操作的唯一方法是将值写入文件,然后读取文件并将结果值放入make变量。
ETA:
但是,如果您只想保留shell中的退出代码(正如编辑所说),那么您根本不需要make
变量。你需要一个shell变量,这很容易。另请注意,make
始终调用/bin/sh
这是一个POSIX shell,pushd
和popd
是bash shell功能,因此这个makefile不可移植。幸运的是,无论如何都不需要pushd
或popd
,因为工作目录(在POSIX系统中)是单个进程的特征(在本例中为shell)所以任何目录都会改变你shell中的make只影响那个shell,当shell退出时它们就消失了。
所以,尝试这样的事情:
RUNNER = \
RETURN=0; \
for asm in $${TEST_ASSEMBLIES}; do \
echo -e "Running tests on $${asm}..."; \
$(ENV_OPTIONS) $(NUNIT_CONSOLE) -nologo -noshadow $$asm \
|| RETURN=$$?; \
done
test:
@export TEST_ASSEMBLIES="$(TEST_ASSEMBLIES)"; \
$(RUNNER); \
exit $$RETURN
我真的不明白为什么要将shell变量TEST_ASSEMBLIES
设置为make变量$(TEST_ASSEMBLIES)
的值。这没有必要,但它会起作用。
答案 1 :(得分:1)
我正在将我的评论扩展为答案;这是解决问题的自动化方式,因为另一个答案侧重于普通制作。
假设您的TEST_ASSEMBLIES
是可以独立方式运行的程序列表:
TESTS = $(TEST_ASSEMBLIES)
完成。做一个make check
,您应该看到测试的摘要。默认情况下,automake将使用自己的测试驱动程序,该驱动程序运行每个测试,将输出重定向到日志文件,并打印出摘要。
如果您需要通过特殊程序运行测试,请使用LOG_COMPILER
变量:
TESTS = $(TEST_ASSEMBLIES)
LOG_COMPILER = $(NUNIT_CONSOLE)
AM_LOG_FLAGS = -nologo -noshadow
如果您需要设置环境变量(ENV_OPTIONS
是什么?),您可以使用AM_TESTS_ENVIRONMENT
。