我正在学习makefile。我在理解 makefile 中 eval 的用法时遇到问题。
这是我的 Makefile:
testt:
@R=5
$(eval $(echo $R))
当我运行make testt时,没有显示任何内容。你能告诉我是什么原因吗?非常感谢。
当 make 读取你的 makefile 时,它将 shell 命令块存储testt
为单个递归扩展变量。还没有发生任何不愉快的事情。
在读入你的 makefile 之后,make 现在决定要构建什么。testt
是第一个目标,所以它有一个去。您的文件系统中没有调用testt
文件,因此 make 决定它必须运行 shell 命令块。
在这一点上,它试图扩展它之前隐藏的变量。它开始于
@R=5
$(eval $(echo $R))
首先是展开$R
。扩展是空的,留下make with
@R=5
$(eval $(echo ))
现在,它扩展了$(echo )
. 这个变量也不存在,make 已经到了
@R=5
$(eval )
Make 确实知道$(eval ...)
,但其输出始终为空。所以现在make有了
@R=5
扩展完成,make 现在将每一行分别依次传递给 shell 的新调用,检查每个的返回码。所以,shell 看到R=5
. 此命令(对shell变量的简单赋值)完成且没有错误。@
由于前缀,Make 不会将其回显到标准输出。全部做完。
始终使用--warn-undefined-variables
.
$ make --warn-undefined-variables
Makefile:3: warning: undefined variable `R'
Makefile:3: warning: undefined variable `echo '
make: Nothing to be done for `testt'.
(请注意变量名末尾的额外空格:(`echo '
是的,您可以使用包含空格的变量名)。)
哦,虽然我在使用它,但它$(eval ...)
确实很有用,但不要在 shell 命令中使用它。这很少有意义。
我不知道 stackoverflow 是您在此处查找的信息级别的最佳位置。最好回答具体问题,但基于这个例子,你需要先获得一些更基本的理解。
仅供参考,测试中的第一行是设置shell变量R
。然后该行结束,从该 shell 调用中退出,现在您的变量设置丢失了。然后在下一行中,您通过引用访问make变量。那从来没有在任何地方设置过,所以总是一个空字符串。然后您尝试将其提供给 make 函数,但 make 中没有这样的函数,因此也可以扩展为空字符串。然后将生成的空字符串传递给函数,并评估空字符串会产生另一个空字符串,然后将其作为运行命令提供给 shell,它什么都不做。R
$R
$(echo ...)
$(eval ...)
如果您想问一个特定的问题(“我如何做 XYZ?”),那么我们可以给出答案……但在这个级别上需要 GNU make 手册的重要部分来提供帮助。你也可以在 help-make@gnu.org 邮件列表上提问。
指示评估在 makefile 评估中使用带有“shell”命令的 shell $(shell xxx)
。
不知道为什么需要这样做,但 Makefile 与命令行不同 - 可移植性,但如果这不是问题,则使用 shell 指令。
$(eval $(shell echo $R))
参考“使用 GNU make 管理项目”,O'Reilly,2004,第三次添加,第 89 页:
$(eval $(shell echo Shell echo 1>&2))