需要在 Makefile 目标中设置环境变量

Require an environment variable to be set in a Makefile target

我试图要求在 运行 特定目标时在 Makefile 中设置环境变量。我正在使用 the answer to this question 中的技术,您可以在其中设置另一个目标来保证设置环境变量。

我的看起来像这样:

require-%:
    @ if [ "${${*}}" = "" ]; then \
        $(error You must pass the $* environment variable); \
    fi

使用该目标设置,这是预期的:

$ make require-FOO
Makefile:3: *** You must pass the FOO environment variable.  Stop.

然而,在测试时,我永远无法让它不报错:

$ make require-FOO FOO=something
Makefile:3: *** You must pass the FOO environment variable.  Stop.

$ make require-FOO FOO=true
Makefile:3: *** You must pass the FOO environment variable.  Stop.

$ make require-FOO FOO='a string'
Makefile:3: *** You must pass the FOO environment variable.  Stop.

即使我注释掉目标中的 if 块:

require-%:
    # @ if [ "${${*}}" = "" ]; then \
    #   $(error You must pass the $* environment variable); \
    # fi

我在 运行 时仍然收到错误:

$ make require-FOO FOO=something
Makefile:3: *** You must pass the FOO environment variable.  Stop.

我做错了什么?我怎样才能让它工作?

您在没有理解差异的情况下修改了该链接答案中提供的解决方案。

链接的答案使用 shell echoshell exit做消息输出和退出。

您的修改使用了 make $(error) 函数。

不同之处在于 shell 命令仅在 shell 逻辑表明它们应该执行时才执行,但是 make 函数在 之前执行 make 运行 shell 命令(并且总是 expands/executes)。 (即使在 shell 评论中,因为那些是 shell 评论。)

如果你想在 shell 时断言,那么你需要使用 shell 构造来测试和退出。喜欢原来的答案。

如果你想在配方扩展时断言这个,那么你需要使用 make constructs 来测试和退出。像这样(未经测试):

require-%:
    @: $(if ${${*}},,$(error You must pass the $* environment variable))
    @echo 'Had the variable (in make).'