1-Basic Introduce Makefile

2 篇文章 0 订阅
2 篇文章 0 订阅
本文详细介绍了Makefile的基础概念,包括延时与立即变量的区分、自动变量与内嵌变量的使用、常用选项和特殊target,以及一系列实用函数的调用方法。深入理解这些内容有助于高效编写和管理Makefile文件。
摘要由CSDN通过智能技术生成

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为变量名,而不是其引用,故不需要加"$;

​ 函数的返回结果是一个字符串,其字符串的含义如下:

返回字符串含义
undefinedvariable从未有定义过
defaultvariable是默认定义
environmentvariable是环境变量定义,选项“-e”没有打开
environment overridevariable是环境变量定义,选项“-e”已经打开
filevariable在makefile中定义
command linevariable在命令行中定义
overridevariable在makefile中用override指定定义
automaticvariable是自动变量
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的目录!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值