-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
294 lines (221 loc) · 12.5 KB
/
Makefile
File metadata and controls
294 lines (221 loc) · 12.5 KB
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
#━━━━━━━━━━Make Configuration━━━━━━━━━━━━━━━━━━━━━━━
.PHONY: test install install_cli install_desktop uninstall clean coverage valgrind all
.DEFAULT_GOAL := install
#━━━━━━━━━━Compiler and Base Flags━━━━━━━━━━━━━━━━━━
CC := gcc
CXX := g++
C_STD_FLAGS := -std=c11
CXX_STD_FLAGS := -std=c++20 -fPIC
INCLUDE_DIRS := -I./src
WARN_FLAGS := -Werror -Wextra -Wall
CONVERSION_FLAG := -Wconversion
TURN_OFF_RANDOM_FLAG := -DNONRANDOM_RANDOM
CURSES_FLAG := -lncurses
RESOURCES_NAMESPACE := resources
CFLAGS := $(C_STD_FLAGS) $(WARN_FLAGS) $(CONVERSION_FLAG) $(WARN_PADDING) $(INCLUDE_DIRS)
CXXFLAGS := $(CXX_STD_FLAGS) $(WARN_FLAGS) $(EFFICIENT_CPP) $(INCLUDE_DIRS)
#━━━━━━━━━━Qt Configuration━━━━━━━━━━━━━━━━━━━━━━━━━━
ifeq ($(shell uname),Darwin) # Mac
BREW_QT := $(shell ls -d $(shell brew --cellar qt)/* | head -n 1 2>/dev/null)
QT_DIR := $(BREW_QT)
MOC := $(QT_DIR)/share/qt/libexec/moc
RCC := $(QT_DIR)/share/qt/libexec/rcc
QT_INCLUDES := -I$(QT_DIR)/lib/QtWidgets.framework/Headers \
-I$(QT_DIR)/lib/QtGui.framework/Headers \
-I$(QT_DIR)/lib/QtCore.framework/Headers \
-I$(QT_DIR)/lib/QtSvg.framework/Headers
QT_LIBS = -F$(QT_DIR)/lib \
-framework QtWidgets \
-framework QtGui \
-framework QtCore \
-framework QtSvg
RPATH = -Wl,-rpath,$(QT_DIR)/lib
else # Linux
QT6_PREFIX := $(shell pkg-config --variable=prefix Qt6Core)
QT6_TOOLS_DIR := $(QT6_PREFIX)/lib/qt6/
MOC := $(QT6_TOOLS_DIR)/moc
RCC := $(QT6_TOOLS_DIR)/rcc
QT_INCLUDES := $(shell pkg-config --cflags Qt6Widgets Qt6Svg)
QT_LIBS := $(shell pkg-config --libs Qt6Widgets Qt6Svg)
# Set RPATH to Qt library directory
QT_LIB_DIR := $(shell pkg-config --variable=libdir Qt6Core)
RPATH := -Wl,-rpath,$(QT_LIB_DIR)
endif
#━━━━━━━━━━Directory Structure━━━━━━━━━━━━━━━━━━━━━━
SRC_DIR := src
BUILD_DIR := build
BIN_DIR := bin
BACKEND_BUILD_DIR := $(BUILD_DIR)/backend
FRONTEND_BUILD_DIR := $(BUILD_DIR)/frontend
TESTS_BUILD_DIR := $(BUILD_DIR)/tests
COVERAGE_DIR = $(BUILD_DIR)/coverage
BACKEND_TETRIS_SRC_DIR := $(SRC_DIR)/brick_game/tetris
BACKEND_TETRIS_BUILD_DIR := $(BACKEND_BUILD_DIR)/tetris
BACKEND_SNAKE_SRC_DIR := $(SRC_DIR)/brick_game/snake
BACKEND_SNAKE_BUILD_DIR := $(BACKEND_BUILD_DIR)/snake
FRONTEND_CLI_SRC_DIR := $(SRC_DIR)/gui/cli
FRONTEND_CLI_BUILD_DIR := $(FRONTEND_BUILD_DIR)/cli
FRONTEND_DESKTOP_SRC_DIR := $(SRC_DIR)/gui/desktop
FRONTEND_DESKTOP_BUILD_DIR := $(FRONTEND_BUILD_DIR)/desktop
FRONTEND_DESKTOP_MOC_DIR := $(FRONTEND_BUILD_DIR)/desktop/moc
FRONTEND_DESKTOP_RCC_DIR := $(FRONTEND_BUILD_DIR)/desktop/rcc
LIB_BUILD_DIR := $(BUILD_DIR)/lib
TESTS_DIR := tests
TETRIS_TESTS_DIR := $(TESTS_DIR)/tetris
SNAKE_TESTS_DIR := $(TESTS_DIR)/snake
#━━━━━━━━━━Files and Dependencies━━━━━━━━━━━━━━━━━━━
BACKEND_TETRIS_SRC_FILES := $(wildcard $(BACKEND_TETRIS_SRC_DIR)/*.c)
BACKEND_TETRIS_OBJ_FILES := $(patsubst $(BACKEND_TETRIS_SRC_DIR)/%.c,$(BACKEND_TETRIS_BUILD_DIR)/%.o,$(BACKEND_TETRIS_SRC_FILES))
BACKEND_TETRIS_LIB := tetris_backend.a
BACKEND_SNAKE_SRC_FILES := $(wildcard $(BACKEND_SNAKE_SRC_DIR)/*.cc)
BACKEND_SNAKE_OBJ_FILES := $(patsubst $(BACKEND_SNAKE_SRC_DIR)/%.cc,$(BACKEND_SNAKE_BUILD_DIR)/%.o,$(BACKEND_SNAKE_SRC_FILES))
BACKEND_SNAKE_LIB := snake_backend.a
SNAKE_CLI_CONTROLLER_SRC_FILES := $(wildcard $(FRONTEND_CLI_SRC_DIR)/*.cc)
SNAKE_CLI_CONTROLLER_OBJ_FILES := $(patsubst $(FRONTEND_CLI_SRC_DIR)/%.cc,$(FRONTEND_CLI_BUILD_DIR)/%.o,$(SNAKE_CLI_CONTROLLER_SRC_FILES))
FRONTEND_CLI_SRC_FILES := $(wildcard $(FRONTEND_CLI_SRC_DIR)/*.c)
FRONTEND_CLI_OBJ_FILES := $(patsubst $(FRONTEND_CLI_SRC_DIR)/%.c,$(FRONTEND_CLI_BUILD_DIR)/%.o,$(FRONTEND_CLI_SRC_FILES))
EXECUTABLE_CLI_SRC_FILE := $(SRC_DIR)/run_cli.cc
EXECUTABLE_CLI_OBJ_FILE := $(patsubst $(SRC_DIR)/%.cc,$(FRONTEND_CLI_BUILD_DIR)/%.o,$(EXECUTABLE_CLI_SRC_FILE))
EXECUTABLE_CLI := run_cli
FRONTEND_DESKTOP_HEADER_FILES := $(wildcard $(FRONTEND_DESKTOP_SRC_DIR)/*.h)
FRONTEND_DESKTOP_MOC_SRC_FILES := $(patsubst $(FRONTEND_DESKTOP_SRC_DIR)/%.h,$(FRONTEND_DESKTOP_MOC_DIR)/%.moc.cc,$(FRONTEND_DESKTOP_HEADER_FILES))
FRONTEND_DESKTOP_SRC_FILES := $(wildcard $(FRONTEND_DESKTOP_SRC_DIR)/*.cc)
FRONTEND_DESKTOP_QRC_FILE := $(FRONTEND_DESKTOP_SRC_DIR)/resources.qrc
FRONTEND_DESKTOP_RESOURCES_CC_FILE := $(patsubst $(FRONTEND_DESKTOP_SRC_DIR)/%.qrc,$(FRONTEND_DESKTOP_RCC_DIR)/%.cc,$(FRONTEND_DESKTOP_QRC_FILE))
FRONTEND_DESKTOP_SRC_OBJ_FILES := $(patsubst $(FRONTEND_DESKTOP_SRC_DIR)/%.cc,$(FRONTEND_DESKTOP_BUILD_DIR)/%.o,$(FRONTEND_DESKTOP_SRC_FILES))
FRONTEND_DESKTOP_MOC_OBJ_FILES := $(patsubst $(FRONTEND_DESKTOP_MOC_DIR)/%.moc.cc,$(FRONTEND_DESKTOP_BUILD_DIR)/%.moc.o,$(FRONTEND_DESKTOP_MOC_SRC_FILES))
FRONTEND_DESKTOP_RESOURCES_OBJ_FILE := $(patsubst $(FRONTEND_DESKTOP_RCC_DIR)/%.cc,$(FRONTEND_DESKTOP_BUILD_DIR)/%.o,$(FRONTEND_DESKTOP_RESOURCES_CC_FILE))
FRONTEND_DESKTOP_OBJ_FILES := $(FRONTEND_DESKTOP_SRC_OBJ_FILES) $(FRONTEND_DESKTOP_MOC_OBJ_FILES) $(FRONTEND_DESKTOP_RESOURCES_OBJ_FILE)
EXECUTABLE_DESKTOP_SRC_FILE := $(SRC_DIR)/run_desktop.cc
EXECUTABLE_DESKTOP_OBJ_FILE := $(patsubst $(SRC_DIR)/%.cc,$(FRONTEND_DESKTOP_BUILD_DIR)/%.o,$(EXECUTABLE_DESKTOP_SRC_FILE))
EXECUTABLE_DESKTOP := run_desktop
TETRIS_TESTS_SRC_FILES := $(wildcard $(TETRIS_TESTS_DIR)/*.c)
TETRIS_TESTS_OBJ_FILES := $(patsubst $(TETRIS_TESTS_DIR)/%.c,$(TESTS_BUILD_DIR)/%.o,$(TETRIS_TESTS_SRC_FILES))
SNAKE_TESTS_SRC_FILES := $(wildcard $(SNAKE_TESTS_DIR)/*.cc)
SNAKE_TESTS_OBJ_FILES := $(patsubst $(SNAKE_TESTS_DIR)/%.cc,$(TESTS_BUILD_DIR)/%.o,$(SNAKE_TESTS_SRC_FILES))
#━━━━━━━━━━Test and Coverage Configuration━━━━━━━━━━
TESTS_CHECK_LINKER_FLAGS := -lcheck -lm
TESTS_GTEST_LINKER_FLAGS := -lgtest_main -lgtest -pthread
COVERAGE_FLAGS := -fprofile-arcs -ftest-coverage
GCOVR_THEME := --html-theme github.dark-green
GCOVR_CONFIG_FLAGS := --html --html-single-page=js-enabled --html-details
GCOVR_FLAGS := $(GCOVR_CONFIG_FLAGS) $(GCOVR_THEME)
#━━━━━━━━━━OS-Specific Configuration━━━━━━━━━━━━━━━━━
DISTRO:=
ifeq ($(shell uname),Darwin)
OPEN_COMMAND := open
else
OPEN_COMMAND := xdg-open
DISTRO := $(shell cat /etc/os-release | grep ^ID= | cut -d'=' -f2 | tr -d '"')
ifneq ($(DISTRO),arch)
TESTFLAGS+= -lsubunit
endif
endif
#━━━━━━━━━━Distribution Parametres━━━━━━━━━━━━━━━━━
PROJECT_NAME := s21_brickgame
VERSION := 1.0
DIST_ARCHIVE := $(PROJECT_NAME)-$(VERSION).tar.gz
README_MD := README.md
DOC_OUTPUT := README
DIST_DIR := $(PROJECT_NAME)-$(VERSION)
#━━━━━━━━━━Main Targets━━━━━━━━━━━━━━━━━━━━━━━━━━━━
all: install test
install: $(BIN_DIR)/$(EXECUTABLE_CLI) $(BIN_DIR)/$(EXECUTABLE_DESKTOP)
install_cli: $(BIN_DIR)/$(EXECUTABLE_CLI)
install_desktop: $(BIN_DIR)/$(EXECUTABLE_DESKTOP)
uninstall:
rm -drf $(BIN_DIR)
#━━━━━━━━━━Backend Tetris targets━━━━━━━━━━━━━━━━━━
$(BACKEND_TETRIS_LIB): $(LIB_BUILD_DIR)/$(BACKEND_TETRIS_LIB)
$(LIB_BUILD_DIR)/$(BACKEND_TETRIS_LIB): $(BACKEND_TETRIS_OBJ_FILES) | $(LIB_BUILD_DIR)
@ar rcs $@ $^
$(BACKEND_TETRIS_BUILD_DIR)/%.o: $(BACKEND_TETRIS_SRC_DIR)/%.c | $(BACKEND_TETRIS_BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@
#━━━━━━━━━━Backend Snake targets━━━━━━━━━━━━━━━━━━━
$(BACKEND_SNAKE_LIB): $(LIB_BUILD_DIR)/$(BACKEND_SNAKE_LIB)
$(LIB_BUILD_DIR)/$(BACKEND_SNAKE_LIB): $(BACKEND_SNAKE_OBJ_FILES) | $(LIB_BUILD_DIR)
@ar rcs $@ $^
$(BACKEND_SNAKE_BUILD_DIR)/%.o: $(BACKEND_SNAKE_SRC_DIR)/%.cc | $(BACKEND_SNAKE_BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
#━━━━━━━━━━Frontend CLI Targets━━━━━━━━━━━━━━━━━━━━
$(FRONTEND_CLI_BUILD_DIR)/%.o: $(FRONTEND_CLI_SRC_DIR)/%.c | $(FRONTEND_CLI_BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@
$(FRONTEND_CLI_BUILD_DIR)/%.o: $(FRONTEND_CLI_SRC_DIR)/%.cc | $(FRONTEND_CLI_BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
$(EXECUTABLE_CLI_OBJ_FILE): $(EXECUTABLE_CLI_SRC_FILE) | $(FRONTEND_CLI_BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
$(BIN_DIR)/$(EXECUTABLE_CLI): $(EXECUTABLE_CLI_OBJ_FILE) $(FRONTEND_CLI_OBJ_FILES) $(SNAKE_CLI_CONTROLLER_OBJ_FILES) $(LIB_BUILD_DIR)/$(BACKEND_TETRIS_LIB) $(LIB_BUILD_DIR)/$(BACKEND_SNAKE_LIB) | $(BIN_DIR)
$(CXX) $(CXXFLAGS) $^ -o $@ $(CURSES_FLAG)
#━━━━━━━━━━Frontend Desktop Targets━━━━━━━━━━━━━━━━
$(FRONTEND_DESKTOP_MOC_DIR)/%.moc.cc: $(FRONTEND_DESKTOP_SRC_DIR)/%.h | $(FRONTEND_DESKTOP_MOC_DIR)
$(MOC) $< -o $@
$(FRONTEND_DESKTOP_BUILD_DIR)/%.moc.o: $(FRONTEND_DESKTOP_MOC_DIR)/%.moc.cc | $(FRONTEND_DESKTOP_BUILD_DIR)
$(CXX) $(CXXFLAGS) $(QT_INCLUDES) -c $< -o $@
$(FRONTEND_DESKTOP_BUILD_DIR)/%.o: $(FRONTEND_DESKTOP_SRC_DIR)/%.cc | $(FRONTEND_DESKTOP_BUILD_DIR)
$(CXX) $(CXXFLAGS) $(QT_INCLUDES) -c $< -o $@
$(FRONTEND_DESKTOP_RESOURCES_CC_FILE): $(FRONTEND_DESKTOP_QRC_FILE) | $(FRONTEND_DESKTOP_RCC_DIR)
$(RCC) -name resources $< -o $@
$(FRONTEND_DESKTOP_RESOURCES_OBJ_FILE): $(FRONTEND_DESKTOP_RESOURCES_CC_FILE) | $(FRONTEND_DESKTOP_BUILD_DIR)
$(CXX) $(CXXFLAGS) $(QT_INCLUDES) -c $< -o $@
$(EXECUTABLE_DESKTOP_OBJ_FILE): $(EXECUTABLE_DESKTOP_SRC_FILE) | $(FRONTEND_DESKTOP_BUILD_DIR)
$(CXX) $(CXXFLAGS) $(QT_INCLUDES) -c $< -o $@
$(BIN_DIR)/$(EXECUTABLE_DESKTOP): $(EXECUTABLE_DESKTOP_OBJ_FILE) $(FRONTEND_DESKTOP_OBJ_FILES) $(LIB_BUILD_DIR)/$(BACKEND_TETRIS_LIB) $(LIB_BUILD_DIR)/$(BACKEND_SNAKE_LIB) | $(BIN_DIR)
$(CXX) $(CXXFLAGS) $(QT_INCLUDES) $^ -o $@ $(QT_LIBS) $(RPATH)
#━━━━━━━━━━Tests and Coverage━━━━━━━━━━━━━━━━━━━━━━
test: $(BIN_DIR)/run_tetris_tests $(BIN_DIR)/run_snake_tests
./$(BIN_DIR)/run_tetris_tests
./$(BIN_DIR)/run_snake_tests
coverage: CFLAGS += $(COVERAGE_FLAGS)
coverage: CXXFLAGS += $(COVERAGE_FLAGS)
coverage: clean $(BIN_DIR)/run_tetris_tests $(BIN_DIR)/run_snake_tests | $(COVERAGE_DIR)
./$(BIN_DIR)/run_tetris_tests
./$(BIN_DIR)/run_snake_tests
@gcovr -o $(COVERAGE_DIR)/gcov_report.html --html --html-self-contained --html-details $(GCOVR_THEME) --exclude $(TETRIS_TESTS_DIR) --exclude $(SNAKE_TESTS_DIR) --exclude ".*random\.h"
@$(OPEN_COMMAND) $(COVERAGE_DIR)/gcov_report.html
rm -f *.gcda *.gcno *.gcov
$(BIN_DIR)/run_tetris_tests: $(TETRIS_TESTS_OBJ_FILES) $(LIB_BUILD_DIR)/$(BACKEND_TETRIS_LIB) | $(BIN_DIR)
@$(CC) $(CFLAGS) $(TURN_OFF_RANDOM_FLAG) $^ $(TESTS_CHECK_LINKER_FLAGS) -o $@
$(BIN_DIR)/run_snake_tests: $(SNAKE_TESTS_OBJ_FILES) $(LIB_BUILD_DIR)/$(BACKEND_SNAKE_LIB) | $(BIN_DIR)
@$(CXX) $(CXXFLAGS) $^ $(TESTS_GTEST_LINKER_FLAGS) -o $@
$(TESTS_BUILD_DIR)/%.o: $(TETRIS_TESTS_DIR)/%.c | $(TESTS_BUILD_DIR)
$(CC) $(CFLAGS) -c $< -o $@
$(TESTS_BUILD_DIR)/%.o: $(SNAKE_TESTS_DIR)/%.cc | $(TESTS_BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
pdf:
pandoc -f markdown-implicit_figures -t pdf $(README_MD) --resource-path=. --variable geometry:a4paper --variable geometry:margin=2cm -o $(DOC_OUTPUT).pdf
tex:
sed '/^## Finite State Machine diagram/,/^$$/d' $(README_MD) | \
pandoc -s -f markdown -t latex -o $(DOC_OUTPUT).tex
dvi: tex
latex -shell-escape $(DOC_OUTPUT).tex
latex -shell-escape $(DOC_OUTPUT).tex
rm -f *.aux *.log *.out.ps *.tex ../*.tex
dist: pdf
mkdir -p $(DIST_DIR)
cp -R $(SRC_DIR) $(TESTS_DIR) Makefile LICENSE $(DOC_OUTPUT).pdf $(DIST_DIR)/
tar --create --verbose --file=$(DIST_ARCHIVE) --directory=$(DIST_DIR) --exclude='*.DS_Store' .
rm -rf $(DIST_DIR)
rm -f $(DOC_OUTPUT).pdf
clean:
rm -rf $(BUILD_DIR)
rm -f $(DIST_ARCHIVE)
rm -drf $(DIST_DIR)
rm -drf $(BIN_DIR)
rm -f *.aux *.log *.out.ps *.dvi *.tex ../*.tex
rm -f $(DOC_OUTPUT).pdf
rm -rf svg-inkscape
#━━━━━━━━━━Directories━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
$(BUILD_DIR):
@mkdir -p $@
$(BIN_DIR):
@mkdir -p $@
# Backend-related
$(BACKEND_BUILD_DIR) $(BACKEND_TETRIS_BUILD_DIR) $(BACKEND_SNAKE_BUILD_DIR) $(LIB_BUILD_DIR): | $(BUILD_DIR)
@mkdir -p $@
# Frontend-related
$(FRONTEND_BUILD_DIR) $(FRONTEND_CLI_BUILD_DIR) $(FRONTEND_DESKTOP_BUILD_DIR) $(FRONTEND_DESKTOP_MOC_DIR) $(FRONTEND_DESKTOP_RCC_DIR): | $(BUILD_DIR)
@mkdir -p $@
# Test-related
$(TESTS_BUILD_DIR) $(COVERAGE_DIR): | $(BUILD_DIR)
@mkdir -p $@