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

Ian*_*lor 0 makefile environment-variables gnu-make

我正在尝试在运行特定目标时要求在Makefile中设置环境变量.我正在使用该问题的答案中的技术,您可以在其中设置另一个目标,以确保设置环境变量.

我看起来像这样:

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

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

$ make require-FOO
Makefile:3: *** You must pass the FOO environment variable.  Stop.
Run Code Online (Sandbox Code Playgroud)

但是,在测试时,我永远不会得到它没有错误:

$ 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.
Run Code Online (Sandbox Code Playgroud)

即使我if在目标中注释出块:

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

运行时我仍然遇到错误:

$ make require-FOO FOO=something
Makefile:3: *** You must pass the FOO environment variable.  Stop.
Run Code Online (Sandbox Code Playgroud)

我做错了什么?我怎样才能让它发挥作用?

Eta*_*ner 5

您修改了该链接答案中提供的解决方案,但未理解其中的差异.

链接的答案使用shell echoshell exit来执行消息输出和退出.

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

不同之处在于shell命令仅在shell逻辑说出它们应该执行时执行,但make函数 make运行shell命令之前执行(并且始终展开/执行).(即使在shell注释中,因为这些是shell注释.)

如果你想在shell时断言,那么你需要使用shell结构来测试和退出.像原来的答案一样.

如果您希望在配方扩展时断言,那么您需要使用make构造来测试和退出.像这样(未经测试):

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