1. ¿Qué es Makefile?
Makefile
El documento describe Linux
las C/C++
reglas de compilación del sistema del proyecto, que se utiliza para compilar el C/C++
proyecto de automatización . Una vez que la escritura es buena escribiendo Makefile
papeles, solo un make
comando, todo el proyecto comenzará a compilarse automáticamente, ya no es necesario ejecutar manualmente GCC
el comando. En un gran C/C++
archivo fuente del proyecto hay cientos, según sus funciones, módulos, tipos se colocaron en diferentes directorios, el Makefile
archivo define un conjunto de reglas que indica el orden de compilación de las dependencias del archivo fuente, la necesidad de volver a compilar y pronto.
Makefile
Puede considerarse simplemente como las reglas de compilación de un archivo de proyecto, que describen las reglas de compilación y vinculación de todo el proyecto. Que contiene los archivos que deben compilarse, los archivos que no necesitan compilarse, los archivos que deben compilarse primero, los archivos que deben compilarse más tarde, los archivos que deben reconstruirse, etc. Recopile todas las necesidades del proyecto involucradas, en Makefile
ambas se pueden describir. En otras palabras, Makefile
la compilación de nuestro proyecto se puede automatizar sin tener que ingresar manualmente un montón de archivos fuente y parámetros cada vez.
2. Por qué utilizar Makefile
Para Linux
reducir el C
desarrollo del lenguaje como ejemplo para explicar el compilador de múltiples archivos específico que genera un archivo, el comando del compilador es el siguiente:
gcc -o outfile name1.c name2.c ...
outfile
El nombre del programa ejecutable que se generará es el nombre nameN.c
del archivo fuente. Esto es lo que Linux
usamos en el gcc
compilador para compilar C
los archivos de muestra. Si el número de archivos fuente que encontramos no es muy grande, podemos elegir este método de compilación. Si hay demasiados archivos fuente, encontrará los siguientes problemas.
2.1 El problema de vincular bibliotecas al compilar
Aquí hay algunas bibliotecas estándar que debemos vincular manualmente:
name1.c
Utilizamath
funciones de biblioteca matemática , tenemos que agregar parámetros manualmente-lm
;name4.c
Use unaSQLite
función de base de datos pequeña , tenemos que agregar parámetros manualmente-lsqlite3
;name5.c
Cuando se utilizan subprocesos, necesitamos agregar parámetros manualmente-lpthread
;
Debido a que hay muchos archivos, se deben vincular muchas bibliotecas de terceros. Por lo tanto, el comando será muy largo al compilar y es posible que estemos involucrados en el orden de vinculación de archivos al compilar, por lo que la compilación manual será muy problemática.
Si aprendemos a usar Makefile
no el caso, simplificaría radicalmente el funcionamiento del compilador. Para vincular el archivo de la biblioteca Makefile
, el desarrollo de las reglas apropiadas y el orden de enlace correspondiente. Así que solo necesita ejecutar make
el comando, el proyecto compilará automáticamente una compilación manual de opciones de parámetros y comandos omitidos, muy conveniente.
2.2 La compilación de un proyecto grande llevará mucho tiempo
Makefile
La compatibilidad con la operación simultánea de múltiples subprocesos acortará en gran medida nuestro tiempo de compilación, y cuando modifiquemos el archivo fuente, al compilar todo el proyecto, el make
comando solo compilará los archivos que hemos modificado y los archivos no modificados no necesitan volver a compilarse. Resolvió nuestro problema que consumía mucho tiempo.
Y el archivo Makefile
solo debe hacerse una vez, generalmente no agregamos un archivo o eliminamos el proyecto, Makefile
básicamente no tenemos que modificarlo, en tiempo de compilación use solo un make
comando. Nos proporciona una gran comodidad y mejora en gran medida la eficiencia de la compilación.
3. Reglas de Makefile
Sus reglas se componen principalmente de dos partes, la relación de dependencia y el comando ejecutado, y su estructura es la siguiente:
targets : prerequisites
command
o
targets : prerequisites; command
command
Las instrucciones relevantes son las siguientes:
targets
: El objetivo de la regla es imprescindible, puede serObject File
(generalmente llamado archivo intermedio), puede ser un archivo ejecutable o puede ser una etiqueta;prerequisites
: Nuestro archivo de dependencia para generartargets
un archivo o un objetivo deseado. Puede haber varios, separados por espacios o ninguno;command
:make
Comando (debe ejecutar cualquiera de losshell
comandos). Puede haber varios comandos, cada comando ocupa una línea;
Si es command
demasiado largo, puede utilizar \
una nueva línea.
Nota: Para usar dos puntos entre nuestros objetivos y los archivos dependientes están separados, el comando de inicio debe usar las
Tab
teclas, no puede usar la barra espaciadora.
Para resumir brevemente Makefile
el contenido, contiene principalmente cinco partes, a saber:
3.1 Reglas explícitas
Las reglas explícitas explican cómo generar uno o más archivos de objeto. Esto se debe a que Makefile
los escritores señalaron claramente que el archivo resultante, las dependencias del archivo, generaron comandos.
3.2 Reglas oscuras
Como nuestro make
nombre con función de derivación automática, las reglas tan oscuras nos permiten escribir brevemente terreno irregular Makefile
, que es un make
comando compatible.
3.3 Definición de variables
En el Makefile
medio tenemos que definir un conjunto de variables, que generalmente son cadenas, esto es un poco como las macros del lenguaje C, cuando se Makefile
ejecutan, donde las variables se extenderán a la posición de referencia correspondiente.
3.4 Documentar instrucciones
Que consta de tres partes, una es una Makefile
referencia a la otra Makefile
, como en el lenguaje C include
como; se refiere a los otros casos de acuerdo con cierta Makefile
porción válida especificada , como lenguaje C precompilado #if
lo mismo; y Es para definir un comando multilínea .
3.5 Notas
Makefile
Sólo en línea comentarios, y UNIX
de Shell
los mismos scripts que el comentario es #
caracteres, si desea que su Makefile
uso de #
caracteres puede ser con una barra invertida, tales como: \#
.
3.6 comodines en las reglas
*
Representa uno o más caracteres?
Representa cualquier personaje[...]
[abcd] significa cualquier carácter en a, b, c, d, [^ abcd] significa un carácter que no sea a, b, c, d, [0-9] significa cualquier número del 0 al 9~
Representa el directorio de inicio del usuario
4.Ejemplo de Makefile
main.cpp
Código:
#include <iostream>
int main()
{
std::cout << "hello,world" << std::endl;
return 0;
}
Específicamente mediante los siguientes ejemplos sobre el uso del archivo de Makefile
reglas Makefile
, agregue el siguiente código:
main: main.cpp
g++ main.cpp -o main
Cuál main
es el archivo de destino y nuestro archivo ejecutable resultante. Archivos dependientes que main.cpp
operan con los archivos de origen, los archivos de objetos deben hacer para reconstruirlos g++ main.cpp -o main
. Este es el Makefile
uso de reglas gramaticales básicas.
Modo de uso
Makefile
: primero debe escribir un buenMakefile
archivo y luego ejecutar elmake
comando de shell , el programa se ejecutará automáticamente y obtendrá el archivo de destino final.
wohu@ubuntu:~/cpp/demo$ ls
main.cpp `Makefile`
wohu@ubuntu:~/cpp/demo$ make
g++ main.cpp -o main
wohu@ubuntu:~/cpp/demo$ ls
main main.cpp `Makefile`
wohu@ubuntu:~/cpp/demo$ ./main
hello,world
wohu@ubuntu:~/cpp/demo$
Si se usa la barra espaciadora al comienzo del comando, se informará un error
Makefile:2: *** missing separator. Stop.
Makefile
: 2 para el error de la segunda línea, debería Tab
comenzar.
5. Proceso de Makefile
Cuando ejecutamos make
cuando el comando, make
se realizará para buscar compilar las reglas bajo el archivo actual, que es Makefile
archivo. Escribimos el Makefile
nombre del archivo cuando se puede usar GNUMakefile
, makefile
, Makefile
, make
para volver a buscar a la hora de realizar Makefile
archivo, busque la secuencia de archivo es como esto.
Recomendado de usar Makefile
(generalmente escrito de esta manera en el proyecto, las mayúsculas estarán más estandarizadas). Si el archivo no existe, make
se nos informará de un error, solicitando:
make: *** No targets specified and no `Makefile` found. Stop.
Al Makefile
agregar el siguiente código:
main: main.o name.o greeting.o
g++ main.o name.o greeting.o -o main
main.o: main.cpp
g++ -c main.cpp -o main.o
name.o: name.cpp
g++ -c name.cpp -o name.o
greeting.o: greeting.cpp
g++ -c greeting.cpp -o greeting.o
Cuando compilamos el archivo del proyecto, por defecto, la make
ejecución es la Makefile
primera regla ( Makefile
aparecen las primeras dependencias), el primer objetivo de esta regla se denomina "objetivo final" o "objetivo final".
En la shell
línea de comandos del make
sistema, puede obtener los archivos ejecutables main
y archivos intermedios main.o
, name.o
y greeting.o
, main
que es nuestro documento final que será generada.
Por Makefile
puede encontrar nuestro objetivo main
en Makefile
el primer gol, por lo que es el make
objetivo final, cuando la modificación de los archivos, ejecutar make
reconstruirá el objetivo final main
.
Su orden de trabajo específica es: cuando shell
la entrada solicita el make
comando subsiguiente. make
Leer en los Makefile
archivos del directorio actual , y Makefile
archivar el primer objetivo como "objetivo final" de su ejecución, comenzar a procesar la primera regla (regla donde el objetivo final).
En nuestro ejemplo, la primera regla es el objetivo de main
las reglas se encuentra. Las reglas describen las main
dependencias y definen el comando de .o
destino de generación de archivos de enlace main
; make
antes de ejecutar este comando, las reglas definidas por el primer destino de procesamiento, main
todos los archivos dependientes (esos ejemplos del .o
archivo) actualizan la regla (estos .o
archivos Reglas de destino).
Estas .o
reglas de segmentación se refieren al archivo de los siguientes tres casos:
- El
.o
archivo de destino no existe, créelo usando sus reglas de descripción; - El
.o
archivo de destino existe, el.o
archivo de destino depende del archivo ".cpp" fuente ".h" de cualquier archivo de.o
"Actualización" de proporción de destino (última marca después de ser modificado), luego se vuelven a compilar las reglas según las cuales; - El
.o
archivo de destino existe, el.o
archivo de destino que cualquiera de sus dependencias (".c" fuente, ". H" archivo) "Actualizar" (Depende de que el archivo no se haya modificado después de una renovación), no haga nada ;
A través de las reglas de actualización anteriores podemos entender el rol del archivo intermedio, que se genera al compilar .o
el archivo. La función es comprobar si se ha modificado un determinado archivo de origen y si es necesario reconstruir el archivo de destino final.
Ejecutamos el make
comando, solo se reconstruirán los archivos de origen modificados o el archivo de destino inexistente, pero esos archivos no se cambian sin volver a compilar, para ahorrar tiempo en gran parte, para mejorar la eficiencia de la programación.