在 makefile 中使用 call 和 eval

Use of call and eval in makefiles

如果我有以下 Makefile:

define FOO
: ;
        @echo  
endef
$(call FOO,foo,foo1)
$(eval $(call FOO,bar,bar1))

然后我得到:

tmp> make foo
foo foo1
tmp> make bar
bar bar1

这两个调用都正确扩展,正确处理参数,并作为 Makefile 的一部分进行解析。 $(eval $(call ...)) 格式在我见过的 Makefile 中似乎更受欢迎。与直接使用 $(call MACRO) 相比,这样做有什么好处?

第一个之所以有效,是因为您在第一行添加了一个额外的分号。同样,如果您将定义的命令扩展为包含不止一行,那么它将不起作用。

例如,如果你写:

define FOO
:
        @echo  
endef

这不适用于 $(call ...),但适用于 $(eval $(call ...))。同样,如果你写:

define FOO
: ;
        @echo 
        @echo 
endef

这不适用于 $(call ...),但适用于 $(eval $(call ...))

基本上,call 本身会导致 make 将整个结果视为一个单独的长行,就好像换行符被转换为空格一样(尽管这实际上并没有发生)。如果其结果是有效的 makefile 语法,那么它就可以工作。如果结果不是有效的 makefile 语法,你就输了。

另一方面,

eval 将 re-interpret call 函数的结果,以便将换行符视为实际的 makefile 换行符。