Makefile 文本处理函数(上)
GNU make提供了一系列文本处理函数:subst、patsubst、strip、findstring、filter、filer-out、sort、word、wordlist、words、fistword。接下来我们一一讲解:
subst函数
subst函数用来实现字符串的替换,将字符串text中的old替换为new
$(subst old,new,text)
编写一个Makefile,将当前目录下的所有c文件的名称xx.c转换为xx.o
.PHONY: all
SRC = $(wildcard *.c)
OBJ = $(subst .c,.o,$(SRC))
all:
@echo "OBJ = $(OBJ)"
@echo $(subst banana, apple, "banana is good, I like banana")
执行make命令,可以看到执行结果:字符串中的banana替换成了apple,SRC变量中的所有.c 替换成了 .o:
# ls
add.c add.h hello.c main.c makefile sub.c sub.h
# make
OBJ = hello.o main.o add.o sub.o
apple is good, I like apple
patsubst函数
patsubst函数主要用来模式替换:使用通配符 % 代表一个单词中的若干字符,在PATTERN和REPLACEMENT如果都包含这个通配符,表示两者表示的是相同的若干个字符,并执行替换操作。
$(patsubst PATTERN, REPLACEMENT, TEXT)
如果我们想把某个目录下的所有.c文件皆为的文件名转换为以.o皆为的目标文件名,相比subst,使用patsubst会更加方便:
.PHONY: all
SRC = $(wildcard *.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
all:
@echo "OBJ = $(OBJ)"
SRC变量中包括多个字符串,代表各个文件名,各个字符串之间使用空格隔开,使用OBJ变量保存转换后的字符串。在当前目录下直接执行make,可以看到运行结果:
# ls
add.c add.h hello.c main.c makefile sub.c sub.h
# make
OBJ = hello.o main.o add.o sub.o
在Makefile中,如果我们已经得到了需要编译的C文件,想要得到它们对应的目标文件,经常使用上面的patsubst函数进行转换。
strip函数
strip函数是一个去空格函数:一个字符串通常有多个单词,单词之间使用一个或多个空格进行分割,strip函数用来将多个连续的空字符合并成一个,并去掉字符串开头、末尾的空字符。空字符包括:空格、多个空格、tab等不可显示的字符。
.PHONY: all
STR = hello a b c
STRIP_STR = $(strip $(STR))
all:
@echo "STR = $(STR)"
@echo "STRIP_STR = $(STRIP_STR)"
执行make后的结果:
# make
STR = hello a b c
STRIP_STR = hello a b c
strip函数经常用在条件判断语句的表达式中,去掉多余的空格等因素,确保表达式比较的可靠和健壮。
ifeq ($(strip $(foo)),)
echo "foo is empty"
endif
findstring 函数
findstring函数用来查找一个字符串。使用格式如下:
$(findstring FIND, IN)
findstring函数会在字符串IN中查找“FIND”字符串,如果找到,则返回字符串FIND,否则,返回空。
.PHONY: all
STR = hello a b c
FIND = $(findstring hello, $(STR))
all:
@echo "STR = $(STR)"
@echo "FIND = $(FIND)"
执行make,运行结果为:
# make
STR = hello a b c
FIND = hello
filter 函数
filter函数用来过滤掉一个指定的字符串,使用格式如下:
$(filter PATTERN…,TEXT)
filter函数用来过滤掉字符串TEXT中所有不符合PATTERN模式的单词,只留下符合PATTERN格式的单词。
.PHONY: all
FILE = a.c b.h c.s d.cpp
SRC = $(filter %.c, $(FILE))
all:
@echo "FILE = $(FILE)"
@echo "SRC = $(SRC)"
执行make,运行结果为:
# make
FILE = a.c b.h c.s d.cpp
SRC = a.c
filter-out 函数
filer-out函数是一个反过滤函数,功能和filter函数恰恰相反:该函数会过滤掉所有符合PATTERN模式的单词,保留所有不符合此模式的单词。
.PHONY: all
FILE = a.c b.h c.s d.cpp
SRC = $(filter-out %.c, $(FILE))
all:
@echo "FILE = $(FILE)"
@echo "SRC = $(SRC)"
在上面的Makefile中,使用filter-out %.c 过滤掉所有的.c文件。执行make,运行结果为:
# make
FILE = a.c b.h c.s d.cpp
SRC = b.h c.s d.cpp