简述
Make是一个GNU 工具, 它的用途是用来做自动化构建.通常情况下,我们都用其来构建程序.
Makefile是指示如何来做自动化构建的文件.
Makefile的规则:
target ... : prerequisites ...
recipe
...
- target是我们要生成的对象.
- prerequisite是依赖对象
- recipe是生成target的指令集1
使用Makefile只需要在其目录执行make
指令即可2.
下文将以例子为主,循序渐进的完善Makefile.
hello-world
假设我们只有一个源文件main.cpp
:
#include<iostream>
using namespace std;
int main()
{
cout<<"hello world"<<endl;
return 0;
}
如果不使用make
的情况下,我们会在命令行中输入以下来构建程序:
g++ main.cpp -o program
当我们更改了main.cpp
时,我们会在命令行通过光标来重复执行这条命令.
但当我们关闭了命令行后则需要重新执行指令.
Makefile
的第一个好处就是把构建指令以文件形式保存,然后反复执行.
这里给出两种可能的写法:
写法1
program: main.cpp
g++ main.cpp -o program
写法2
program:
g++ main.cpp -o program
这两种写法在初次使用时,产生的程序是相同的.
但是假设更改了main.cpp
,则会发现写法2运行make
并未重新生成,但是写法1重新生成了.
这里大家可以体会一下依赖文件的作用3:
如果依赖文件发生了改变,则生成对象重新生成.
这里就是Makefile的第二个好处,不做无用功. 如果依赖文件未发生改变,那么不需要重新执行指令,在代码量大的时候可以大大减少软件的构建时间.
依赖推导
当依赖文件不存在时,就会在makefile里面继续寻找这个依赖文件的推导规则.
还以上述为例子. 我们这次不直接生成目标程序.
program: main.o
g++ main.o -o program
main.o: main.cpp
g++ -c main.cpp
我们来分析下make
运行的情况:
1. 第一次运行时,program不存在,然后寻找其依赖文件main.o
.然后发现main.o
也不存在,然后继续寻找其依赖文件main.cpp
.
找到main.cpp
后,因为main.o
不存在所以执行下面的编译指令
g++ -c main.cpp
.
然后main.o
生成后,program
的依赖文件满足,
但program
本身不存在. 于是执行g++ main.o -o program
.
2. 第二次运行时,因为我们未更改任何文件,所以