Makefile类似于一门编程语言,也有相应的函数,这一章我们介绍常用的Makefile函数。
一、常用Makefile函数
在Makefile中有常用的foreach、filter、filter-out、wildcard、patsubst函数等等。
1. foreach 函数
foreach作为makefile中的函数,相当于一个循环函数。
作用: 循环处理文件列表。
语法格式:$(foreach var, list, text)
- var:局部变量
- list:文件列表,空格隔开,每一次取一个值赋值为变量var
- text:对var变量进行操作(一般会使用var变量,不然没意义),每次操作结果都会以空格隔开,最后返回空格隔开的列表。
2. filter 函数
作用:过滤掉字串“text”中所有不符合模式“pattern”的单词,保留所有符合此模式的单词。
语法格式:$(filter pattern…,text)
- pattern: 需要匹配的格式,模式中一般需要包含模式字符“%”
- text:待处理数据
3. filter-out 函数(和filter相反)
作用:过滤掉字串“text”中所有符合模式“pattern”的单词,保留删除符合此模式的单词之后的数据。
语法格式:$(filter-out pattern…,text)
- pattern: 需要匹配的格式,模式中一般需要包含模式字符“%”
- text:待处理数据
4. wildcard 函数
作用:获取具有某一特征的所有文件或者数据。
语法格式:$(wildcard pattern)
- pattern: 定义文件名的格式
5. patsubst函数
作用:从列表中取出每一个值,如果符合pattern,则替换为replacement。
语法格式:$(patsubst pattern, replacement, $(var))
- pattern: 定义文件名的格式
- replacement:替换的值
- var:需要处理的数据
二、实验
1. foreach 函数(类似于for循环)
Makefile代码:
A = a b c
B = $(foreach f, $(A), $(f).o)
all:
@echo B = $(B)
运行结果:
运行原理:
- 首先f类似于for循环的循环变量i,依次取列表A中的值,依次为a, b, c
- $ (A) 是引用A变量,$(f)是引用f的值,分别为a, b, c
- $(f).o表示将每个A中的数据添加后缀.o
- 运行后B得到一个新的列表,里面的值分别为a.o b.o c.o
- 随后就是打印B的值
2. filter和filter-out函数
Makefile代码:
A = a b c
B = $(foreach f, $(A), $(f).o)
C = a b c d/
D = $(filter %/, $(C))
E = $(filter-out %/, $(C))
all:
@echo B = $(B)
@echo D = $(D)
@echo E = $(E)
运行结果:
运行原理:
- C列表中有特殊字符 d/, 我们看出这个d多出了/,所以我们需要匹配/, 那么应该pattern写成 %/,
- $ ( C ) 是引用C变量
- 运行完后D存放的是和%/匹配的字符,也就是 d/
- E存放的就是去除和%/匹配的字符,也就是 a b c
3. wildcard 函数
Makefile代码:
A = a b c
B = $(foreach f, $(A), $(f).o)
C = a b c d/
D = $(filter %/, $(C))
E = $(filter-out %/, $(C))
files = $(wildcard *.c)
all:
@echo B = $(B)
@echo D = $(D)
@echo E = $(E)
@echo files = $(files)
运行结果:
运行原理:
- 从上图我们可以看到,当前目录下有a.c c.c main.c b.c sub.c文件
- *.c中的 * 号为通配符,表示所有以.c结尾的匹配对象,将其赋值给 files
- 最后调用@echo files = $(files) 进行打印相应的变量值。
wildcard 函数还有另外一个用法:查找当前路径下真实存在的文件。实例代码
Makefile
A = a b c
B = $(foreach f, $(A), $(f).o)
C = a b c d/
D = $(filter %/, $(C))
E = $(filter-out %/, $(C))
files = $(wildcard *.c)
files2 = a.c b.c c.c d.c e.c
files3 = $(wildcard $(files2))
all:
@echo B = $(B)
@echo D = $(D)
@echo E = $(E)
@echo files = $(files)
@echo files3 = $(files3)
运行结果:
运行原理:
- 从上图我们可以看到,当前目录下有a.c c.c main.c b.c sub.c文件
- 而 files2目录包含: a.c b.c c.c d.c e.c
- 在运行$(wildcard $(files2))后程序会在files2中提取当前目录下包含files2存在的文件。
4. patsubst函数
该函数可以完成在一个列表数据中查找匹配的字符串,用另一种格式进行替换
实例代码:
Makefile
A = a b c
B = $(foreach f, $(A), $(f).o)
C = a b c d/
D = $(filter %/, $(C))
E = $(filter-out %/, $(C))
files = $(wildcard *.c)
files2 = a.c b.c c.c d.c e.c abc
files3 = $(wildcard $(files2))
dep_files = $(patsubst %.c, %.d, $(files2))
all:
@echo B = $(B)
@echo D = $(D)
@echo E = $(E)
@echo files = $(files)
@echo files3 = $(files3)
@echo dep_files = $(dep_files)
运行结果:
运行原理:
- $(patsubst %.c, %.d, $(files2))表示在files2文件中查找所有的.c文件(%.c中的%为通配符,表示匹配.c文件),查找的对象中将.c用.d替换,没有匹配的对象不改变
- 可见dep_files的值为a.d b.d c.d d.d e.d abc