Make编译学习笔记(四)常用函数

来源:互联网 发布:十大收银软件 编辑:程序博客网 时间:2024/05/10 14:55

Makefile 中可以使用函数来处理变量,调用方式如下

$(foo a, b, c)

其中 foo 是函数名 a, b, c 是函数参数

make 编译中常用函数如下

字符串操作函数

函数名 原型 字符串替换函数 $(subst <from>, <to>, <text>) 模式字符串替换函数 $(patsubst <pattern>, <replacement>, <text>) 字符串去空格函数 $(strip <string>) 字符串查找函数 $(findstring <find>, <in>) 字符串过滤函数 $(filter <pattern...>, <text>) 字符串反过滤函数 $(filter-out <pattern...>, <text>) 字符串排序函数 $(sort <list>) 取单词串函数 $(wordlist <s>, <e>, <text>) 统计单词数函数 $(words <text>) 取首单词函数 $(firstword <text>)

1. 字符串替换函数是将 < text > 字符串中的 < from > 子串替换为 < to > 串并返回,例如

$(subst .c, .o, foo.c bar.c.c)

此时函数的返回值为 foo.o bar.o.o
2. 模式字符串替换函数是查找 < text >中的单词符合模式 < pattern >的子串替换为 < replacement > 串并返回,例如

$(subst %.c, %.o, foo.c bar.c.c)

此时函数的返回值为 foo.o bar.c.o,对比 subst 函数即可发现区别
3. 字符串去空格函数是去掉 < string > 中开头和结尾的空格后返回,注意串中的空格是不会去掉的
4. 字符串查找函数是在字符串 < in > 中查找 < find > 子串如果有返回 < find > 子串,若没有返回空
5. 字符串过滤函数是以 < pattern > 模式过滤 < text > 字符串中的单词,保留符合模式 < pattern > 的单词作为值返回,< pattern > 可以有多个用空格隔开,例如

$(filter %.c %.h, foo.c foo.h bar.cpp bar.h)

此时函数的返回值为 foo.c foo.h bar.h
6. 字符串反过滤函数的作用正好同 filter 函数相反,去掉符合模式 < pattern… > 的单词作为值返回,例如

$(filter-out %.c %.h, foo.c foo.h bar.cpp bar.h)

此时函数的返回值为 bar.cpp
7. 字符串排序函数是把 < list > 中的单词以升序排序,并且去掉相同单词后返回
8. 取单词函数是返回字符串 < text > 中第 < n > 个单词,如果 < n > 比单词数大,则返回空
9. 取单词串函数是返回字符串 < text > 中从 < s > 开始到 < e > 的单词串,< s >和 < e > 是一个数字,如果 < s > 比单词数大,那么返回空,如果 < e > 比单词数大,那么返回从 < s > 开始到结束的单词串。
10. 统计单词数函数是返回统计 < text > 字符串中的单词数
11. 取首单词函数是返回字符串 < text > 中的第一个单词

文件名操作函数

函数名 原型 取目录函数 $(dir <names...>) 取文件函数 $(notdir <names...>) 取后缀函数 $(suffix <names...>) 取前缀函数 $(basename <names...>) 加后缀函数 $(addsuffix <suffix>, <names...>) 加前缀函数 $(addprefix <prefix>, <names...>) 连接函数 $(join <list1...>, <list2...> )

1. 取目录函数是从文件名序列 < names… > 中取出目录部分,目录部分是指最后一个反斜杠之前的部分。如果没有反斜杠,那么返回 ./
2. 取文件函数是从文件名序列 < names… > 中取出非目录部分,非目录部分是指最后一个反斜杠之后的部分
3. 取后缀函数是从文件名序列中取出各个文件名的后缀
4. 取前缀函数是从文件名序列中取出各个文件名的前缀
5. 加后缀函数是把后缀 < suffix > 加到 < names… > 中的每个单词后面,例如

$(addsuffix .c, foo bar)

此时函数的返回值为 foo.c bar.c
6. 加前缀函数把前缀 < prefix > 加到 < names… > 中的每个单词后面1,例如

$(addprefix src/, foo bar)

此时函数的返回值为 src/foo src/bar
7. 连接函数是把 < list2… > 中的单词对应地加到 < list1… > 的单词后面。如果 < list1… > 的单词个数要比 < list2… > 多那么,< list1… > 中的多出来的单词将保持原样。如果 < list2… > 的单词个数要比 < list1… >多那么,< list2… > 多出来的单词将被复制到 < list2… > 中,例如

$(join aaa bbb , 111 222 333)

此时函数的返回值为 aaa111 bbb222 333

foreach 函数

$(foreach <var>, <list>, <text>)

这个函数的作用类似于迭代器
是把参数 < list > 中的单词逐一取出放到参数 < var > 所指定的变量中,然后再执行 < text > 所包含的表达式,每一次 < text > 会返回一个字符串,循环过程中,< text > 的所返回的每个字符串会以空格分隔,最后当整个循环结束时,< text > 所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值,例如

names := foo barfiles := $(foreach n,$(names),$(n).o)

foreach函数会把 names 中的单词依次赋值给 $(n),再做 $(n).o 操作得到 foo.o 和 bar.o 每个值都以空格隔开作为最后的返回值,所以函数的返回值为 foo.o bar.o

if 函数

$(if <condition>, <then-part>) $(if <condition>, <then-part>, <else-part>)

if 函数的参数可以是两个,也可以是三个取决于是否包含 else
< condition > 参数是if的表达式,如果其返回的为非空字符串,那么这个表达式就是真,于是返回 < then-part > ,否则返回 < else-part >,所以 < then-part > 和 < else-part > 只会有一个被计算。

call 函数

$(call <expression>, <parm1>, <parm2>...)

call 函数是唯一一个可以用来创建新的参数化的函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用call函数来向这个表达式传递参数。当make执行这个函数时,< expression >参数中的变量,如 $(x),$(y) 等,会被参数 < parm1 >,< parm2 > 依次取代。而 < expression > 的返回值就是 call 函数的返回值。例如:

reverse = $(x) $(y)z = $(call reverse, foo, bqr)

则 z 的值就是 foo bar

origin 函数

$(origin <variable>)

origin函数作用是返回变量的类型,注意 < variable > 是变量的名字,不应该是引用。所以最好不要在 < variable > 中使用“$”字符。origin函数的返回值如下表

返回值 变量类型 undefined 变量没有定义 default 变量是一个默认的定义,如$(CC) environment 变量是一个环境变量,且当Makefile被执行时 -e 参数没有被打开 file 变量在Makefile文件中定义 command line 变量在命令行中定义 override 变量被override指示符重新定义 automatic 变量是一个命令运行中的自动化变量。

shell 函数

$(shell <command>)

shell函数顾名思义,它的参数是Shell的命令,会把执行命令后的输出作为返回值。例如

files := $(shell echo *.c)

flies 的值即为所有的 .c 文件,注意这个函数会新生成一个Shell进程来执行命令,所以你要注意其运行性能,如果你的Makefile中有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统性能是有害的。特别是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你想像的多得多。

make控制函数

$(error <text ...>)$(warning <text ...>)

< text … > 是错误或警告的信息,这两个函数可以控制make的运行,通常需要检测运行Makefile时的运行时信息,并且根据这些信息来决定,你是让make继续执行,还是停止
error 函数可以产生一个错误输出一段错误信息,并终止 make 运行
warning 函数可以产生一个警告输出一段警告信息,但不会终止 make 运行


  1. 然而我也没有弄明白加前缀函数和加后缀函数的区别,是对单词列表有过滤,还是链接时有什么不同的规则吗,有木有大神指点下呀 ↩
0 0
原创粉丝点击