乐趣区

关于c++:make从入门到入门

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]# make
makefile: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.o

test: $(all)
$(CC) -o test $(all)

test.o: ./test.cpp
$(CC) -c test.cpp

clear:
        rm -f *.o test

执行 make 命令

[root@localhost makefiletest]# make
g++ -c test.cpp
g++ -o test test.o
[root@localhost makefiletest]# ls -lrt
total 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 clear
rm -f *.o test

如果不执行 make clear 清理之前的.o 文件,make 会比拟.o 和.cpp 谁更新,如果依赖文件 cpp 更新,从新编译这个.o,否则不从新编译。

退出移动版