bash 如何在 Makefile 中使用 eval

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15886273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:08:28  来源:igfitidea点击:

How to use eval in Makefile

bashshellmakefileeval

提问by AlexTP

I am learning makefile. I have problem in understanding usage of eval in makefile.

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

This is my Makefile:

这是我的 Makefile:

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

when I run make testt, nothing is displayed. Could you please show me what is the reason ? Thanks a lot.

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

回答by MadScientist

I don't know that stackoverflow is the best place for the level of information you're looking for here. It's best for answering specific questions, but based on this example you need to get some much more fundamental understandings first.

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

FYI, the first line in your test is setting the shellvariable R. Then that line ends, which exits from that shell invocation, and now your variable setting is lost. Then in the next line you access the makevariable Rby referencing $R. That was never set anywhere so is always an empty string. Then you try to give that to a make function $(echo ...), but there is no such function in make so that expands to the empty string as well. Then you pass the resulting empty string to the $(eval ...)function, and evaluating the empty string results in another empty string, which is then provided to the shell as a command to run, which does nothing.

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

If you wanted to ask a specific question ("how do I do XYZ?") then we can give an answer... but it would require significant sections of the GNU make manual to help at this level. Also you can ask on the [email protected] mailing list.

如果您想提出一个特定的问题(“我如何做 XYZ?”),那么我们可以给出答案……但这需要 GNU make 手册的重要部分才能在此级别上提供帮助。您也可以在 [email protected] 邮件列表中询问。

回答by bobbogo

When make reads in your makefile, it stores the block of shell commands for testtas a single recursively expanded variable. Nothing untoward has happened yet.

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

After reading in your makefile, make now decides what to build. testtis the first target so it has a go at that. You have no file called testtin your file system, so make decides it has to run the block of shell commands.

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

At this point it tries to expand the variable that it squirreled away earlier. It starts off with

在这一点上,它试图扩展它之前松散掉的变量。它开始于

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

First is expands $R. The expansion is empty, leaving make with

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

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

Now, it expands $(echo ). This variable does not exist either, and make has got as far as

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

@R=5
$(eval )

Make does know about $(eval ...), but its output is always empty. So now make has

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

@R=5

The expansion is finished, and make now passes each line separately and sequentially to fresh invocations of the shell, checking the return code of each. So, the shell sees R=5. This command (a simple assignment to a shellvariable) completes without error. Make does not echo this to stdout due to the @prefix. All done.

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

Alwaysrun make with --warn-undefined-variables.

始终运行 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'.

(Notice that extra space at the end of the variable name: `echo '(yes, you can have variable names that include spaces).)

(请注意变量名称末尾的额外空格:(`echo '是的,您可以使用包含空格的变量名称)。

Oh, and while I'm at it, $(eval ...)is truly useful, but do not use it in shell commands. It rarely makes sense.

哦,虽然我正在$(eval ...)使用它,但它确实很有用,但不要在 shell 命令中使用它。它很少有意义。

回答by Chelton

Instruct the evaluation to use the shell with the "shell" command inside the makefile $(shell xxx)evaluation.

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

Not sure why this is required, but the Makefile differs from the command line - portability, but if this is not an issue then use the shell directive.

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

$(eval $(shell echo $R))

Reference "Managing Projects with GNU make", O'Reilly,2004, Third addition, p.89:

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

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