函数原型 $(eval text)
它的意思是 text 的内容将作为makefile的一部分而被make解析和执行。
比如这样一个makefile:
$(eval xd:xd.c a.c)
将会产生一个这样的编译
cc xd.c a.c -o xd
这样一个makefile:
define MA
aa:aa.c
gcc -g -o aa aa.c
endef
$(eval $(call MA) )
会产生一个这样的编译:
gcc -g -o aa aa.c
这样的makefile:
OBJ=a.o b.o c.o d.o main.o
define MA
main:$(OBJ)
gcc -g -o main $$(OBJ)
endef
$(eval $(call MA) )
会产生这样的编译过程:
cc -c -o a.o a.c
cc -c -o b.o b.c
cc -c -o c.o c.c
g++ -c -o d.o d.cpp
cc -c -o main.o main.c
gcc -g -o main a.o b.o c.o d.o main.o
请注意到$$(OBJ) ,因为make要把这个作为makefile的一行,要让这个地方出现$,就要用两个$,因为两个$,make才把把作为$字符。
Gnu make manual里面举了一个例子:
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%)
ALL_OBJS += $$($(1)_OBJS)
endef
$(foreach prog,$(PROGRAMS),$(eval $(call PROGRAM_template,$(prog))))
$(PROGRAMS):
$(LINK.o) $^ $(LDLIBS) -o $@
clean:
rm -f $(ALL_OBJS) $(PROGRAMS)
首先我认为$(PROGRAMS):
$(LINK.o) $^ $(LDLIBS) -o $@
这一句好像是多余的,本来在foreach 里要定义server和client的依赖对象,然后套用缺省的规则来编译目标,我在cygwin+make3.8 下不把这个注释掉会编译不过。
注释掉之后可以很好的产生 server.exe 和 client.exe。
我的理解是这样
foreach 从 PROGRAMS 依次取出 server和client
对于server 在call之后会得到:
server:$$(server_OBJS) $$(server_LIBS:%=-l%)
经过eval之后将相当于makefile里有这么一行:
server:$(server_OBJS) $(server_LIBS:%=-l%)
make执行时按照变量替换原则相当于这么一行:
server:server.o server_priv.o server_access.o -lpriv -lprotocol
所以make就会先编译这些.o文件,然后priv 和protocol 连接成server.exe
在这个makefile的基础上我写了一些简单的c文件来测试和学习。
可以在这里下载这些源码:http://download.csdn.net/detail/brooknew/4943653