make是一个根据指定的
shell
命令进行构建的工具,规则很简单,规定要构建哪个文件、它依赖哪些源文件,当那些文件有变动时,如何重新构建它。
一、Make
make命令执行时需要一个makefile文件,以告诉make命令需要怎么样的去编译和链接程序。它是一个根据指定的Shell命令进行构建的工具,规则很简单,你规定要构建哪个文件、它依赖哪些源文件,当那些文件有变动时,如何重新构建它。
二、Makefile
Makefile
文件由一系列规则rules
构成,每条规则就明确两件事:构建目标的前置条件是什么,以及如何构建。每条规则的形式如下
1 | <target> : <prerequisites> |
- 目标
target
:一个目标target
就构成一条规则,它通常是文件名(一个或多个,多个用空格分开),指明Make
命令所要构建的对象目标是一/多个文件名。target
除了可以是文件名,还可以是某个操作的名字,这称为”伪目标”(phony target
)。
- 前置条件
prerequisites
:它通常是一组文件名,之间用空格分隔。- 前置条件指定了
目标
是否重新构建的判断标准:只要有一个前置文件不存在,或者有过更新(前置文件的last-modification时间戳比目标的时间戳新)目标
就需要重新构建。
- 前置条件指定了
- 制表键
tab
:每行命令之前必须有一个制表键tab
。- 如果想用其他键可以用内置变量
.RECIPEPREFIX
声明。
- 如果想用其他键可以用内置变量
- 命令
commands
:表示如何更新目标文件,由一行或多行的shell
命令组成。它是构建目标
的具体指令,它的运行结果通常就是生成目标文件。- 每行命令在一个单独的
shell
中执行,这些shell
之间没有继承关系。若要一次性执行执行多行shell
有三种方案:- 将多行shell写在一行,中间用逗号分隔
- 在每行shell后加反斜杠
\
转义 - 使用内置变量
.ONESHELL
- 每行命令在一个单独的
- Makefile语法
- 注释:用
#
,跟shell
脚本一样 - 回声
echoing
:正常情况下make
会打印每条命令,然后再执行,这就叫做回声。- 在命令的前面加上
@
可以关闭回声。
- 在命令的前面加上
- 通配符
wildcard
:用来指定一组符合条件的文件名。Makefile
的通配符与Bash
一致,主要有*
、?
和[...]
,如*.o
表示所有后缀名为o的文件。
- 模式匹配:Make命令允许对文件名进行类似正则运算的匹配,主要用到的匹配符是
%
。- 使用匹配符
%
可以将大量同类型的文件只用一条规则就完成构建。
- 使用匹配符
- 变量和赋值符:和大多数变成语言类似,使用等号
=
进行赋值给变量- 调用
shell
变量需要在美元符号前再加一个美元符号,如echo $$PATH
- 调用
- 注释:用
1 | VARIABLE = value # 在执行时扩展,允许递归扩展 |
- 内置变量
Implicit Variables
:Make命令提供一系列内置变量,比如$(CC)
指向当前使用的编译器,$(MAKE)
指向当前使用的Make工具。 - 自动变量
Automatic Variables
:自动变量的值与当前规则有关,常用的如下:$@
指代当前目标,就是Make命令当前构建的目标。$<
指代第一个前置条件,如规则为t: p1 p2
,那么$<
就指代p1
。$^
指代所有前置条件,之间以空格分隔。$+
表示所有依赖文件的集合(不去重)。$?
指代比目标更新的所有前置条件,之间以空格分隔。$*
指代匹配符%
匹配到的部分。$(@D)
和$(@F)
分别指向$@
的目录名和文件名。$(<D)
和$(<F)
分别指向$<
的目录名和文件名。
- 判断和循环:
Makefile
使用Bash
语法完成判断和循环。 - 函数:
Makefile
还可以使用函数,格式为:$(function arguments)或${function arguments}
,一些常用的函数如下:shell
函数用来执行shell
命令。wildcard
函数用来在Makefile
中替换Bash
的通配符。subst
函数用来文本替换。patsubst
函数用于模式匹配的替换。strip
函数用于去除头部和尾部的空格。filter
函数用于过滤特定模式的字符串。word
函数用于取单词。