makefile杂项

来源:互联网 发布:建立网站的软件 编辑:程序博客网 时间:2024/04/28 10:02

1 makefile例子:关于自定义函数调用call,函数eval,foreach用法:
例子来源
https://www.gnu.org/software/make/manual/html_node/Eval-Function.html

PROGRAMS    = server clientserver_OBJS = server.o server_priv.o server_access.oserver_LIBS = priv protocolclient_OBJS = client.o client_api.o client_mem.oclient_LIBS = protocol# Everything after this is generic.PHONY: allall: $(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)

上面函数调用中会有一次call调用和一次eval调用第一个call调用后:
比如第一个参数:server,

server:$$(server_OBJS) $$(server_LIBS:%=-l%)ALL_OBJS += $$(server_OBJS)

注意call左边那个,eval,eval字符,那么需要输入两次,,那么会将西,以及后面的东西
那么进行一次eval展开后:

server:$(server_OBJS) $(server_LIBS:%=-l%)ALL_OBJS += $(server_OBJS)由于eval是将语句展开成makefile语句,因此得到上面的语句后系统再会进行一次展开:server:server.o server_priv.o server_access.o -lpriv -lprotocol$(server_OBJS):对应server.o server_priv.o server_access.o$(server_LIBS:%=-l%):对应-lpriv -lprotocol

因为foreach有一个返回值,最后面的那个处理结果,所以,有以下几个返回项:
返回字符,二返回的字符可以有以下几个作用,:
1 直接将foreach的左边是个变量,将处理的字符给到变量
2 如果foreach的左边不接变量,并且foreach的最后一项是调用了eval函数,那么作用相当于是在直接将eval中的内容展开成一条makefile语句,直接执行,而不是字符,由于eval没有返回值,因此foreach也没有返回值
3 将字符作为命令返回,需要注意的是:
make
出现“makefile:2: * 遗漏分隔符 。 停止。”问题,原因是在编写makefile文件时:
gcc、rm、cp前面是没有用tab分割符,不能用空格

另外,上面有自定义函数,个人理解自定义函数就是相当于一个宏替换

上面的代码中在函数中使用了eval函数
eval函数的作用是将一条语句展开成一条makefile语句,函数调用:
(evalxxxxxxxxx)(函数名 参数1,参数2,…)

eval注意事项:

foreach注意事项:
最好是在foreach最后面的那个括回前面加上一个分号,网上有说可加可不加,但是不加有些地方会出问题
比如下面这个例子,想循环对几个文件夹下的目录进行编译,需要注意以下几点:
1 需要将命令包起来,再加上分号,这样作为命令处理时命令之间会有分隔,否则,当前的语句会和下一句语句连接起来
2 用括号包起来还有一个作用,foreach返回这些命令时,在第二个命令cd及后面的cd命令前面会莫名其妙的加上空格,
而作为命令其前面是不能够有空格的,只能够是tab,因此包起来后加上strip,当然,将strip放在最前面也可以,经过测试,下面的没注释的是可用的,注释掉的是不能够用的

另外,下面的例子中就不要使用eval,理论上eval是可以的,但是问题出在加上eval后后面会自动的加上空格,导致出错

ADD_DIR := coreADD_DIR += coress.PHONY : make_allmake_all:    $(foreach dirss,$(ADD_DIR),$(strip)(cd $(dirss) && make -f $(dirss).make DELS);)    $(strip)$(foreach dirss,$(ADD_DIR),(cd $(dirss) && make -f $(dirss).make DELS);)    #$(foreach dirss,$(ADD_DIR),$(strip)cd $(dirss) && make -f $(dirss).make DELS;)    #$(foreach dirss,$(ADD_DIR),$(strip)(cd $(dirss) && make -f $(dirss).make DELS))    #$(foreach dirss,$(ADD_DIR),$(eval cd $(dirss) && make -f $(dirss).make DELS);)    #$(foreach dirss,$(ADD_DIR),$(eval $(strip)(cd $(dirss) && make -f $(dirss).make DELS));)
0 0