我正在学习makefile。我在理解makefile中使用eval时遇到了问题。
这是我的Makefile:
testt:
@R=5
$(eval $(echo $R))
当我运行 make testt 时,不会显示任何内容。 你能告诉我是什么原因吗?非常感谢。
答案 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))