我有这样的 make 文件目标foo: i = 1 @echo $(i) 当我运行这样的 make 文件时:$ make foo i = 1make: i: 未找到命令Makefile:2: 目标“foo”的配方失败make...
我已经像这样制作文件目标
foo:
i = 1
@echo $(i)
当我像这样运行 make 文件时:
$ make foo
i = 1 make:i:未找到命令 Makefile:2:目标“foo”的配方失败 make:[foo] 错误 127
但如果我在作业中没有留空格(即
i=1
然后没有错误但没有输出,i 的值没有打印
参数 i
和 =
运行命令 2
。shell 中的正确赋值 在等号两边没有空格。
您的第二个问题是,两个物理行上的配方将运行两个不相关的 shell 实例。第一个将变量设置为一个值,然后退出并丢失该变量。第二个不相关的实例不知道第一个实例做了什么,当然也没有变量赋值的痕迹。解决这个问题的方法是将两者逻辑上合并为一行(您仍然可以将行拆分为几行物理行,只要它们之间有分号):
foo:
i=1; \
echo "$${i}"
还请注意,我们需要将美元符号加倍,以防止 make
对其进行解释;以及 在 shell 中正确使用引号括住字符串。 (在这个特定情况下,我们知道字符串不包含任何 shell 元字符;但许多初学者也会遇到这个问题。)
另外,GNU Make 允许您指定 .ONESHELL
,强制在单个 shell 实例中评估配方中的所有命令;
.ONESHELL:
foo:
i=1
echo "$${i}"
(命令替换,尝试运行命令 $(i)
并将其标准输出插入到下一步将执行的命令行的一部分)和 i
(变量插值,也可以写成 ${i}
之间的区别 $i
使用圆括号来表示 make
确实令人困惑 make
;但同样,这是一个 shell 变量。简而言之,前面带有制表符的所有内容都由 shell 进行评估(但如果它包含 make
变量,或者在 GNU Make 中,包含函数调用,则将首先评估这些变量)。