1.Makefile基础
-
Makefile的作用和意义
- 工程项目中C文件太多管理不方便,因此用Makefile来做项目管理,方便编译链接过程
- uboot和Linux kernel本质都是C语言的项目,由多个文件组成,需要通过Makefile来管理
-
目标、依赖和命令
- 目标就是我们要去
make xxx
的xxx
,就是我们最终要生成的文件 - 依赖是用来生成目录的原材料
- 命令就是加工方法
make xxx
的过程就是使用命令将原材料加工成目标的过程。
- 目标就是我们要去
-
通配符%和Makefile的自动推导(规则)
%
是Makefile中的通配符,代表一个或几个字母,也就是说%.o
就代表所有以.o
为结尾的文件- 所谓自动推导,就是当Makefile需要某一个目标时,它会把这个目标去套规则说明,一旦套上了某个规则说明,则Makefile会试图寻找这个规则中的依赖,如果能找到则会执行这个规则用依赖生成目标
-
Makefile中定义和使用变量
- 没有变量类型,直接定义使用,引用变量时
$(var)
- 没有变量类型,直接定义使用,引用变量时
-
伪目标(.PHONY)
- 伪目标意思是这个目标本身不代表一个文件,执行这个目标是为了完成目标下面的命令
- 伪目标没有依赖,执行伪目标就是为了执行命令
- 伪目标可以直接写,不影响使用;有时候为了明确声明,会在伪目标前面加上
.PHONY
-
Makefile的文件名
- 合法文件名可以为:Makefile和makefile
-
Makefile中引用其他makefile
- 有时候makefile比较复杂,会分成多个makefile来写,然后在主makefile中用include指令来引用,引用的效果也就是原地展开,和C语言中的头文件包含非常相似
2. Makefile常见知识点
-
makefile中使用
#
注释 -
在makefile的命令行中前面的
@
表示静默执行。在makefile中默认执行一行命令前会把这行命令打印出来,然后再执行,在命令前面加上@
之后则不会打印 -
makefile中的变量赋值运算符
-
=
:用=
赋值的变量,在被解析时它的值取决于最后一次的赋值,变量引用的值要往后看A = 123 B = $(A)456 A = abc all: echo $(B) 输出结果为:abc456
-
:=
:直接赋值,不需要考虑后面的赋值。A = 123 B := $(A)456 A = abc all: echo $(B) 输出结果为:123456
-
?=
:如果变量前面没被赋值过,则执行这条赋值,如果赋值了则本行被忽略。(没有被赋值过其实就是这个变量没有被定义过) -
+=
:给一个已经赋值的变量接续赋值。在shell和makefile文件中,可以认为所有变量都是字符串,该符号相当于给字符串strcat,+=
接续的内容之间会自动加一个空格隔开
-
-
makefile中并不要求赋值运算符两边一定要有空格或者无空格,比shell格式要求松一些
3.Makfile 环境变量
- Makefile中用export导出的就是环境变量。一般情况下要求环境变量名用大写,普通变量名用小写
- 环境变量不同与普通变量,环境变量类似于整个工程中所有makefile之间可以共享的全局变量,而普通变量只是本makefile中使用的局部变量
- makefile中可能有一些环境变量是makefile本身自己定义的内部的环境变量或者是当前的执行环境提供的环境变量。(譬如在make执行时给makefile传参,
make CC=arm-linux-gcc
,其实就是给makefile传了一个环境变量CC,值是arm-linux-gcc
,在make时给makefile传的环境变量值优先级最高,可以覆盖makefile中的赋值。
4.makefile通配符
*
:表示若干个任意字符?
:表示1个任意字符[]
:将[]中的字符依次去和外面的结合匹配%
也是通配符,表示任意多个字符,与*
相似,但是%
一般只用于规则描述中,又叫做规则通配符。
5. makefile的自动变量
- 自动变量就是预定义的特殊意义的符号,类似于C语言中预置的那些宏。在有些情况下文件集合中文件特别多,描述的时候很麻烦,所以在makefile中用一些特殊意义的符号
$@
:规则的目标文件名$<
:规则的第一个依赖文件名$^
:依赖的文件集合