make从入门到入门

makefile文件是用来帮助编译和管理C++项目代码的,须要配合make命令使用。makefile里也能够执行shell操做,具有一部分.sh脚本的功能。ios

makefile格式

makefile内容的编写按照以下规则shell

目标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命令时会报spa

[root@localhost makefiletest]# make
makefile:5: *** missing separator (did you mean TAB instead of 8 spaces?).  Stop.

举个例子

如下面简单的C++代码为例,说明makefile的具体使用。code

源代码文件test.cppip

#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文件,文件就是makefilestring

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命令io

[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。
上面两个规则完成了从源代码到可执行文件的编译。test

大型工程必须用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文件的生成规则。 stream

上面说的是按最原始的写法,实际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,不然不从新编译。

相关文章
相关标签/搜索