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
《Makefile工程实践》视频教程,一线开发工程师独家录制,网上首家讲解Makefile的实战课程。从零开始,教你一步一步编写一个工程项目的Makefile,支持使用第三方静态库、动态库,支持指定模块或目录编译生成静态库、动态库,赠送企业级的Makefile模板,学完即可拿来使用,投入项目开发实战,具备独立开展项目开发和管理的能力。详情请点击淘宝链接:Linux三剑客