在 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 换行符。
如果我有以下 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 换行符。