Índice
Los makefile sirven para automatizar el proceso de compilación de un proyecto estableciendo unas reglas que dictan cómo y en qué orden han de crearse los ficheros objetos, librerías y binarios.
La creación de un fichero MakeFile puede llegar a ser compleja conforme va incrementando el tamaño del proyecto. En este artículo vamos a ver cómo se pueden compilar con una sola regla todos los archivos cpp del proyecto.
Se irá mostrando línea a línea el fichero MakeFile para ir explicándolo y luego se mostrará todo:
BIN = bin
SRC = src
OBJ = obj
CXX = g++
CPPFLAGS = -Wall -g -ansi
Con esto se establecen los nombres de los directorios correspondientes en la carpeta del proyecto. Nota: los directorios deben estar creados previamente.
SOURCES = $(wildcard $(SRC)/*.cpp)
OBJS = $(addprefix $(OBJ)/, $(notdir $(SOURCES:.cpp=.o)))
Con esto almacenamos en la variable SOURCES
todos los ficheros cpp que residan en el directorio src. En la variable OBJS
se hacen varias cosas, $(SOURCES:.cpp=.o)
reemplaza la extensión de los ficheros .cpp
por .o
, $(notdir $(SOURCES:.cpp=.o))
elimina cualquier ruta que existiera para dejar únicamente el nombre del fichero, por ejemplo /src/fichero.cpp pasaría a ser fichero.cpp. Con $(addprefix $(OBJ)/
añadimos el prefijo indicado, en este caso obj al nombre del fichero, siguiendo con el ejemplo anterior, de fichero.o obtendríamos obj/fichero.o.
target = programa
all: $(BIN)/$(target)
$(BIN)/$(target): $(OBJS)
@echo Creando $@... con $^
$(CXX) $(CPPFLAGS) $(OBJS) -o $@
Ésta regla define cómo compilar el programa final, para generar dicho programa dependemos de los ficheros objeto guardados en la variable $(OBJS)
, $@ contiene el nombre del destino (target), en este caso bin/programa.
$(OBJ)/%.o: %.cpp
@echo Creando $@... con $^
$(CXX) $(CPPFLAGS) -c $< -o $@
Con esta regla se crean los ficheros objeto necesarios para la regla anterior. La regla crea objetos a partir de sus correspondientes cpps, de ahí %.o : %.cpp
.
El makefile completo es el siguiente:
BIN = bin
SRC = src
OBJ = obj
CXX = g++
CPPFLAGS = -Wall -g -ansi
CFLAGS = -Wall -O3 -c
SOURCES = $(wildcard *.cpp)
OBJS = $(addprefix $(OBJ)/, $(notdir $(SOURCES:.cpp=.o)))
target = programa
all: $(BIN)/$(target)
$(BIN)/$(target): $(OBJS)
@echo Creando $@... con $^
$(CXX) $(CPPFLAGS) $(OBJS) -o $@
$(OBJ)/%.o: %.cpp
@echo Creando $@... con $^
$(CXX) $(CPPFLAGS) -c $< -o $@
# ************ Limpieza ************
.PHONY: clean
clean :
@echo Limpiando archivos intermedios...
rm $(OBJ)/*
rm $(SRC)/*.*~
La parte de limpieza simplemente elimina los ficheros generados automáticamente en el proceso de compilación.
Referencias
- Compile all CPP files using makefile under MinGW »» stackoverflow.com
- Manual GNU Make »» gnu.org
¿Has visto algún error?: Por favor, ayúdame a corregirlo contactando conmigo o comentando abajo.