8.8 eval函数
¾ 函数功能: 函数“ eval”是一个比较特殊的函数。使用它可以在Makefile中构
造一个可变的规则结构关系(依赖关系链),其中可以使用其它变量和函数。
函数“ eval”对它的参数进行展开,展开的结果作为Makefile的一部分, make
可以对展开内容进行语法解析。展开的结果可以包含一个新变量、目标、隐含
规则或者是明确规则等。也就是说此函数的功能主要是:根据其参数的关系、
结构,对它们进行替换展开。
¾ 返回值: 函数“ eval”的返回值时空,也可以说没有返回值。
¾ 函数说明:“ eval”函数执行时会对它的参数进行两次展开。第一次展开过程
发是由函数本身完成的,第二次是函数展开后的结果被作为Makefile内容时由
make解析时展开的。明确这一过程对于使用“ eval”函数非常重要。理解了函
数“ eval”二次展开的过程后。实际使用时,如果在函数的展开结果中存在引
用(格式为: $(x)),那么在函数的参数中应该使用“ $$”来代替“ $”(参考 6.1
变量的引用 一节)。因为这一点,所以通常它的参数中会使用函数“ value” 来
取一个变量的文本值。
我们看一个例子。例子看起来似乎非常复杂,因为它综合了其它的一些概念和函数。
不过我们可以考虑两点:其一,通常实际一个模板的定义可能比例子中的更为复杂;其
二,我们可以实现一个复杂通用的模板,在所有Makefile中包含它,亦可作到一劳永逸。
相信这一点可能是大多数程序员所推崇的。
示例:
# sample Makefile
PROGRAMS = server client
server_OBJS = server.o server_priv.o server_access.o
server_LIBS = priv protocol
client_OBJS = client.o client_api.o client_mem.o
client_LIBS = protocol
# Everything after this is generic
.PHONY: all
all: $(PROGRAMS)
#函数模板定义(自定义函数)
define PROGRAM_template
$(1): $$($(1)_OBJS) $$($(1)_LIBS:%=-l%) #$$($(1)_LIBS:%=-l%)为简单的替换,将$($(1)_LIBS)替换为 -l$($(1)_LIBS)
ALL_OBJS += $$($(1)_OBJS)
endef
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
#展开为:
#server : $(server_OBJS) –l$(server_LIBS)
#client : $(client_OBJS) –l$(client_LIBS)
#
$(PROGRAMS):
$(LINK.o) $^ $(LDLIBS) -o $@ #“ $(LINK.o)”为“ $(CC) $(LDFLAGS)”,意思是对所有的.o文件和指定的库文件进行
#链接。可参考 10.2 make隐含规则一览 一节
clean:
rm -f $(ALL_OBJS) $(PROGRAMS)
来看一下这个例子:它实现的功能是完成“ PROGRAMS”的编译链接。例子中
“ $(LINK.o)”为“ $(CC) $(LDFLAGS)”,意思是对所有的.o文件和指定的库文件进行
链接。可参考 10.2 make隐含规则一览 一节
“ $(foreach prog,$(PROGRAM),$(eval $(call PROGRAM_template,$(prog))))”展开为:
server : $(server_OBJS) –l$(server_LIBS)
client : $(client_OBJS) –l$(client_LIBS)
参考:《Makefile编程.pdf》