Makefile de entrada a entrada

El archivo Makefile se usa para ayudar a compilar y administrar el código del proyecto C ++ y debe usarse con el comando make. Las operaciones de shell también se pueden realizar en el archivo MAKE, con algunas funciones del script .sh.

formato makefile

El contenido del archivo MAKE se escribe de acuerdo con las siguientes reglas

目标1:依赖1
  命令1

目标2:依赖2
  命令2

目标3:依赖3
  命令3
.........................
目标N:依赖N
            命令N

El comando puede ser cualquier declaración de shell. En la mayoría de los casos, los comandos se utilizan para generar destinos a partir de dependencias. Por ejemplo, si un archivo .o se genera a partir de un archivo .cpp, el comando debe incluir un comando de compilación completo de g ++ y algunos parámetros de compilación.
El objetivo 1 2 3 puede ser una dependencia anidada. Si la dependencia 1 contiene el objetivo 2 y el objetivo 3, es una dependencia anidada. También puede ser independiente. Por ejemplo, el objetivo 1 2 3 son tres archivos ejecutables independientes o tres bibliotecas dinámicas, entonces no pueden tener dependencias en absoluto y pueden escribirse en un archivo MAKE para facilitar la administración unificada.
Comience con una pestaña antes del comando. Si usa espacios en lugar de tabulación, informará cuando ejecute el comando make

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

por ejemplo

El siguiente código C ++ simple se toma como ejemplo para ilustrar el uso específico de makefile.

Archivo de código fuente 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 file, el archivo es 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

Ejecuta el comando 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 y test.o se generan correctamente

Explicación de ejemplo

La prueba "target 1" en el archivo MAKE es un archivo ejecutable, y es lo que finalmente necesitamos. test depende de (all)这个变量,文件开头定义了all = test.o,所以test依赖的是test.o,生成test的命令是(CC) -o test $ (all), después de la sustitución de variables es g ++ -o test test.o, que es el comando de compilación más básico que conocemos.
De forma similar, "target 2" test.o depende de test.cpp, y el comando para generar el objetivo es g ++ -c test.cpp.
Las dos reglas anteriores completan la compilación desde el código fuente hasta el archivo ejecutable.

Makefile debe usarse para proyectos grandes

其实我们直接执行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,否则不重新编译。


Supongo que te gusta

Origin blog.51cto.com/14947900/2540196
Recomendado
Clasificación