从事嵌入式开发,各种工程项目几乎都会使用Makefile,linux、freertos以及Android工程都会使用它。先来看看它的用途。
Makefile主要用于定义和管理一个项目的构建过程,具体来说,它的用途包括:
1. 自动化编译和链接:通过定义编译器、编译选项、源文件、目标文件等信息,Makefile可以自动完成代码的编译和链接过程,从而提高开发效率。
2. 管理依赖关系:Makefile中可以指定各个源文件之间的依赖关系,确保在修改某个文件后,只需要重新编译该文件及其相关的依赖文件。
3. 跳过不必要的编译:通过检查源文件和目标文件的时间戳,Makefile可以避免重新编译未发生变化的文件,从而加快构建速度。
4. 执行其他任务:除了编译和链接任务,Makefile还可以定义其他任务,如清理临时文件、运行测试、生成文档等。
用途如此强大,不清楚如何编写岂不可惜?
那Makefile具体是什么东东?简易理解是一种脚本语言,像shell脚本一样,需要有解释器(make)。
虽说Makefile是脚本语言,学习的时候也应当按正常编程语言来学习,也是有变量,符号,语句,函数。
1,Makfile必须要含有目标结构,如下所示
:
解释如下:
1)target 叫目标,也就是make 执行时带参数;
make [target]
2)prerequisties 叫着前置条件,target依赖条件;
3)第二行必须用TAB键起,紧接着是具体的执行命令,命令是shell命令。
注意:target 是必须的;prequisites,和command是可选的,递归执行前置条件,但是两者必须有一个。
2,Makeflie入口程序
1)当执行make [target]时,Makefile 中target 亦是入口;
2)当执行make不带参数时,入口默认是第一个target。
整体为顺序执行。
3,Makefile工作原理
1,变量类型
Makefile变量皆为字符串。
定义变量通常只需要写变量名=xxx,在后面的调用中用$(变量) 即可。
#变量
testvar=hello
printvar:
@echo $(testvar)
make执行结果如下:
# make
hello
2,变量赋值种类
Makefile一共提供了四个赋值运算符 (=、:=、?=、+=),它们的区别如下:
1)var= $(value)
在执行时扩展,允许递归扩展。是指右值value 为变量时,var会随着value变动而变动,var值是value 最后一次值。
2)var:= $(value)
在定义时扩展。当value为变量时,var为value当前值,不会随着value变化而变化。
3)var?= $(value)
只有在该变量var为空时才设置值。
如果没有初始化变量var,就给它赋上默认值;如果已经赋值了便不会起作用。
4)var+= $(value)
将值追加到变量的尾端。
同=是一样。
1,注释
注释用# 表示。
2,回声
正常情况下,makefile会在控制台打印每一条命令,这叫回声。
在第一行命令前增加 @ 符号,就可以关闭回声,这样就不会打印命令.
3,通配符
通配符(wildcard)用来指定一组符合条件的文件名。Makefile 的通配符与 Bash 一致,主要有星号(*)、问号(?)和 [...] 。比如, *.o 表示所有后缀名为o的文件。
clean:
rm -f *.o
4,模式匹配
makefile可以用% 来匹配makefile 文件中的目标.%表示任何非空字符串. % 和通配符中的* 的区别在于他们使用的作用域不一样:* 指的运用在系统中,而%运用在makefile文件中.
例如:对于模式规则“%.o : %.c”,它表示的含义是:所有的.o文件依赖于对应的.c文件。我们可以使用模式规则来定义隐含规则。
1,判断语句
makefile中的判断 一般采用ifxxx ... else ... endif 的形式;条件判断 有
ifeq ... else ...endif,
ifneq ... else ... endif ,
ifdef ...else ... endif,
ifndef ... else ... endif
CC=gcc
ifeq ($(CC),gcc)
libs=gcc
else
libs=not gcc
endif
all:
@echo ${libs}
运行结果:
# make
gcc
2,循环语句
使用shell 循环语句。
while/do/done
for/do/done
makefile 使用函数的格式
${function arg1 arg2} 或者 $(function arg1 arg2)
多样函数使编写Makefile更加灵活,丰富了扩展。