如何在 Makefile 中包含 bash 间接变量赋值

如何在 Makefile 中包含 bash 间接变量赋值

bash 中的间接变量设置可以像所以:

#!/bin/bash
foo=bar
ind=foo
echo ${!ind}   # prints `bar'

尝试与 (GNU) Makefile 配方一样运行

# Makefile
test:
    foo=bar
    ind=foo
    echo $$\{!ind\}
    echo $${!ind}

无论是否转义{}字符都会失败,并显示以下消息:

foo=bar
ind=foo
echo $\{!ind\}
${!ind}
echo ${!ind}
/bin/sh: 1: Bad substitution
/tmp/Makefile:2: recipe for target 'test' failed
make: *** [test] Error 2

问题可能是 Makefile 的特殊字符丢失/错误转义。

或者它可能是变量扩展的顺序/时间,请参阅make的二次扩展

有任何想法吗?

如果重要的话,这是 bash4.4.12(1)-release和 makeGNU Make 4.1

答案1

你们真是太不可思议了。在我发布问题后不到十分钟,您就引导我找到了正确的解决方案,即:

# Makefile
SHELL=/bin/bash
test:
    foo=bar; \
    ind=foo; \
    echo $${!ind}

谢谢 Steeldriver,谢谢 Choroba。

答案2

这里有两个问题:

  1. 用于菜谱的默认 shell 是 a sh,因此您需要使用SHELL=/bin/bash菜谱才能理解类似语法${!ind}
  2. 配方中的每一行都由单独的 shell 执行,因此,如果您在配方中定义变量,则同一配方的下一行会丢失该变量。这是通过.ONESHELL特殊目标解决的

所以工作示例如下所示:

# Makefile
.ONESHELL:
SHELL=/bin/bash
test:
    foo=bar
    ind=foo
    echo $$\{!ind\}
    echo $${!ind}

有关更详细(和官方)的解释,请访问 https://www.gnu.org/software/make/manual/make.html#Execution

相关内容