Makefile学习之路6————通过函数增强功能
通过函数能显著增强Makefile的功能。对于simple项目的Makefile,尽管使用了模式规则,但还是有一件比较麻烦的事情,就是要在Makefile中指明每一个项目源文件。下面介绍几个后期会使用到的函数,更多请参考《GUN Make》。
1.abspath函数
从命名就应该能够猜出它的作用。abspath函数用于将_name中的各路径名转化成绝对路径,并将转化后的结果返回。调用形式为:
$(abspath _name)
.PHONY: all root :=$(abspath /uer/../lib) all: @echo $(root)
2.addprefix函数
addprefix函数用于给名字列表_names中的每一个名字增加前缀_prefix,并将增加了前缀的名字列表返回,调用形式为:
$(addprefix _prefix, _names)
.PHONY: all without_dir=main.c foo.c with_dir :=$(addprefix objs/,$(without_dir)) all: @echo $(with_dir)
3.addsuffix函数
和前面addprefix刚好相反,addsuffix函数用于给名字列表_names中的每一个名字增加后缀_suffix,调用形式为:
$(addsuffix _suffix, _names)
.PHONY: all without_dir=main foo with_dir :=$(addsuffix .c,$(without_dir)) all: @echo $(with_dir)
4.filter函数
filter函数被用于从一个名字列表_text中根据模式_patterm得到满足需要的名字列表并返回,其形式是:
$(filter _pattern,_text)
.PHONY: all sources =foo.o bar.c main.c hell.s
sources :=$(filter %.c %.s,$(sources)) all: @echo $(sources)
从结果来看,调用filter函数后source变量中只存在.c文件和.s文件,而.o文件因为不满足所指定的模式而被过滤掉了。
5.eval函数
eval函数的存在使得Makefile具有动态语言的特征。eval函数使得make将再一次解析_text语句。eval返回空字符串,调用形式为:
$(eval _text)
.PHONY: all sources =foo.o bar.c main.c hell.s $(eval sources :=$(filter %.c %.s,$(sources))) all: @echo $(sources)
虽然它和上面第四个函数运行结果完全一样,但是在某些场合却必须用eval。
可参考:http://bbs.chinaunix.net/thread-2321462-3-1.html
eval的二次展开,是递归的一种形式,因为有时候在Makefile的表达式中,最后得出来的可能还是Makefile的表达式而非真正我们想要传递的值,需要再展开Makefile的表达式得到最终的结果。
6.filter-out函数
该函数用于从名字列表_text中根据模式_pattern滤除一部分名字并将滤除后的列表返回,其形式为:
$(filter-out _pattern,_text)
.PHONY: all objs =foo.o main.o main1.o main2.o result :=$(filter-out main%.o,$(objs)) all: @echo $(result)
7.notdir函数
该函数用来从路径_name中抽取文件名,并将文件名返回。其形式为:
$(notdir _name)
.PHONY: all file_name :=$(notdir c/d/e/f/a.c q/w/e/r/b.c) all: @echo $(file_name)
8.patsubst函数
该函数用来将名字列表_text中符合_pattern模式的名字替换成_replacement,并将替换后的名字列表返回。其形式为:
$(patsubst _pattern,_replacement,_text)
.PHONY: all mixed=foo.c bar.c main.o objs :=$(patsubst %.c,%.o,$(mixed)) all: @echo $(objs)
、
9.realpath函数
该函数用于获取_name所对应的真实路径名。其形式为:
$(realpath _name)
.PHONY: all root :=$(realpath ./) all: @echo $(root)
10.strip函数
如果希望清除名字列表中的多余空格,strip函数是最佳选择,它将_string中的多余空格去除后返回。其形式为:
$(strip _string)
.PHONY: all ori=foo.c main.c res:=$(strip $(ori)) all: @echo "$(ori)" @echo "$(res)"
这里对echo命令做了一点变动,细心的人已经发现加了一个双引号,如果不加双引号,这里的两个输出将是相同的。
双引号用于保持引号内所有字符的字面值(回车和空格也不例外)。
11.wildcard函数
该函数是通配符函数,通过它可以得到当前工作目录中满足_pattern模式的文件或目录名列表。其形式为:
$(wildcard _pattern)
.PHONY:all srcs=$(wildcard *.c) all: @echo $(srcs)
有了上面函数的基础之后,我们来看看之前的simple项目,对它进行改进:
之前的代码:
.PHONY: clean CC = gcc RM = rm EXE =simple OBJS =main.o foo.o $(EXE): $(OBJS) $(CC) -o $@ $^ %.o : %.c $(CC) -o $@ -c $^ clean: $(RM) -rf $(EXE) $(OBJS)
还是要手动添加源文件,麻烦,运用函数之后,改进如下:
.PHONY: clean CC = gcc RM = rm EXE =simple SRCS =$(wildcard *.c) OBJS =$(patsubst %.c, %.o, $(SRCS)) $(EXE): $(OBJS) $(CC) -o $@ $^ %.o : %.c $(CC) -o $@ -c $^ clean: $(RM) -rf $(EXE) $(OBJS)
此时我们增加一个源文件,touch bar.c,看看我们的Makefile需不需要修改。
从结果看,不用修改Makefile就可以增加源文件了,同理,删除也一样,这样的Makefile具有更好的鲁棒性。
欢迎加入作者的小圈子
扫描下方左边二维码加入QQ交流群,扫描下方右边二维码关注个人微信公众号并,获取更多隐藏干货,QQ交流群:859800032 微信公众号:Crystal软件学堂
作者:Liu_Jing bilibili视频教程地址:https://space.bilibili.com/5782182 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在转载文章页面给出原文连接。 如果你觉得文章对你有所帮助,烦请点个推荐,你的支持是我更文的动力。 文中若有错误,请您务必指出,感谢给予我建议并让我提高的你。 |