在上一篇文章中,尽管使用了变量和模式,但还是有不够好的地方,在Makefile中要指明每一个源文件,我们接下来利用函数对其进行优化,并介绍其他常用的一些函数。
依旧是以fun.c ,main.c 和Makefile三个文件为例,文件内容就不再贴出来了,前两篇文章中都有。
wildcard是通配符函数,通过它可以得到当前工作目录中满足 _pattern模式的文件或目录名列表。
格式为:$(wildcard _pattern)
.PHONY:all SRC = $(wildcard *.c) all: @echo $(SRC)
运行make
fun.c main.c
patsubst 函数被用来将名字列表 _text中符合 _pattern模式的名字替换为 _replacement,并将替换后的名字列表返回。
格式为:$(patsubst _pattern, _replacement , _text)
.PHONY:all SRC = fun.c main.c objects := $(patsubst %.c, %.o, $(SRC)) all: @echo $(objects)
运行make
fun.o main.o
有了这个两个函数,我们可以对之前的makefile进行优化
优化前
.PHONY:clean CC = gcc RM = rm TARGET = app OBJS = main.o fun.o $(TARGET) : $(OBJS) $(CC) -o $@ $^ %.o : %.c $(CC) -o $@ -c $^ clean: $(RM) $(TARGET) $(OBJS)
优化后
.PHONY:clean CC = gcc RM = rm TARGET = app SRCS = $(wildcard *.c) OBJS = $(patsubst %.c, %.o, $(SRCS)) $(TARGET) : $(OBJS) $(CC) -o $@ $^ %.o : %.c $(CC) -o $@ -c $^ clean: $(RM) $(TARGET) $(OBJS)
abspath函数被用于将 _names中的各路径名转换成绝对路径,并将转换后的结果返回。
格式为:$(abspath _names)
.PHONY:all ROOT := $(abspath /usr/../lib) all: @echo $(ROOT)
运行make
/lib
addprefix函数被用于给名字列表 _names中的每一个名字增加前缀 _prefix,并将增加了前缀的名字列表返回。
格式为:$(addprefix _prefix, _names)
.PHONY:all without_dir := fun.c main.c with_dir := $(addprefix objs/, $(without_dir)) all: @echo $(with_dir)
运行make
objs/fun.c objs/main.c
addsuffix函数被用于给名字列表 _names中的每一个名字增加后缀 _suffix,并将增加了后缀 _suffix的名字列表返回。
格式为:$(addsuffix _suffix, _names)
.PHONY:all without_suffix := funA funB with_suffix := $(addsuffix .c, $(without_suffix)) all: @echo $(with_suffix)
运行make
funA.c funB.c
filter函数被用于从一个名字列表 _text中根据模式 _pattern得到满足需要的名字列表并返回。
格式为:$(filter _pattern, _text)
.PHONY:all sources = fun.c main.c other.o test.h sources := $(filter %.c %.o, $(sources)) all: @echo $(sources)
# touch other.o test.h # ls fun.c main.c Makefile other.o test.h
运行make,可以看到,调用filter函数后,sources变量中只会有.c和.o的文件, .h文件不符合要求被过滤了
fun.c main.c other.o
filter-out函数被用于从名字列表 _text中根据模式 _pattern滤除一部分名字,并将滤除后的列表返回。
格式为:$(filter-out _pattern, _text)
.PHONY:all objects = funA.o funB.o fun.c main.c other.o test.h results = $(filter-out fun%.o, $(objects)) all: @echo $(results)
利用touch命令新建funA.o,funB.o文件,运行make
fun.c main.c other.o test.h
notdir函数被用来从路径 _names中抽取文件名,并将文件名返回。
格式为:$(notdir _names)
.PHONY:all file_name := $(notdir code/src/fun.c code/src/main.c) all: @echo $(file_name)
运行make
fun.c main.c
realpath函数被用于获取names所对应的真实路径名。
格式为:$(realpath _names)
.PHONY:all ROOT := $(realpath ./..) all: @echo $(ROOT)
运行make
/mnt/hgfs/Work/Makefile/3.2
10.strip函数
strip函数可以将将 _string 中的多余空格去除后返回。
格式为:$(strip _string)
.PHONY:all orginal := fun.c main.c stripped := $(strip $(orginal)) all: @echo "original = $(orginal)" @echo "stripped = $(stripped)"
运行make
original = fun.c main.c stripped = fun.c main.c
本文介绍了一些常用的函数,只要加以灵活运用,会让你的Makefile变得高效又智能。
———————————————————————————————
码字不易,点个赞再走吧!
欢迎关注我的同名公众号,这里有更多好料等着你哦!