make 是一个根据指定Shell命令进行构建的工具。规定要构建哪个文件,它依赖于哪些源文件,当这些文件变动时,如何重新构建
1. Makefile的格式
make
的规则写在名为Makefile
的文件里,make根据这个文件进行构建。
1. 1 规则格式
<target> : <prerequisites>
[tab] <commands>
其中,
- target通常是文件名,表示你想构建的文件,也可以是带有具体含义的名称(伪目标)
- prerequisites是前置条件,要构建出target,需要先满足前置条件
- commands是构建出target具体执行的命令
1.2 target
一个目标(target)通常是文件名,多个目标之间用空格隔开。
除了具体的文件名,还可以是伪目标(PHONY)
clean:
rm *.o
$ make clean
将删除所有目标文件
但是,如果当前文件中存在clean
文件,那么这个命令将不会执行。解决办法是使用.PHONY
.
.PHONY: clean
clean:
rm *.o
每次执行make命令,不管有没有名为clean的文件,都会删除目标文件。
1.3 prerequisites
前置条件(prerequisites)通常是一组文件,空格分隔。指明目标的构建条件:只要有一个前置条件文件不存在或更新,就重新构建目标。
result.txt: source.txt
cp source.txt result.txt
在上面的规则中,如果source.txt不存在,那么必须在这条规则上面再添加一条规则生成source.txt
source.txt:
echo "source txt" >>source.txt
如果要生成多个文件,使用下面写法
source: file1 file2 file3
这里的source是伪目标,只有三个前置文件,没有对应命令
1.4 commands
命令(commands)表示如何构建目标文件,由一行或多行shell命令组成。
需要注意的是,每行命令是在单独的shell中执行的,shell之间没有继承关系。
test:
export var=hello
echo $$var
结果不会输出hello,因为两个shell不在同一环境。
一个解决办法是写在一行,分号分开。或者使用 \
串接,或者加上.ONESHELL
# 或者
.ONESHELL:
test:
export var=hello; echo $$var
#或者
export var=hello; \
echo $$var
2. Makefile文件语法
2.1 注释
#
表示注释
result.txt: source.txt
# 这是注释
cp source.txt result.txt
2.2 echoing
make会将每条命令包括注释输出,再执行命令。
如果不想输出,就在语句前面加上@
。
2.3 通配符
Makefile通配符与Bash一致。
2.4 模式匹配
make允许对文件名进行匹配,用到的是%
匹配符。比如,当前有a.c 和 b.c 两个源文件,要编译成目标文件。
%.o : %.c
等同于
a.o : a.c
b.o : b.c
2.5 变量和赋值
make允许自定义变量
text = hello make
test:
@echo $(text)
变量要放在$()
里面才能被正确解析。
我们都知道,Shell变量都以,因为make会对$进行转义。
test:
@echo $$PPID
2.6 内置变量
make提供了一系列内置变量。常见的有
内置变量 | 含义 |
---|---|
CC | 当前使用的编译器 |
MAKE | 当前使用的构建工具 |
CXX | C++编译器 |
CPP | C与预处理器,标准输出 |
AS | 编译汇编语言 |
2.7 自动变量
自动变量 | 含义 |
---|---|
$@ | 指代当前目标 |
$< | 指代第一个前置条件 |
$^ | 指代所有前置条件,空格分隔 |
$* | 匹配符% 匹配的部分 |
(@F) | 分别指向$@的目录名和文件名 |
网友评论