1.Makefile的概念
使用keil, mdk, avr等工具开发程序时点点鼠标就可以编译了
它的内部机制是什么?它怎么组织管理程序?怎么决定编译哪一个文件?
gcc -o test a.c b.c
// 简单,
// 但是会对所有文件都处理一次,
// 文件多时如果只修改其中一个文件会导致效率低
在linux系统中make是一个非常重要的编译命令,不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或makeinstall。利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile 带来的好处就是“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
2.Makefile规则与用法
条件
当"目标文件"不存在,
或
某个依赖文件比目标文件"新",
则: 执行"命令"
规则
一条规则:
目标 : 依赖1 依赖2 …
[TAB]命令
自上而下,分解任务
执行:make
二条规则:
伪目标不去判断目标文件是否存在或者已经更新
无条件执行命令
伪目标
.PHONY:
clean:(不用tab)
rm -rf $(OBJS) $(TARGET)
执行:make clean
Makefile基本规则三要素:
目标 : 依赖1 依赖2 …
[TAB]命令
注:这俩文件名字随便取,目的是为了链接
1)目标文件:
通常是要产生的文件名称,目标可以是可执行文件或其它obj文件,也可是一个动作的名称(必须有)
只能一个
2)依赖文件:
用来输入从而产生目标的文件
一个目标通常有几个依赖文件(可以没有)
可以一个可以多个
3)命令:
make执行的动作,一个规则可以含几个命令(可以没有)
有多个命令时,每个命令占一行
语法 :
make [伪目标]
若无伪目标,默认第一个目标
使用
在当前目录执行make命令,会自己找到Makefile里面的内容并执行
说明:检测到没有任何一个依赖需要更新的时候就会如下报错
3.Makefile进阶语法
a. 通配符: %.o
$@ 表示目标
$< 表示第1个依赖文件
$^ 表示所有依赖文件
4.Makefile中的变量使用
类似C语言中宏定义
在Makefile中使用变量有点类似于C语言中的宏定义,使用该变量相当于内容替换,使用变量可以使Makefile易于维护,修改内容变得简单变量定义及使用。
7.1 自定义变量
1)定义变量方法:
变量名=变量值
2)引用变量方式:
( 变 量 名 ) 或 (变量名)或(变量名)或{变量名}
3)makefile的变量名:
makefile变量名可以以数字开头
变量是大小写敏感的
变量一般都在makefile的头部定义
变量几乎可在makefile的任何地方使用
4)变量类型
即时变量、延时变量, export
简单变量(即时变量) :
A := xxx # A的值即刻确定,在定义时即确定
B = xxx # B的值使用到时才确定
:= # 即时变量
= # 延时变量
?= # 延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句
+= # 附加, 它是即时变量还是延时变量取决于前面的定义
5.Makefile函数
a. $(foreach var,list,text)
b. $(filter pattern…,text) # 在text中取出符合patten格式的值
$(filter-out pattern…,text) # 在text中取出不符合patten格式的值
c. $(wildcard pattern) # pattern定义了文件名的格式,
# wildcard取出其中存在的文件
d.
(
p
a
t
s
u
b
s
t
p
a
t
t
e
r
n
,
r
e
p
l
a
c
e
m
e
n
t
,
(patsubst pattern,replacement,
(patsubstpattern,replacement,(var)) # 从列表中取出每一个值
# 如果符合pattern