-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMakefile
160 lines (124 loc) · 6.61 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
###############################################################################
# Makefile Múltiple #
# #
# Por Vicente Errázuriz #
# Para el curso de Estructuras de Datos y Algoritmos, 2017 - 1, PUC #
# Makefile diseñada para el trabajo de varios programas con código común #
###############################################################################
# El compilador a usar: Gnu C Compiler, Standard 2011 with GNU extensions
CC=gcc -std=gnu11
# La carpeta donde va todo el código
SRC=src
# La carpeta donde van todos los archivos de objeto
OBJ=obj
###############################################################################
# OPTIMIZACIÓN POR COMPILADOR (descomenta el que necesites, comenta el otro) #
###############################################################################
OPT=-g# No optimiza.
# OPT=-O1# Optimiza un poquito
# OPT=-O2# Optimiza bastante
# OPT=-O3# Optimiza al máximo. Puede ser peor que -O2 según tu código
# Nivel de optimización para las librerías del código base (COMMON)
BASE_OPT=-O2
###############################################################################
# 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
# -g = (Debug) Guarda la información para debugear
CFLAGS=-Wunused -Wall -g
###############################################################################
# LIBRERÍAS #
###############################################################################
# Matemáticas (C Math library)
MTH=-lm
LIB=$(MTH)
###############################################################################
# MÓDULOS Y PROGRAMAS #
###############################################################################
# Directorios con elementos de uso común
COMMON=# common
# Directorios que serán compilados a un programa
PROGRAMS=mem program
# Todos los directorios que contienen archivos de código
SRCDIR=$(COMMON) $(PROGRAMS)
###############################################################################
# DEPENDENCIAS Y DIRECTORIOS #
###############################################################################
# Todos los archivos .h de las carpetas comunes
DEPS := $(foreach i, $(COMMON), $(shell find $(SRC)/$(i) -name '*.h'))
# Todos los archivos .h
HDRFILES := $(shell find $(SRC) -name '*.h')
# Todos 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))
###############################################################################
# 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) y $(PROGRAMS)
all: $(OBJDIR) $(PROGRAMS)
@echo "done compiling"
# Esta regla elimina todo registro de compilación que se haya hecho
clean:
@rm -fv $(PROGRAMS) && rm -rfv obj && echo "done cleaning"
# Esta regla crea los directorios donde se guardan los archivos de objeto .o
$(OBJDIR):
@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))
# Flag de optimización para el código común
COMMON_OPT = $(if $(findstring $(word 2, $(subst /, ,$@)), $(COMMON)),$(BASE_OPT),$(OPT))
# 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) $(call COMMON_OPT) $< -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
$(PROGRAMS): $$(filter obj/$$@/% $(foreach i, $(COMMON), obj/$(i)/%), $(OBJFILES))
@$(CC) $(CFLAGS) $(OPT) $^ -o $@ $(LIB) && echo "compiled '$@'"
###############################################################################
# Cualquier duda no temas en preguntar! #
###############################################################################
# Disclaimer: #
# #
# Deberías modificar solamente el nivel de Optimización (OPT, linea 20). #
# 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. #
###############################################################################
# Vamos a añadir algunas cosas aquí como shortcuts
.PHONY: test-run test-valgrind test-vailgrind-massif-graph test-python test-flamegraph
test-all: test-run test-valgrind test-vailgrind-massif-graph test-python # test-flamegraph
test-run:
@echo "\n# Test run"
valgrind ./program
test-python:
@echo "\n# Test python"
python3 ./scripts/clean.py
test-valgrind:
@echo "\n# Valgrind"
valgrind ./mem
test-vailgrind-massif-graph:
@echo "\n# Valgrind massif"
valgrind --tool=massif --massif-out-file=massif.out ./mem
ms_print massif.out
test-flamegraph:
@echo "\n# Valgrind flamegraph"
flamegraph ./mem