Bash 如何在Makefile中使用eval

Bash 如何在Makefile中使用eval,bash,shell,makefile,eval,Bash,Shell,Makefile,Eval,我正在学习makefile。我在理解makefile中eval的用法时遇到问题 这是我的生成文件: testt: @R=5 $(eval $(echo $R)) 当我运行make testt时,不会显示任何内容。 你能告诉我原因吗?非常感谢。我不知道stackoverflow是您在这里查找信息级别的最佳场所。这是回答特定问题的最佳方式,但基于此示例,您需要首先获得一些更基本的理解 仅供参考,测试的第一行是设置shell变量R。然后该行结束,退出shell调用,现在变量设置丢失。

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

这是我的生成文件:

testt:
    @R=5
    $(eval $(echo $R))
当我运行make testt时,不会显示任何内容。
你能告诉我原因吗?非常感谢。

我不知道stackoverflow是您在这里查找信息级别的最佳场所。这是回答特定问题的最佳方式,但基于此示例,您需要首先获得一些更基本的理解

仅供参考,测试的第一行是设置shell变量
R
。然后该行结束,退出shell调用,现在变量设置丢失。然后在下一行中,通过引用
$R
访问make变量
R
。它从未设置在任何位置,因此始终是空字符串。然后您尝试将其赋予make函数
$(echo…
),但make中没有这样的函数,因此也会扩展为空字符串。然后将生成的空字符串传递给
$(eval…
函数,对空字符串求值将生成另一个空字符串,然后将其作为命令提供给shell以运行,该命令不执行任何操作


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

当make在makefile中读取时,它将
testt
的shell命令块存储为单个递归扩展变量。还没有什么不愉快的事情发生

读入makefile后,make现在决定构建什么
testt
是第一个目标,因此它可以尝试这样做。您的文件系统中没有名为
testt
的文件,因此make决定必须运行shell命令块

在这一点上,它试图扩展它先前存储的变量。首先是

@R=5
$(eval $(echo $R))
首先是展开
$R
。扩展为空,留下make和

@R=5
$(eval $(echo ))
现在,它展开了
$(echo)
。此变量也不存在,make已达到

@R=5
$(eval )
Make确实知道
$(eval…
,但其输出总是空的。所以,现在让我来做吧

@R=5
扩展完成后,make现在将分别按顺序将每一行传递给shell的新调用,并检查每一行的返回代码。因此,shell会看到
R=5
。此命令(对shell变量的简单赋值)无误完成。由于
@
前缀,Make不会将其回显到标准输出。都做完了

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

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

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

$(eval $(shell echo $R))
参考“使用GNU make管理项目”,O'Reilly,2004年,第三次增补,第89页:

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

谢谢你的快速回复。我很抱歉我的新手问题,但我不明白原因是空变量。我尝试了:testt:$(eval$(echo abc)),但再一次,什么也没有显示。@PatrickDiwel:
echo
是一个shell命令,但您试图将其作为Make函数进行评估。同样,我认为stackoverflow不是解决这一级别问题的合适位置。我强烈要求你把问题转到帮助中心去-make@gnu.org邮件列表:他们有更多提供基本理解的经验。make中的
$(eval…
函数是一个非常高级的主题。如果您不清楚shell变量和make变量、shell命令和make函数之间的区别,以及它们在何时以及如何交互时使用的区别,那么理解
$(eval…
)是不现实的。@Nik Lz没有正确的表达式。正如我所指出的,配方(通常)是
$(eval…
的错误位置。OP的make片段显示了许多其他误解。我只是想用eval解决这个问题@疯狂的科学家在他的回答中涵盖了其余的部分。