函数调用语法
函数调用很像变量的使用,是以’$'来标识的,语法如下:
$(<function> <argument>[,<argument1>,<argument2>...])
或
${<function> <argument>[,<argument1>,<argument2>...]}
- 是所要调用的函数名(详见下列函数调用)
- 是函数参数,参数之间用’,'逗号分隔开。而函数名和参数之间使用’空格’分隔开
字符串处理函数
subst(字符串替换)
- 函数名称:subst
- 函数语法:$(subst ,,
) - 函数功能:把字串
中的字符串替换成 - 函数返回:返回被替换过后的字符串
实例:
将SRC所有".c"替换成".o",再赋值给OBJ
SRC := a.c b.c d.c
OBJ := $(subst .c,.o,$(SRC))
.PHONY: all
all:
@echo $(OBJ)
输出:
a.o b.o d.o
这个函数很死板,会将上述例子中的所有".c"都毫无保留的替换成".o"。如果SRC的值"a.c.c",那么函数调用后,返回的值为"a.o.o"。
一般我们在编写makefile时,普遍都是想将后缀替换掉,显然这个函数在遇到一些特殊情况时,满足不了我们的需求。接下来所描述的函数,就能解决掉这个问题
patsubst(模式字符串替换)
- 函数名称:patsubst
- 函数语法:$(patsubst ,,
) - 函数功能:查找
中的单词(单词以"空格",“Tab”,“回车”,"换行"分隔)是否符合模式,如果匹配的话,则以替换 - 可以包括通配符"%",表示任意长度的字串
- 如果中也包含"%",中的这个"%“将是中的那个”%“所代表的字串(可以用”/“来转义,以”/%“来表示真实含义的”%"字符)
- 函数返回:返回被替换过后的字符串
实例:
将SRC所有".c"后缀替换成".o"后缀,再赋值给OBJ
SRC := a.c b.c d.c
OBJ := $(patsubst %.c,%.o,$(SRC))
.PHONY: all
all:
@echo $(OBJ)
输出结果与subst一致:
a.o b.o d.o
实例2:
将SRC所有".c"后缀替换成".o"后缀,再赋值给OBJ
SRC := .ca.c b.c.c .c/d.c
OBJ := $(patsubst %.c,%.o,$(SRC))
.PHONY: all
all:
@echo $(OBJ)
输出:
.ca.o b.c.o .c/d.o
就如我们预期的那样,只是把".c"后缀替换成了".o",前面的字符与函数调用前保持一致。这个是subst函数无法做到的一点
其他
wildcard(通配符扩展)
- 函数名称:wildcard
- 函数语法:$(wildcard <pattern…>)
- 函数功能:获取与给定之一匹配且存在的文件列表
- 通配符扩展在规则中能够自动展开。但是,不能在定义变量时或在函数的参数内部进行通配符扩展。如果你想在这些地方进行通配符扩展,你需要使用这个wildcard函数
- 函数返回:返回文件列表,文件之间用空格分隔。如果没有与匹配的文件存在,不返回任何字符
实例:
找出目录中的所有".a"和".h"文件,再赋值给SRC
先看看目录中都有哪些文件
root@debian:/home/sda4/test_xvr/debug/ak_ao# ls -l
总用量 24972
-rwxrwxrwx 1 nobody nogroup 7172 7月 20 11:37 ak_ao_demo.c
-rwxrwxrwx 1 nobody nogroup 3459 7月 20 09:55 ak_ao.h
-rwxrwxrwx 1 nobody nogroup 9150 7月 20 09:55 ak_common.h
-rwxrwxrwx 1 nobody nogroup 2185 7月 20 09:55 ak_global.h
-rwxrwxrwx 1 nobody nogroup 7810279 7月 20 15:05 Chris Medina - What Are Words.mp3
-rwxrwxrwx 1 root root 33454 7月 20 11:38 demo
-rwxrwxrwx 1 nobody nogroup 123818 7月 20 09:54 libakaudiofilter.so
-rwxrwxrwx 1 nobody nogroup 13482 7月 20 09:55 libplat_ao.a
-rwxrwxrwx 1 nobody nogroup 22114 7月 20 09:55 libplat_common.a
-rwxrwxrwx 1 nobody nogroup 4184 7月 20 09:55 libplat_thread.a
SRC := $(wildcard *.a *.h)
OBJ := *.a
.PHONY: all
all:
@echo $(SRC)
@echo $(OBJ)
输出:
libplat_ao.a libplat_common.a libplat_thread.a ak_ao.h ak_common.h ak_global.h
*.a
可以看到,SRC变量的定义使用了wildcard函数,返回了所有符合<*.a *.h>模式的文件列表。而OBJ变量的定义直接使用了通配符"*",通配符并没有展开,而是将变量直接赋值为"*.a"
实例2:
通常,我们搭配patsubst一起使用
OBJ := $(patsubst %.a,%.o,$(wildcard *.a))
.PHONY: all
all:
@echo $(OBJ)
输出:
libplat_ao.o libplat_common.o libplat_thread.o
foreach(循环)
函数名称:foreach
函数语法:$(foreach ,,
函数功能:循环把参数中的单词逐一取出放到参数
所指定的变量中,然后再执行
函数返回:每一次
实例:
将变量"SRC"设置为"DIR"指定的目录中所有.c文件的列表
将变量"OBJ"设置为"DIR"指定的目录中所有.c文件替换成.o的列表
先看看目录中都有哪些文件
.
├── Makefile
├── dir_a
│ └── a.c
├── dir_b
│ └── b.c
└── dir_c
│ └── c.c
DIR := dir_a dir_b dir_c
SRC := $(foreach dir,$(DIR),$(wildcard $(dir)/*.c))
OBJ := $(foreach dir,$(DIR),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c)))
.PHONY: all
all:
@echo $(SRC)
@echo $(OBJ)
输出:
dir_a/a.c dir_b/b.c dir_c/c.c
dir_a/a.o dir_b/b.o dir_c/c.o