-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile
145 lines (110 loc) · 6.28 KB
/
Makefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
###############################################################################
# Makefile Múltiple #
# #
# Por Vicente Errázuriz (2017 - 1), modificada por Benjamín Vicente (2024-1) #
# Para el curso de Estructuras de Datos y Algoritmos, PUC #
# Makefile diseñada para el trabajo de varios programas con código común #
###############################################################################
# Directorios que serán compilados a un programa
PROGRAMS=example
# Directorios con elementos de uso común
COMMON=
# La carpeta donde va todo el código
SRC=src
# La carpeta donde quedan los ejecutables
BIN=.
# El compilador a usar: Gnu C Compiler, Standard 2011 with GNU extensions
CC=gcc -std=gnu11
# La carpeta donde van todos los archivos de objeto
OBJ=obj
###############################################################################
# OPTIMIZACIÓN POR COMPILADOR (descomenta el que necesites, comenta el otro) #
###############################################################################
OPT=-g # Guardar toda la información para poder debugear. No optimiza
# OPT=-O3 # Optimiza al máximo, descarta toda la información de debug.
###############################################################################
# PARÁMETROS #
###############################################################################
# -Wunused = (Warn Unused) Da aviso de las variables que no se estan usando
# -Wall = (Warn All) Da aviso de todos los posibles errores de compilación
# -fsanitize=address = (Sanitize Address) Da error si hay problemas de memoria
# -pedantic-errors = (Pedantic Errors) Versión más estricta del estándar C
# $(OPT) = Nivel de optimización
CFLAGS=-Wunused -Wall -fsanitize=address -pedantic-errors $(OPT)
###############################################################################
# LIBRERÍAS #
###############################################################################
# -lm = Matemáticas (C Math library)
# -lpng = Portable Network Graphics (PNG)
LIB=-lm
###############################################################################
# MÓDULOS Y PROGRAMAS #
###############################################################################
# Los directorios que contienen archivos de código
SRCDIR=$(COMMON) $(PROGRAMS)
###############################################################################
# DEPENDENCIAS Y DIRECTORIOS #
###############################################################################
# Los archivos .h de las carpetas comunes
DEPS := $(foreach i, $(COMMON), $(shell find $(SRC)/$(i) -name '*.h'))
# Los archivos .h
HDRFILES := $(shell find $(SRC) -name '*.h')
# Los archivos .c
SRCFILES := $(shell find $(SRC) -name '*.c')
# Archivos de objeto .o, un estado intermedio de compilación
OBJFILES := $(foreach i, $(SRCFILES), $(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(i)))
# Los directorios para los archivos de objeto .o
OBJDIR := $(patsubst $(SRC)/%, $(OBJ)/%, $(shell find $(SRC) -type d))
# Archivos ejecutables
BIN_PROGRAMS := $(addprefix $(BIN)/,$(PROGRAMS))
###############################################################################
# REGLAS #
###############################################################################
# Las reglas son como funciones.
# Cuando llamas 'make X' en la consola, se ejecuta la regla X.
# Las reglas tienen prerrequisitos: esto es lo que aparece a su derecha
# Una vez se cumplan los prerrequisitos, se ejecuta el contenido de la regla
# Si llamas 'make' a secas se ejecutará la primera regla: 'all'
# Esta regla imprime que todo está listo
# Pero solo una vez que se hayan llamado las reglas $(OBJDIR) $(BIN) y $(BIN_PROGRAMS)
all: $(OBJDIR) $(BIN) $(BIN_PROGRAMS)
@echo "done compiling"
# Esta regla elimina todo registro de compilación que se haya hecho
clean:
@rm -rfv $(BIN_PROGRAMS) && rm -rfv $(OBJ)
@if [ -d "$(bin_dir)" ] && [ "$(bin_dir)" != "." ]; then rm -r "$(bin_dir)"; fi
@echo "done cleaning"
# Esta regla crea los directorios donde se guardan los archivos de objeto .o
$(OBJDIR):
@mkdir -p $@
# Crea la carpeta donde se guardan los ejecutables
$(BIN):
@mkdir -p $@
# Esta regla mágica indica que las siguientes reglas necesitan dos pasadas
# Qué significa eso y por qué es importante no tiene importancia
.SECONDEXPANSION:
# Dependencias locales para un archivo .o
LOCAL_DEPS = $(filter $(patsubst $(OBJ)/%, $(SRC)/%, $(dir $(1)))%, $(HDRFILES))
# Esta regla compila cada archivo de objeto .o
# Pero sólo si alguno de los siguientes fue modificado desde la última vez
## el .c respectivo del .o
## algún .h bajo la carpeta respectiva en src
## algún .h de los directorios comunes
## esta mismísima Makefile
obj/%.o: $(SRC)/%.c $$(call LOCAL_DEPS,$$@) $(DEPS) Makefile
@$(CC) $(CFLAGS) $< -c -o $@ $(LIB) && echo "compiled '$@'"
# Esta regla conecta y compila cada programa a partir de los .o
# Pero solo una vez que se haya llamado la regla anterior con lo siguiente
## todos los .o de la carpeta respectiva del programa
## todos los .o de los directorios comunes
$(BIN_PROGRAMS): $$(filter $(OBJ)/$$(notdir $$@)/% $(foreach i, $(COMMON), $(OBJ)/$(i)/%), $(OBJFILES))
@$(CC) $(CFLAGS) $^ -o $@ $(LIB) && echo "compiled '$@'"
###############################################################################
# Cualquier duda no temas en preguntar! #
###############################################################################
# Disclaimer: #
# #
# Deberías modificar solamente el nivel de Optimización. #
# Modificar la Makefile si no sabes lo que está pasando o como la usamos los #
# ayudantes puede resultar en un perjuicio en la evaluación de tu código. #
###############################################################################