5

我正在学习makefile。我在理解 makefile 中 eval 的用法时遇到问题。

这是我的 Makefile:

testt:
    @R=5
    $(eval $(echo $R))

当我运行make testt时,没有显示任何内容。你能告诉我是什么原因吗?非常感谢。

4

3 回答 3

8

当 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 命令中使用它。这很少有意义。

于 2013-04-09T10:57:11.957 回答
7

我不知道 stackoverflow 是您在此处查找的信息级别的最佳位置。最好回答具体问题,但基于这个例子,你需要先获得一些更基本的理解。

仅供参考,测试中的第一行是设置shell变量R。然后该行结束,从该 shell 调用中退出,现在您的变量设置丢失了。然后在下一行中,您通过引用访问make变量。那从来没有在任何地方设置过,所以总是一个空字符串。然后您尝试将其提供给 make 函数,但 make 中没有这样的函数,因此也可以扩展为空字符串。然后将生成的空字符串传递给函数,并评估空字符串会产生另一个空字符串,然后将其作为运行命令提供给 shell,它什么都不做。R$R$(echo ...)$(eval ...)

如果您想问一个特定的问题(“我如何做 XYZ?”),那么我们可以给出答案……但在这个级别上需要 GNU make 手册的重要部分来提供帮助。你也可以在 help-make@gnu.org 邮件列表上提问。

于 2013-04-08T18:34:08.523 回答
-2

指示评估在 makefile 评估中使用带有“shell”命令的 shell $(shell xxx)

不知道为什么需要这样做,但 Makefile 与命令行不同 - 可移植性,但如果这不是问题,则使用 shell 指令。

$(eval $(shell echo $R))

参考“使用 GNU make 管理项目”,O'Reilly,2004,第三次添加,第 89 页:

$(eval $(shell echo Shell echo 1>&2))
于 2018-12-03T14:02:49.343 回答