现在的位置: 首页 > 综合 > 正文

makefile 里的 eval 函数 .

2018年04月16日 ⁄ 综合 ⁄ 共 1428字 ⁄ 字号 评论关闭
函数原型 $(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文件来测试和学习

抱歉!评论已关闭.