如何在makefile中使用eval函数?

Y.L*_*.L. 9 linux makefile

在手册中:

eval函数非常特殊:它允许您定义不是常量的新makefile构造; 这是评估其他变量和函数的结果.扩展eval函数的参数,然后将该扩展的结果解析为makefile语法.

重要的是要意识到eval参数扩展了两次; 首先通过eval函数,然后在将它们解析为makefile语法时再次扩展该扩展的结果.这意味着在使用eval时,您可能需要为"$"字符提供额外的转义级别.

"扩大两次"让我感到困惑.

例如,我创建一个makefile:

define func
    tmp = $(OBJPATH)/$(strip $1)
    objs += $$(tmp)
    $$(tmp) : $2
        gcc $$^ -o $$@
endef

all : foo

$(eval $(call func, foo, 1.c))    
Run Code Online (Sandbox Code Playgroud)

如何扩展eval功能?

Mad*_*ist 19

理解它的最简单方法是用信息替换eval:

$(info $(call func, foo, 1.c))
Run Code Online (Sandbox Code Playgroud)

这将显示第一次扩展的结果作为输出,因此您可以看到实际将解析的make.您没有提供OBJPATH变量的值,但如果是obj例如那么在您的情况下,第一个扩展(调用函数)会导致:

tmp = obj/foo
objs += $(tmp)
$(tmp) : 1.c
    gcc $^ -o $@
Run Code Online (Sandbox Code Playgroud)

然后make解析器将对此进行评估,并在此过程中它将再次展开它,因此$(tmp)扩展了类似的东西.

  • 我不确定我是否理解这个问题,但我认为答案是“不”。所有 GNU make 扩展总是以相同的方式工作:首先扩展最里面的宏,然后使用其结果扩展下一层,等等。因此对于 `$(eval $(call ...))` _first_ `$(call ...)` 被展开,然后其结果被用作 `$(eval ...)` 的参数。 (2认同)