文章目录
Basic Introduce Makefile
一、makefile的赋值方式
makefile分为延时变量与立即变量两种。
延时变量:在真正使用这个变量的时候,变量的值才确定(延时展开)
立即变量:在定义的时候,变量的值已经确定(立即展开)
Note:
“=”,"?=",":=","+="以及define说明
a.“=”,“?=”以及define定义的均为延时变量
b.“:=”定义的为立即变量
c."+="右边定义的变量为立即变量,则左边的为立即变量;否则为延时变量
d."?="仅仅在变量还没有定义时才有效,如果已经定义,则无效。
override:
我们可以在执行make时通过命令行方式重新指定这个变量的值,命令行指定的值将替代出现在Makefile中此变量的值。如果不希望命令行指定的变量值替代在Makefile中的变量定义,那么我们需要在Makefile中使用指示符“override”来对这个变量进行声明。
二、makefile中常用的自动变量与内嵌变量
I.自动变量
$@: 表示规则的目标文件名
$<: 表示第一个依赖文件名
$^: 表示所有的依赖文件名
%: 通配符。用于通配一个字符串中任意数目的字符
$(@D) :
The directory part of the file name of the target, with the trailing slash removed. If the value of $@
is dir/foo.o
then $(@D)
is dir
. This value is .
if $@
does not contain a slash.
http://www.gnu.org/software/make/manual/make.html
$(@F) :
The file-within-directory part of the file name of the target. If the value of $@
is dir/foo.o
then $(@F)
is foo.o
. $(@F)
is equivalent to $(notdir $@)
.
II.内嵌变量
$(CURDIR): 显示当前路径
$(MAKECMDGOALS): 存放指定的终极目标列表
$(MAKEFILE_LIST): 获取最近使用的Makefile文件
三、makefile的常用选项
I.常用的选项
-f => 指定makefile文件
-C => 进入目录
-p => 输出makefile中的变量信息
II.makefile中的特殊target
.PHONY : 来显示的指名一个目标是伪目标,有两个作用:
1.改善性能(跳过隐式规则);
2.避免冲突(避免目标与文件同名)。
PHONY += FORCE
FORCE:
这个规则没有命令也没有依赖,它的目标也不是一个存在的文件名。在执行此规则时,目标 FORCE总会被认为是最新的。这样当它作为其它规则的依赖时,因为依赖总被认为被更新过的,所以那个规则的中定义的命令总会被执行。
# Note:
# 同名目标 将会合并执行;如果两个目标均有cmd则会产生警告,并用后一条cmd替换前一条cmd。
target1: dep1
target1: dep2
cmd
# 等效于
target1: dep1 dep2
cmd
四、makefile的常用函数
I.函数的调用格式
$(function arguments)
function => 函数名
arguments => 参数列表
Note:
1.function与arguments用空格或者Tab隔开
2.arguments之间用逗号隔开
3.逗号与空格不属于arguments
II.kernel中的makefile常用的函数
A.字符串替换与分析函数
a.$(subst from,to,text)
说明:将“text”字符串中的每一处“from”字符串替换为“to”
b.$(patsubst pattern,replacement,text)
说明:寻找“text”中符合格式“pattern”的字,并且用“replacement”进行替换。“pattern”与“replacement”均可以使用通配符“%”
Note:
$(VAR:x=y) <=> $(patsubst %x , %y , $(VAR))
c.$(strip string)
说明:去掉“string”中前导和结尾的空格,并将中间的多个空格压缩为单个空格。
d.$(findstring find,in)
说明:在字符串“in”中寻找“find”,如果找到,则返回“find”;否则,返回空
e.$(filter partten…, text)
说明:返回在text中由空格隔开并且匹配"pattern…"的字。去掉不符合格式“pattern…”的字。
f.$(filter-out partten…, text)
说明:返回在text中由空格隔开并且不匹配"pattern…"的字。去掉符合格式“pattern…”的字。
g.$(sort list)
说明:将“list”中的字按照字母顺序排序,并且去掉重复的字。输出的字以单个空格隔开。
h.$(word n,text)
1.word 函数取 text 中第 n 个单词。
2.n 需满足条件 0 < n <= $(words text),否则返回空值或者出错(if n is bigger than the number of words in text, the value is empty)。
3.n 为 0 时,make 将提示错误(first argument to ‘word’ function must be greater than 0)。
i.$(wordlist s,e,text)
1.wordlist 函数从 text 中取出从 s 开始到 e 结束之间的单词串。
2.s 需满足条件 0 < s <= $(words text) ,否则返回空值或者出错(if s is bigger than the number of words in text, the value is empty)。
3.e 需满足条件 0 < e,否则出错。
4.如果 e > $(words text),则返回从 s 开始到 $(words text) 结束之间的单词串(if e is bigger than the number of words in text, words up to the end of text are returned)。
5.如果 s > e,则返回空值(if s is greater than e, nothing is returned)。
j.$(words text)
说明:
1.words 函数统计 text 中单词的个数。
2.text 最后一个单词为 $(word $(words text),text)。
k.$(firstword names)
1.firstword 函数取 names 中的第一个单词(the value is the first name in the series)。names 展开后被认为是一系列单词的集合(a series of names),这些单词使用空白分隔。
2.$(firstword text) 等同于 $(word 1,text)。
3.$(firstword text) 等同于 $(wordlist 1,1,text)。
l.$(lastword names)
1.lastword 函数取 names 中的最后一个单词(the value is the last name in the series)。names 展开后被认为是一系列单词的集合(a series of names),这些单词使用空白分隔。
2.$(lastword text) 等同于 $(word $(words text),text)。
3.$(lastword text) 等同于 $(wordlist $(words text), $(words text),text)。
B.文件名函数
a.$(dir names…)
说明:抽取“names…”中每一个文件名的路径部分;文件名路径部分包含从文件名首字符到最后一个斜杠之前(包含斜杠)的一切字符。
b.$(notdir names…)
说明:抽取“names…”中每一个文件名中除路径部分的一切字符(真实文件名)。
c.$(suffix names…)
说明:抽取“names…”中每一个文件名的后缀。
d.$(basename names…)
说明:抽取“names…”中每一个文件名除后缀外的一切字符。
e.$(addsuffix suffix, names…)
说明:“names…”为一系列文件名,文件名之间用空格隔开;“suffix”为后缀名。
该函数的作用是,为文件名加上后缀suffix,文件名之间用单个空格隔开。
f.$(addprefix prefix, names…)
说明:“names…”为一系列文件名,文件名之间用空格隔开;“prefix”为前缀名。
该函数的作用是,为文件名加上前缀prefix,文件名之间用单个空格隔开
g.$(wildcard parttern)
说明:“parttern“是文件格式符,包含通配符。
函数作用是,返回当前目录中,与parttern匹配并且正式存在的文件名,文件名之间用单个空格隔开。
C.其他函数
a.$(foreach var, list, text)
说明:将list中的每个字扩展后,赋值给var变量,然后text引用var变量进行扩展。最终得到的text将作为函数foreach的返回值,text的字与字之间通过单个空格分隔
b.$(if condition,then-part[,else-part])
说明:将“condition”的前导与结尾空格去除,然后进行扩展。如果扩展为非空字符串,则condition为真;否则为假。
condition为真,执行then-part的值,并把其作为if函数的返回值
condition为假,若else-part存在,则执行else-part的值,并把其作为if函数的返回值;否则if函数返回为空值。
c.$(call VARIABLE,PARAM,PARAM,…)
说明:自定义函数。用PARAM依次替换VARIABLE中的 ( 1 ) , (1), (1),(2),…后,得到的VARIABLE的计算值即为call的返回值。
EX:$(call if_changed,mkinage)
quiet_cmd_mkimage = MKIMAGE $@
cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \
$(if $(KBUILD_VERBOSE:1=), >/dev/null)
MKIMAGEFLAGS_MLO = -T omapimage -a $(CONFIG_SPL_TEXT_BASE)
MKIMAGEFLAGS_MLO.byteswap = -T omapimage -n byteswap -a $(CONFIG_SPL_TEXT_BASE)
MLO MLO.byteswap: $(obj)/u-boot-spl.bin FORCE
$(call if_changed,mkimage)
如例子中的$(call if_changed, mkimage),如果任何的先决条件比目标更新,将会执行mkimage命令,而mkimage在 <scripts/Makefile.lib>定义,如下:
cmd_mkimage = $(objtree)/tools/mkimages $(MKIMAGEFLAGS_$(@F)) -d $< $@ $(if $(KBUILD_VERBOSE:1=), >/dev/null)
所以,$(call if_changed,mkimage)命令可以转义如下:
以目标MLO为例,如果目标的依赖发生更新时,将会执行下面的命令来生成MLO
$(objtree)/tools/mkimages -T omapimage -a $(CONFIG_SPL_TEXT_BASE) -d $(obj)/u-boot-spl.bin MLO $(if $(KBUILD_VERBOSE:1=), >/dev/null)
d.$(origin variable)
说明:variable为变量名,而不是其引用,故不需要加"$;
函数的返回结果是一个字符串,其字符串的含义如下:
返回字符串 | 含义 |
---|---|
undefined | variable从未有定义过 |
default | variable是默认定义 |
environment | variable是环境变量定义,选项“-e”没有打开 |
environment override | variable是环境变量定义,选项“-e”已经打开 |
file | variable在makefile中定义 |
command line | variable在命令行中定义 |
override | variable在makefile中用override指定定义 |
automatic | variable是自动变量 |
e.$(shell command arguments)
说明:调用shell命令(command arguments)。如果command返回值中换行符(回车符),shell函数的返回值将会处理为单个空格;如果返回值最后是换行符(回车符),将会被去掉
Exp:
BASEDIR:=$(strip $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))))
$(MAKEFILE_LIST) => 返回最近使用的Makefile文件
$(lastword, ) => 提取最后一个Makefile
$(realpath, ) => 返回makefile的绝对路径
$(shell dirname ) => 执行shell command,获取Makefile的目录
$(strip ) => 去除字符串中开头与结尾的空格
所以,该表达式是用于获取当前Makefile的目录!!!