Fundamentos de Make para la Construcción de Proyectos de Software

Make es una herramienta de construcción utilizada para automatizar la compilación y generación de archivos a partir de código fuente. Por ejemplo, ejecutar make ejecutable debería construir el archivo ejecutable, pero sin instrucciones específicas, Make no sabe cómo hacerlo.

Make obtiene las reglas de construcción de un archivo llamado Makefile. Aprender a escribir Makefiles es esencial para su uso.

Estructura de un Makefile

Un Makefile se compone de reglas, cada una con el siguiente formato:

objetivo ... : dependencias ...
    comando
    ...

La primera línea define el objetivo (antes de los dos puntos) y las dependencias (después de los dos puntos). La segunda línea debe comenzar con un taublador, seguido de un comando. Esto establece que el objetivo depende de ciertos archivos; si alguna dependencia es más reciente que el objetivo, se ejecuta el comando.

Los objetivos suelen ser nombres de archivos, como el ejecutable mencionado. Pueden ser múltiples, separados por espacios, o representar operaciones abstractas, conocidas como pseudo-objetivos.

.PHONY : limpiar
limpiar :
    -rm $(objeto)

Aquí, .PHONY indica que limpiar es un pseudo-objetivo, por lo que Make no buscará un archivo con ese nombre.

Las dependencias son archivos que determinan si el objetivo necesita recompilarse. Los comandos son instrucciones de Shell que actualizan el objetivo.

Sintaxis Básica

Comentarios: Se inician con #.

salida.o: entrada.c cabecera.h
    # Esto es un comentario.
    cc -c entrada.c

Variables: Se definen y expanden similarmente a macros en C.

archivos := inicio.o modulo1.o modulo2.o
COMPILADOR := g++
BANDERAS := -Wall -g -O2 -std=c++17
programa: $(archivos)
    $(COMPILADOR) -o programa $(archivos) $(BANDERAS)

Esto es equivalente a:

programa: inicio.o modulo1.o modulo2.o
    g++ -o programa inicio.o modulo1.o modulo2.o -Wall -g -O2 -std=c++17

Make ofrece operadores de asignación: = (expansión diferida), ?= (asginación condicional), := (expansión inmediata), y += (concatenación).

Reglas Implícitas

Escribir todos los comandos manualmente es tedioso. Make puede inferir reglas comunes, llamadas reglas implícitas. Por ejemplo, para archivos objeto en C, <n>.o depende de <n>.c y se genera con $(CC) -c $(CPPFLAGS) $(CFLAGS).

Para C++, <n>.o depende de <n>.cc o <n>.C, usando $(CXX) -c $(CPPFLAGS) $(CXXFLAGS).

Otras reglas cubren ensamblador y enlace de objetos. Al usarlas, es crucial definir las variables relevantes.

Aplicando reglas implícitas, el Makefile anterior se simplifica:

archivos := inicio.o modulo1.o modulo2.o
COMPILADOR := g++
BANDERAS := -Wall -g -O2 -std=c++17
programa: $(archivos)
    $(COMPILADOR) $(archivos) -o $@
%.o: %.cc
    $(COMPILADOR) $(BANDERAS) -c $<

Donde $< representa la dependencia (el archivo .cc) y $@ el objetivo (el archivo .o).

Estos son los fundamentos de Make; su sintaxis avanzada requiere estudio adicional.

Etiquetas: GNU Make Makefile C++ compilación reglas implícitas

Publicado el 6-6 01:01