La automatización de la compilación de proyectos programados de alta complejidad, puede simplificarse por medio de archivos de configuración de la compilación. En ambientes basados en Linux esto se puede lograr con la herramienta make.
¿Qué es make?
make es una herramienta de GNU para actualizar, en forma optimizada y automática, los diversos archivos de programas que integran un proyecto de software.
¿Qué es un makefile?
Un makefile es un archivo que contiene los comandos de compilación, resolución de dependencias, entre otros; por convención el archivo se crea con este nombre.
Características de make
- Make permite al usuario final construir, instalar y correr su paquete sin conocer los detalles de cómo se hace, porque estos detalles se registran en el makefile que usted proporciona.
- Determina automáticamente qué archivos necesita actualizar, según los archivos fuente que hayan cambiado. También determina automáticamente el orden adecuado para actualizar los archivos, en caso de que un archivo no fuente dependa de otro archivo no fuente.
- Si cambia algunos archivos fuente y luego ejecuta Make, no es necesario que vuelva a compilar todo su programa. Actualiza solo aquellos archivos que no son de origen que dependen directa o indirectamente de los archivos de origen que ha cambiado.
- Make no se limita a ningún lenguaje de programación en particular. Para cada archivo no fuente en el programa, el archivo MAKE especifica los comandos de consola. Estos comandos de consola pueden ejecutar un compilador para producir un archivo de objeto, el enlazador para producir un ejecutable
¿Cómo crear un makefile?
Para el ejemplo de este artículo usaremos el sistema operativo Raspbian, el editor de texto integrado nano, el set de instrucciones thumb de ARM y la terminal del sistema.
Primero editamos un archivo de texto con el nombre makefile en la carpeta principal del proyecto, para eso ejecutamos el comando nano makefile:
Ahora, lo primero que vamos a tener en el archivo son nuestras variables, en las cuales tendremos los datos que servirán para el ensamblado y el enlazado del programa de este artículo.
Para declarar una variable en el sistema se hace con la siguiente sintaxis:
Por estándar los nombres de las variables se escriben en mayúscula.
Por estándar para ensamblar y enlazar archivos para generar un archivo ejecutable a base de código de ensamblador de ARM se utilizan las siguientes variables.
EXECUTABLE: Contiene el nombre del programa ejecutable final, es decir el nombre del programa final que queremos generar.
FILES: Contiene el nombre de los archivos de código fuente que van a ser compilados/ensamblados.
FLAGS: Contiene el conjunto de banderas que se le van a pasar a pasar al compilador/ensamblador entre esas podemos destacar -wall, -g, -o
COMP: Contiene el nombre del compilador/ensamblador a utilizar.
LINKER: Contiene el nombre del compilador/ensamblador a utilizar.
OBJ = Contiene el nombre del archivo de código objeto que se va a generar a partir de los archivos de código fuente, en el caso de que se use esta variable se tiene que tener una regla para generar el archivo.
Reglas
Las reglas son básicamente etiquetas que ejecutan sentencias de instrucciones del sistema mediante la terminal.
Las reglas tienen la siguiente sintaxis:
Bajo esta estructura es muy importante recalcar que siempre las líneas de la receta tienen que estar a una tabulación del inicio de la línea.
Para el ejemplo utilizaremos los archivos que se indican a continuación y variables explicadas anteriormente.
Para la siguiente regla será necesario explicar que para utilizar el valor de una variable se hace con la siguiente sintaxis: $(VARIABLE).
En la primera línea de la regla tenemos el nombre de la regla seguido de dos puntos y el nombre de la dependencia que tenemos, la cual es el archivo de código objeto.
En la segunda línea tenemos el nombre del enlazador, el nombre del archivo de código objeto, la bandera de enlazado y el nombre del ejecutable que vamos a crear.
En la tercera línea tenemos una línea en la cual usamos comando de Linux para borrar el o los programas de código objeto que genere este archivo make, esto usualmente se hace por optimización.
Como se dijo en la explicación de la primera línea de la regla anterior, el usar un archivo de código objeto nos genera la obligación de generarlo, por lo cual en la primera línea solo se usa el nombre de la regla, la cual en este caso tiene que ser el nombre del archivo de código objeto y extensión.
En la segunda línea se llama al compilador o ensamblador, se le da los nombres de los archivos a ser ensamblados, seguido de las banderas y el nombre del archivo de código objeto que queremos generar.
Si guardamos el archivo y llamamos el comando make vemos que lo que hacen las reglas y las variables es hacer de manera automática 3 líneas de instrucciones que son realizables de manera manual, lo cual a veces se hace tedioso, por ende, el makefile es una buena solución a este problema.
Referencias
https://blog.desdelinux.net/que-es-un-archivo-makefile-y-como-funciona-dentro-de-linux/
http://www.chuidiang.org/clinux/herramientas/makefile.php
https://iie.fing.edu.uy/~vagonbar/gcc-make/make.htm
https://www.tutorialspoint.com/makefile/makefile_rules.htm
https://www.gnu.org/software/make/manual/html_node/Rule-Syntax.html