在Makefile目标内的命令内分配变量

时间:2014-01-17 12:18:28

标签: shell unix makefile autotools automake

所以我在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会返回错误。

2 个答案:

答案 0 :(得分:3)

你做不到。你必须记住,配方是在一个shell中运行,它已被调用。这是一个单独的过程,而不是在制作过程中。

shell(子进程)中发生的任何事情都无法改变make(父进程)的任何方面,例如设置make变量。一旦shell退出,它所拥有的所有信息都将丢失。从shell返回的唯一东西是最终的退出代码;这就是make决定命令是成功还是失败的方法。

执行此操作的唯一方法是将值写入文件,然后读取文件并将结果值放入make变量。

ETA:

但是,如果您只想保留shell中的退出代码(正如编辑所说),那么您根本不需要make变量。你需要一个shell变量,这很容易。另请注意,make始终调用/bin/sh这是一个POSIX shell,pushdpopd是bash shell功能,因此这个makefile不可移植。幸运的是,无论如何都不需要pushdpopd,因为工作目录(在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