引用
本文完全参照大佬的文档写的,写这篇文章只是为了梳理一下知识
https://github.com/marmotedu/geekbang-go/blob/master/makefile/Makefile%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86.md
介绍
Makefile是一个工程文件的编译规则,描述了整个工程的编译和链接等规则,这些规则里包含了这些内容:
- 工程中的哪些源文件需要编译,以及如何编译;
- 需要创建哪些库文件,以及如何创建;
- 如何最终生成我们想要的可执行文件。
学习makefile,主要就是学习它的规则、语法,以及shell脚本,在makefile中会大量使用shell命令,所以shell是makefile的基础。
规则
target ...: prerequisites ...command...
target:可以是目标文件、也可以是执行文件或者标签。可以用通配符、多个目标之间用空格分开
prerequisites:表示生成target的依赖项,在执行target对应的command前需要完成依赖项的执行,多个prerequisite用空格分开
command:生成target的指令
- 在执行command之前,默认会先打印出该命令,然后再输出命令的结果;如果不想打印出命令,可在各个command前加上@。
- command可以为多条,可以分行写,但每行都要以tab键开始。另外,如果后一条命令依赖前一条命令,则这两条命令需要写在同一行,并用分号进行分隔。
- 如果要忽略命令的出错,需要在各个command之前加上减号-。
只要targets不存在或prerequisites中有一个以上的文件比targets文件新,command所定义的命令就会被执行。command会产生我们需要的文件或执行我们期望的操作。
伪目标
伪目标不是文件,make 无法生成它的依赖关系和决定是否要执行它,通常我们需要显式地指明这个目标为伪目标。为了避免和文件重名,在Makefile中可以使用.PHONY来标识一个目标为伪目标:
.PHONY: clean #声明伪目标,不进行检查
clean:rm hello.o
伪目标总是会被执行,其依赖也会被决议
order-only依赖
在上面介绍的规则中,只要当prerequisites中有任何文件发生改变时就会重新构造target,但是有时候我们希望只有当prerequisites中的部分文件改变时才重新构造target,这时可以通过order-only prerequisites实现。
order-only prerequisites:
targets : normal-prerequisites | order-only-prerequisitescommand......
在上面的规则中,只有第一次构造targets时才会使用order-only-prerequisites,后面即使order-only-prerequisites发生改变,也不会重新构造targets,而只有normal-prerequisites中的文件发生改变时才重新构造targets。符号|后面的prerequisites即是order-only-prerequisites。
引入其它makefile
include scripts/make-rules/common.mk
include scripts/make-rules/golang.mk
除了include文件路径,makefile还有其它方式引入,顺序如下:
- 根据include的文件路径引入
- 如果make命令携带参数-I 或–include-dir 时会去该文件夹下找文件
- 会去/usr/local/bin或/usr/include路径下找
语法
赋值
= 最基本的赋值方法。
a = a
b = $(a) b
a = c
这种赋值方式下b最终等于c b
:= 直接赋值,赋予当前位置的值。
a = a
b := $(a) b
a = c
b最后等于 a c
?= 表示如果该变量没有被赋值,则赋予等号后的值。
+= 表示将等号后面的值添加到前面的变量上。
变量
环境变量
makefile通过$(xxx)
的方式来使用环境变量和其它变量
通常我们会在执行makefile前定义一些makefile需要使用的环境变量,这样makefile就能根据环境变量的不同执行不同的操作
特殊变量
特殊变量是make提前定义好的,可以在makefile中直接引用,特殊变量列表如下:
变量 含义
- MAKE: 当前make解释器的文件名
- MAKECMDGOALS: 命令行中指定的目标名(make的命令行参数)
- CURDIR 当前make解释器的工作目录
- MAKE_VERSION 当前make解释器的版本
- MAKEFILE_LIST make所需要处理的makefile文件列表,当前makefile的文件名总是位于列表的最后,文件名之间以空格进行分隔
- .DEFAULT_GOAL 指定如果在命令行中未指定目标,应该构建哪个目标,即使这个目标不是在第一行
- .VARIABLES 所有已经定义的变量名列表(预定义变量和自定义变量)
- .FEATURES 列出本版本支持的功能,以空格隔开
- .INCLUDE_DIRS make查询makefile的路径,以空格隔开
自动化变量(重要)
所谓自动化变量,就是这种变量会把模式中所定义的一系列的文件自动地挨个取出,直至所有的符合模式的文件都取完了。这种自动化变量只应出现在规则的命令中。Makefile中支持的自动变量见下表。
函数