如何在Makefile中使用eval

时间:2013-04-08 18:27:04

标签: bash shell makefile eval

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

这是我的Makefile:

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

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

3 个答案:

答案 0 :(得分:7)

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

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

如果你想问一个特定的问题(“我该怎么做XYZ?”),那么我们可以给出一个答案......但是这需要GNU制作手册的重要部分来帮助达到这个水平。您也可以在help-make@gnu.org邮件列表中查询。

答案 1 :(得分:6)

当make在makefile中读取时,它会将testt的shell命令块存储为单个递归扩展变量。没有发生任何不幸事件。

在你的makefile中读完之后,make现在决定要构建什么。 testt是第一个目标,所以它有一个目标。您的文件系统中没有名为testt的文件,因此决定是否必须运行shell命令块。

此时它会尝试扩展之前变得松散的变量。它从

开始
@R=5
$(eval $(echo $R))

首先是展开$R。扩展是空的,留下make with

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

现在,它扩展了$(echo )。这个变量也不存在,而make已经到了

@R=5
$(eval )

Make确实知道$(eval ...),但其输出始终为空。所以现在make has

@R=5

扩展完成后,make现在分别按顺序传递每一行到shell的新调用,检查每个的返回码。所以,shell看到R=5。此命令(对 shell 变量的简单分配)完成且没有错误。由于@前缀,Make不会将此回显到stdout。一切都完成了。

始终使用--warn-undefined-variables生成make。

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

答案 2 :(得分:-1)

通过makefile $(shell xxx)评估中的“ shell”命令指示评估使用外壳。

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

$(eval $(shell echo $R))

参考文献“使用GNU make管理项目”,O'Reilly,2004年,第三版,第89页:

$(eval $(shell echo Shell echo 1>&2))