makefile基础内容学习笔记
这篇文章是阅读廖雪峰老师的文章 后的一点笔记和心得
makefile文件学习
规则格式
规则格式如下
1 | <target> : <prerequisites> |
格式解释:
- 目标target : 目标是规则名,常常设置为文件名或者操作目的,同时一条规则可以有多个目标,可以理解为,多个目标有相同的command,然后就可以合并写。需要注意的是,makefile文件的目标会优先构建文件,因此操作目的需要与文件名有所区分,如果存在与操作目的同名的文件,那么该规则会认为没有必要重新构建该文件,因此不会触发。如果想要避免这种情况,可以在文件中加上
.PHONY: <target>
(位置随意,有就行,写在最前面或者最后面的比较多见) 值得注意的是如果make命令没有指定目标,那么将会默认为makefile文件的第一个目标 - 前置条件prerequisites
- 命令command:一条或者多条shell命令,通常需要能够构建目标文件。如果有多行shell指令的话将会在相互独立的shell中执行,同一行的多条指令将会按照次序在同一个shell中执行;如果想要多行shell也在同一个shell中执行,可以在目标上一行加上
.ONESHELL
,也可以在每一行后面加上\
表示把换行符转义
语法
注释
#
在makefile中表示注释
回声
make执行的规则前会将该规则的command(包括注释)打印在终端上,如果不需要哪一行内容打印可以在对应的command前面加上@,通常会在注释前面加上
模式匹配
1 | %.o:%.c |
这一条指令会将当前目录下的所有的 .c文件 执行command变为对应的 .o 文件
具体命令行怎么写,可以参考后文提到的自动变量之一的$*
变量和赋值符
普通变量定义:
1 | # 定义时扩展(静态扩展),还是在运行时扩展(动态扩展) |
内置变量定义
1 | # 内置变量 |
自动变量定义
1 | # 自动变量 |
判断与循环
判断语法实例如下:
1 | ifeq ($(CC),gcc) |
循环操作实例如下:
1 | # 数组类型变量定义 循环的写法 shell中的循环写法 |
函数
使用函数的格式:
1 | $(function arguments) |
常用的函数如下:
1 | # subst 函数 替换文本 语法格式如下 |
心得体会
我理解的makefile就是一个shell指令的一个批处理操作,对于每一个目标target,就是这一条规则将会生成的文件或者达到的效果。而前置条件,也是一些target,为了区别于目标名,这里将前置条件的target可以记作protarget,就是要实现target就得先实现protarget,就是基于这个思路,可以设置一个指令的批处理操作,而其对于重构target的标准中对于时间戳的考量,则是其能够提高编译效率的一个关键。至于其中提到的command,对于初学者,这一部分是最让人懵逼的,但是仔细一看,需要记忆的也只有一些专有的变量和函数,而且实际的命令写法则是shell脚本语言,所以学习makefile之前最好能先修shell脚本语言,这里可以看看菜鸟教程关于shell脚本语言的介绍,之后作者也会更新相关的知识笔记。
其实对于makefile的使用频率是很少的,因为一个项目往往只需要一个makefile,甚至多个类似的项目使用的makefile几乎一模一样,可以直接copy,而且其在项目初期建立之后往往很少需要改动(如果项目里面的makefile需要常常改动,那这个项目大概率是不适合使用makefile的)。因此makefile实际练手的机会是比较少的,我觉得可以通过先修shell之后,再来结合makefile能够编写出一些shell小脚本,这样makefile和shell都能得到锻炼。