【问题标题】:Assigning variables inside a command inside a Makefile target在 Makefile 目标内的命令内分配变量
【发布时间】:2014-01-17 12:18:28
【问题描述】:

所以我在Makefile.am 文件(自动制作)中有这段代码:

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 的全局变量,如果所有测试运行良好,则为 0,如果 任何 测试失败,则为 1。但是对于我的生活,我什至无法在变量中捕获$$? 的值。我尝试了很多事情:通过简单的“VAR = $$?”导出、分配,还使用+= 运算符......等等。没有任何效果! :(

我想要一个变量GLOBAL_EXIT_CODE 的原因是我可以在test 目标中执行exit $GLOBAL_EXIT_CODE,以防它的值大于零,以便让命令make test 返回错误.

【问题讨论】:

  • 为什么不使用 automake 的内置测试套件支持?
  • 你能详细说明一下吗?提供一个记录在案的 URL?
  • 手册在这里:gnu.org/software/automake/manual/html_node/Tests.html 这可能只是简单地指定一个TESTS 变量(而不是TEST_ASSEMBLIES)和一个自定义LOG_DRIVER 或LOG_DRIVER(可能是什么你的RUNNER 确实)。

标签: shell unix makefile autotools automake


【解决方案1】:

你不能那样做。您必须记住,配方在 make 调用的 shell 中运行。这是一个单独的过程,而不是在制作过程中。

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

这样做的唯一方法是将值写入文件,然后让 make 读取文件并将结果值放入 make 变量中。

预计到达时间:

但是,如果您只想在 shell 中保留退出代码(正如您的编辑所说),那么您根本不需要 make 变量。你需要一个 shell 变量,这很容易。另外,请注意make 总是调用/bin/sh 这是一个POSIX shell,而pushd 和popd 是bash shell 功能,所以这个makefile 是不可移植的。幸运的是,无论如何都没有必要执行pushd 或popd,因为工作目录(在 POSIX 系统中)是单个进程(在本例中为 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) 的值。这不是必需的,但它会起作用。

【讨论】:

  • 编辑问题以添加有关 GLOBAL_EXIT_CODE 动机的信息
【解决方案2】:

我正在将我的评论扩展为答案;这是解决问题的自动制作方法,因为另一个答案侧重于普通制作。

假设您的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。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 2011-02-12
    • 2011-01-23
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多