说明
本小节所有实例主要采用Linux-Kernel-4.13中的首Makefie源码片断,未采用部分,在案例中备注了源码出处
实现中Makefile文件路径为:/opt/linux-kernel/linux-kernel-4.13/linux-4.13
一、条件判断语句
1.1 ifeq 判断条件是否相等,相等则向下执行
1、语法:
ifeq (<argv1> , <argv2>) #最常用
ifeq '<argv1> , <argv2>'
ifeq "<argv1> , <argv2>"
ifeq '<argv1> ' "<argv2>"
ifeq "<argv1> " '<argv2>'
2、举例
# origin是一个Makefile文件中的函数,在这里的功能是判断变量V是否在命令行中定义,
# 如下定义了,则返回command line
#即如下ifeq功能:判断使用make命令时,是否定义了变量V,
# 如果定义了变量V,则将V的值赋值给变量KBUILD_VERBOSE
ifeq ("$(origin V)", "command line")
KBUILD_VERBOSE = $(V)
endif
1.2 ifneq 判断条件是否不相等,不相等则向下执行
1、语法:
ifneq (<argv1> , <argv2>) #最常用
ifneq '<argv1> , <argv2>'
ifneq "<argv1> , <argv2>"
ifneq '<argv1> ' "<argv2>"
ifneq "<argv1> " '<argv2>'
2、举例
#CURDIR变量的值为(Makefile文件当前路径):
# /opt/linux-kernel/linux-kernel-4.13/linux-4.13
#MAKEFLAGS变量的值为:
# -rR -I/opt/linux-kernel/linux-kernel-4.13/linux-4.13 --no-print-directory
#filter-out是一个反过滤函数,
# 语法:$(filter-out <规则> <字符串>
# 其功能是:根据规则,反过虑字符串中的内容,即,返回不满足规则的字符串
# 即处理结果为:-rR -I/opt/linux-kernel/linux-kernel-4.13/linux-4.13
#findstring是一个查找函数:
# 语法:$(findstring <字符串A> <字符串B>
# 其功能是:在字符串B中查找字符串A
# 返回值:如果找到,返回字符串A,否则返回空
# 即判断filter-out反过滤后的字符串中是否包含s,如果包含s,则返回s,否由返回空
MAKEFLAGS += -rR --include-dir=$(CURDIR)
ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),) #经上述分析,表达式为:ifneq( , ) ,即argv1是否为空,如果不为空,向下执行
quiet=silent_
tools_silent=s
endif
#省略更多.............
MAKEFLAGS += --no-print-directory
1.3 ifdef 判断某个变量的值是否为空,非空向下执行
1、语法:
ifdef <变量>
2、举例:
1.4 ifndef 判断某个变量的值是否为空,为空向下执行
1、语法:
ifndef <变量>
2、举例
#功能:判断KBUILD_VERBOSE值是否为空,
# 如果为空,则执行KBUILD_VERBOSE = 0
ifndef KBUILD_VERBOSE
KBUILD_VERBOSE = 0
endif
二、字符串处理函数
2.1、subst字符串替换函数
1、语法:$(subst <'from> , <'to> , <'text>)
2、功能:用字符串to替换字符串from
3、举例:
# $(subst :, ,$(CURDIR))
# 功能:检查$(CURDIR)字符串中是否有字符 ' : ',如果有,就替换为空格
# $(words <text>)
功能:统计字符串单词的个数,即以空隔分开为一个单词
#ifneq 功能:
# 首先使用subst判断绝对路径是否为合规路,如果为合规路径,则不会出现subst匹配成功的情况
# 再使用words函数计算单词个数,如果subst函数没有匹配功能,绝对路径的字符串中为会有空隔
# 此时单词数为 1
# 最后通过ifneq判断是否为1,如果不为1,向下执行,即报错
ifneq ($(words $(subst :, ,$(CURDIR))), 1)
$(error main directory cannot contain spaces nor colons)
endif
2.2、patsubst模式字符串替换函数
1、语法:$(patsubst <匹配内容> , <'to> , <'text>)
2、功能:将字符串text中的满足”匹配内容“的字符串替换成字符串to
3、举例:
# patsubst -Wl$(comma)%,%,
# 功能 :
# 将 :-Wl$(comma)--build-id 替换成 --build-id
LDFLAGS_BUILD_ID := $(patsubst -Wl$(comma)%,%,\
$(call cc-ldoption, -Wl$(comma)--build-id,))
2.3、strip 去空格函数
1、语法:$(strip , <'text>)
2、功能:将字符串text中的前后无效空格去除
3、举例:
#源码位置:tools/power/cpupower/Makefile
# $(strip $(STATIC))
# 功能:去除变量STATIC中的前后无效空隔
# ifeq
# 判断STATIC变量值是否为true,,如果是,向下执行
ifeq ($(strip $(STATIC)),true)
UTIL_OBJS += $(LIB_OBJS)
UTIL_HEADERS += $(LIB_HEADERS)
UTIL_SRC += $(LIB_SRC)
endif
2.4、findstring查找字符串函数
1、语法:$(findstring <字符串A>, <字符串B>)
2、功能:在字符串B中查找字符串A,如果存在,返回字符串A,否则返回空
3、举例:
见 1.2
2.5、filter 过滤字符串函数
1、语法:$(filter <'pattern> <'text>)
2、功能:返回字符串text中满足pattern条件的字符串
3、举例:
# MAKECMDGOALS 变量用于保存make命令后面的参数,即 :
# linux-4.13 $ make xxx XXY ... #保存的是XXX XXY ...
# $(filter all _all modules,$(MAKECMDGOALS))
# 功能:判断MAKECMDGOALS变量的值是否为 :all _all modules
# 即:是否为如下命令:
# make all
# make all _all
# make all _all module
# make _all
# make _all module
# ............
# 如果是,返回对应的值,如:
# all
# all _all
# modules
# .........
# ifneq 功能:当make命令后面的参数为all _all modules中任意一个或多个时,向下执行
ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
KBUILD_MODULES := 1
endif
2.6、filter-out反过滤字符串函数
1、语法:$(filter-out <'pattern> , <'text>)
2、功能:去除字符串text中,满足pattern条件的字符串
3、举例:
见 1.2
2.7、sort 排序函数
1、语法:$(sort <'list>)
2、功能:将list字符串列表中的字符串进行排序
3、举例:
# $(filter-out arch/%,$(vmlinux-alldirs))
# 返回值:变量vmlinux-alidirs中不带 ' arch/% '的值
# 注:关于变量vmlinux-alidirs值较多,可参见源码分析
# $(sort ...)
# 对filter-out的返回值和 arch Documentation include samples scripts tools
# 排序后赋值给变量KBUILD_ALLDIRS。
export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Documentation include samples scripts tools)
2.8 word 取单词函数
1、语法:$(word <'n> , <'text>)
2、功能:返回字符串text中第n个单词,n从1开始,且n不能小于1
3、举例:
# 源码位置 :arch/arm/Makefile
# ifneq ($(machine-y),)
# 当变量machine-y值不为空时,向下执行 :
# MACHINE := arch/arm/mach-$(word 1,$(machine-y))/
# 否则:
# MACHINE :=
# $(word 1,$(machine-y)
# 功能 :返回变量machine-y的第一个值
ifneq ($(machine-y),)
MACHINE := arch/arm/mach-$(word 1,$(machine-y))/
else
MACHINE :=
endif
2.9 wordlist 取单词串函数
1、语法:$(wordlist <'start> , , <'text>)
2、功能:返回字符串text中第start个单词到第end个单词
3、举例:
用法类似于2.8案例
2.10、words 计算字符串中单词个数
1、语法:$(words <'text>)
2、功能:返回字符串texte有多少个单词,区分单词的依据为空格
3、举例:
见2.1案例
2.11 firstword首单词函数
1、语法:$(firstword <'text>)
2、功能:返回字符串texte中的第一个单词
3、举例
# $if( 条件,满足条件执行的语句)
# $(KBUILD_EXTMOD) 不为空时执行后面的语句
# $(firstword $(KBUILD_EXTMOD))/
# 返回变量KBUILD_EXTMOD第一个值 + '/'
# 当$(KBUILD_EXTMOD)有值时,
# MODVERDIR值为KBUILD_EXTMOD第一个值 + .tmp_versions
# 否则:
# MODVERDIR值为.tmp_versions
export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions