makefile文件是用来帮忙编译和治理C++我的项目代码的,须要配合make命令应用。makefile里也能够执行shell操作,具备一部分.sh脚本的性能。
makefile格局
makefile内容的编写依照如下规定
指标1:依赖1 命令1指标2:依赖2 命令2指标3:依赖3 命令3.........................指标N:依赖N 命令N
命令能够是任意的shell语句。少数状况下,命令都是起到了从依赖生成指标的性能。例如从.cpp文件生成.o文件,那么命令肯定包含g++和一些编译参数的残缺的编译命令。
指标1 2 3能够是嵌套依赖的,如果依赖1里蕴含指标2 指标3,那就是一种嵌套的依赖。也能够是独立的,例如指标1 2 3就是三个独立的可执行文件,或者三个动静库,那么他们之间是能够齐全没有依赖关系的,写在一个makefile文件里只是便于对立治理。
命令前要以一个tab结尾 。如果应用空格代替tab,执行make命令时会报
[root@localhost makefiletest]# makemakefile:5: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
举个例子
以上面简略的C++代码为例,阐明makefile的具体应用。
源代码文件test.cpp
#include <string>#include <iostream>#include<iomanip>int main(int argc, char** argv){using namespace std;int i =1 ;int j = 2; j += 3;cout << j<<endl;}
makefile文件,文件就是makefile
CC=g++all = test.otest: $(all)$(CC) -o test $(all)test.o: ./test.cpp$(CC) -c test.cppclear: rm -f *.o test
执行make命令
[root@localhost makefiletest]# makeg++ -c test.cppg++ -o test test.o[root@localhost makefiletest]# ls -lrttotal 24-rw-r--r--. 1 root root 196 Aug 6 11:00 test.cpp-rw-r--r--. 1 root root 120 Aug 6 11:04 makefile-rw-r--r--. 1 root root 2328 Aug 6 11:04 test.o-rwxr-xr-x. 1 root root 8840 Aug 6 11:04 test
正确生成了test和test.o
例子解说
makefile中的“指标1”test是个可执行文件,也是最终咱们须要的货色。test依赖$(all)这个变量,文件结尾定义了all = test.o,所以test依赖的是test.o,生成test的命令是$(CC) -o test $(all),进行变量替换后就是g++ -o test test.o,是一个咱们熟知最根底的编译命令。
同理,“指标2”test.o依赖的是test.cpp,生成指标的命令是g++ -c test.cpp。
下面两个规定实现了从源代码到可执行文件的编译。
大型工程必须用makefile
其实咱们间接执行g++ -o test test.cpp就能够生成test了,但这种间接敲命令只实用于代码文件很少的状况。
即便我的项目只有5个文件,每次代码更新都要敲5个编译命令也是很麻烦的。咱们只有编写一次makefile,之后每次代码更新,或者代码文件有增减,都只须要批改makefile对应的一小部分内容,而后执行make就行了。
例如test依赖是100个.o文件,在下面的makefile中咱们只有写一次all = test.o test1.o test2.o ..... test99.o,就把指标test的生成规定表白分明了。当然上面要写上100个.o文件的生成规定。
下面说的是按最原始的写法,理论makefile的编写有很多技巧使得编写量大大减少,
- 编译命令的各种参数选项对立都写在变量中
- 模式匹配
- 特殊符号代码依赖集
- 指标集
- shell指令在makefile里实现主动查找生成所有文件名,而后替换.cpp为.o的玩法
这些都能够大大减少makefile的篇幅。如果关上一个开源C++我的项目的makefile,会感觉齐全看不懂,就是因为外面大量应用各种技巧。但即便咱们用最原始方法也就是第一次编写麻烦一些,之后保护是很简略的,因为一个C++我的项目不会频繁的大变样。
makefile文件名
make默认反对makefile和Makefile两种文件名,所以咱们间接执行make等价于执行make Makefile。如果咱们写make规定的文件叫test20200806,须要执行的命令是make -f test20200806。
并行编译
并行make的命令是make -j。能够放慢工程编译速度,对于大规模工程实用。
主动推导
make会主动推导各个指标的依赖关系,依照依赖关系的程序生成指标文件。
伪指标
本文makefile里的“指标3”clear是个伪指标,伪指标前面无文件依赖,make不主动找文件依赖,无奈执行前面的命令。要执行伪指标,就要make+为指标名。执行make clear,会执行上面的rm命令,这种命令用来清理我的项目之前编译的.o等文件,在须要彻底从新编译我的项目时都会执行这个命令。
[root@bogon makefiletest]# make clearrm -f *.o test
如果不执行make clear清理之前的.o文件,make会比拟.o和.cpp谁更新,如果依赖文件cpp更新,从新编译这个.o,否则不从新编译。