插播!插播!插播!亲爱的朋友们,我们的Makefile课程上线啦!感兴趣的小伙伴可以去下面的链接学习哦~
https://edu.csdn.net/course/detail/39264
使用函数我们的Makefile可以书写的更加灵活,可以在需要的地方调用函数来处理指定的文本(需要处理的文本作为函数的参数),函数的在调用它的地方被替换为它的处理结果。函数的调用格式类似于变量的引用,以“$”开始表示一个引用。语法格式如下:
$(FUNCTION ARGUMENTS)
调用语法格式中“FUNCTION”是需要调用的函数名,它应该是make内嵌的函名。“ARGUMENTS”是函数的参数,参数和函数名之间使用若干个空格隔开。
4.1 过滤函数--filter
语法格式如下:
$(filter PATTERN, TEXT)
此函数的功能是过滤掉字符串”TEXT“中所有不符合模式”PATTERN"的单词,保留所有符合此模式的单词,可以使用多个模式。模式中一般需要包含模式字符串“%”。存在多个模式时,模式表达式之间使用空格分隔。
可见此函数返回的值为:TEXT字符串中所有符合模式PATTERN的字符串,举例说明:
source = foo.c bar.c bar.s bar.h
OBJ = $(filter %.c %.s , $(source))
all :
@echo "$(OBJ)"
此例把字符串中“foo.c bar.c bar.s bar.h”中所有不符合以.c 和.s结尾的字符串过滤掉,返回符合模式的字符串,可见函数返回值为foo.c bar.c bar.s
4.2 反过滤函数---filter-out
语法格式如下:
$(filter-out PATTERN.. , TEXT)
与上述filter函数实现功能相反,过滤掉字符串TEXT中所有符合模式PATTERN的单词,同样举上例说明:
source = foo.c bar.c bar.s bar.h OBJ = $(filter %.c %.s , $(source)) all : @echo "$(OBJ)"
此例把字符串中“foo.c bar.c bar.s bar.h”中所有符合以.c 和.s结尾的字符串过滤掉,返回不符合模式的字符串,可见函数返回值为bar.h
4.3 模式替换函数--patsubst
语法格式如下:
$(patsubst PATTERN,REPLACEMENT,TEXT)
此函数简单来说就是搜索TEXT中以空格分开的单词,并且将符合模式PATTERN替换成REPLACEMNT,参数PATTERN中可以使用模式通配符“%”来代表一个单词中的若干字符。可见此函数的返回值为:替换后的新字符串。举例说明
$(patsubst %.c ,%.o, x.c , foo.c bar.c)
此例把字符串中foo.c bar.c 中以.c结尾的单词替换以.o结尾的字符,则可见此例返回结果为“foo.o bar.o”
4.4 取文件名函数--notdir
语法格式如下:
$(notdir NAME...)
此函数功能就是从文件名NAME中取出非目录部分。目录部分是指最后一个斜线“/”之前的部分,删除所有文件名中的目录部分,只保留非目录部分。举例说明:
$(notdir src/foo.c bar.c)
此例把文件名中“src/foo.c bar.c”中的目录部分删除,返回非目录部分,可见此例返回结果为“foo.c bar.c”。
4.5 取前缀函数--basename
语法格式如下:
$(basename NAME..)
此函数功能是从NAME..中取出各个文件名的前缀部分,前缀部分指的是文件名中最后一个点号之前的部分。举例说明:
$(basename src/foo.c bar)
此例把文件名src/foo.c bar中文件名中最后一个点号之前的部分取出,可见此例返回结果为“src/foo bar"
4.6 加前缀函数--addprefix
语法格式如下:
$(addprefix PREFIX,NAMES..)
此函数的功能是为NAME中的每一个文件名添加前缀PREFIX。参数NAME是空格来分隔开文件名序列,并将PREFIX添加到此序列的每个文件名之前。
可见返回值为:以单空格分割的添加了前缀PREFIX的文件名序列。举例说明:
$(addprefix src/ , foo bar)
此条语句返回的值为:src/foo src/bar
4.7 获取匹配模式文件名函数--wildcard
语法格式如下:
$(wildcard PATTERN)
此函数的功能简单来说就是列出当前目录下所有符合模式”PATTERN“格式的文件名,并且所得到的返回值为空格分割的,存在当前目录下的所有符合模式”PATTERN“格式的文件名。举例说明:
$(wildcard *.c)
返回值为当前目录下的所有.c源文件列表
4.8 循环函数---foreach
语法结构如下:
$(foreach VAR,LIST,TEXT)
此函数的功能相当于C语言中的for循环语句,这个函数工作过程为:首先展开变量VAR和LIST,表达式TEXT先不展开。执行时把LIST中使用空格分隔开的单词依次取出,然后赋值给变量VAR,接下来再执行TEXT表达式,重复直到LIST的最后一个单词为空时结束。
举例说明:
DIRS:=a b c d
files:= $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*))
此例中,执行时先把DIRS中的单词依次取出,表达式为$(wildcard $(DIR)/*)。表达式第一次执行时,DIRS先赋值a给DIR,然后执行表达式$(wildcard $(a)/*);表达式第二次执行时,DIRS先赋值b给DIR,然后执行表达式$(wildcard $(b)/*);依次类推到DIRS的最后一个单词为空时结束,可见此例files的值为四个目录下的文件列表。
4.9 shell函数
语法结构如下:
$(shell commend)
其中,commend是要执行的shell命令。shell函数可以通过它来和外部通信,它可以让我们在makefile中执行shell命令,并将命令的输出结果返回给makefile。使用shell函数可以方便的在makefile中执行一些需要使用shell命令才能完成的操作,比如获取当前目录,在当前目录创建文件等。举例说明:
.PHONY:all
$(shell mkdir -p test)
all:
@echo "helloworld"
此例中在当前目录下创建了一个叫test的空目录,执行完make后,会发现终端在当前目录下出现了一个test新创建的目录。