一. 前言
call函数是一个可以定制化函数参数的引用函数,使用这个函数可以实现对用户自定义函数的引用。也可以将一个变量定义为一个复杂的表达式,用call函数根据不同的参数对他进行展开获得不同的结果。
eval对它的参数进行展开,展开的结果作为Makefile的一部分,eval函数根据其参数的关系,结构,对它们进行替换展开。
二. call函数
1. 定义
$(call VARIALBLE,PARAM,PARAM,...)
2. 函数功能
在执行时,将参数"PARAM"依次赋值给临时变量"$(1)","$(2)"等等,最后得到"VARIABLE"表达式的计算值。
3. 返回值
参数值"PARAM"依次替换"$(1)","$(2)"后,变量"VARIABLE"定义的表达式的计算值。
举例如下:
define test
foo:=$(1)
endef
$(warning $(call test,apple))
all:
@echo foo=$(foo).
结果:
test1.mk:8: foo:=apple
foo=.
如上可知,$(warning $(call test,apple))语句的功能是call函数调用"test"表达式,并传入"apple"后,得到"test"表达式返回的结果为"foo:=apple",注意,"foo:=apple"只是call函数的一个返回值,make在解析此Makefile时,并不会解析到"foo:=apple"这个语句。所以最后foo的值还是空的。
三. eval函数
1. 定义
$(eval ...)
2. 函数功能
函数eval对他的参数进行展开,展开的结果作为Makefile的一部分,make可以对展开的内容做语法解析。对这三句话的解析如下:
函数"eval"对它的参数进行展开:
eval函数会它后面跟着的参数进行展开,如果有间接调用其他变量的,将在此处一起展开,得到最终表达式或变量的值。举例如下:
apple_tree:=3
define test
foo:=$($(1)_tree)
endef
$(warning $(eval $(call test,apple)))
all:
@echo foo=$(foo).
结果:
test23.mk:8:
foo=3.
如上可知,"$(call test,apple)"函数返回的表达式的计算值是"foo:=$(apple_tree)"。所以此时,"foo:=$(apple_tree)"就作为了eval函数的参数,eval函数将对它进行展开操作,得到"foo:=3"语句。
展开的结果作为Makefile的一部分:
eval函数会将对它参数的展开的结果做为Makefile的一部分,也就是make在解析Makefile时会解析到这个"展开的结果"。参考上例,在eval的展开操作后,得到了"foo:=3",这是eval函数的第一步操作,接下来的操作是将"foo:=3"作为Makefile的一部分,这是第二步。
make可以对展开的内容做语法解析:
最后,make在解析Makefile后,foo的值就是3。
3. 返回值
函数"eval"的返回值为空,也可以没有返回值。
三. 总结
call函数的作用是能够函数的参数,并将函数内的表达式和变量进行展开,函数返回值是展开之后的结果,但是,展开后的结果并不是Makefile的一部分,make解析Makefile时,解析不到它。eval函数首先会对其参数进行展开操作,而后将展开的结果作为Makefile的一部分,make可以解析到该语句。