-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmakefile
More file actions
223 lines (190 loc) · 7.63 KB
/
makefile
File metadata and controls
223 lines (190 loc) · 7.63 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
#===============================================================================
# DEFINIÇÕES DO COMPILADOR E OPÇÕES DE COMPILAÇÃO
#===============================================================================
# Compilador C++
CXX ?= g++
# Opções de compilação para debug e release
CXXFLAGS_DEBUG = -std=c++20 -Wall -Wextra -g -O0 -MMD -MP -Iinclude
CXXFLAGS_RELEASE = -std=c++20 -Wall -Wextra -O3 -DNDEBUG -MMD -MP -Iinclude
# Modo de compilação (debug ou release)
MODE ?= debug
# Altere para "release" para compilar em modo release
ifeq ($(MODE), release)
CXXFLAGS = $(CXXFLAGS_RELEASE)
else
CXXFLAGS = $(CXXFLAGS_DEBUG)
endif
#===============================================================================
# DETECÇÃO DO SISTEMA OPERACIONAL E VARIÁVEIS ESPECÍFICAS
#===============================================================================
ifeq ($(OS),Windows_NT)
# Ambiente Windows
RM = rmdir /q /s
FIXPATH = $(subst /,\,$1)
MKDIR = mkdir
OBJ_MKDIR = $(MKDIR) "$(dir $@)" 2>nul
EXT = .exe
Cleanup = cls
CommandCreate = if not exist $@ ($(MKDIR) $@)
else
# Ambiente Unix/Linux
RM = rm -f
FIXPATH = $1
MKDIR = mkdir -p
OBJ_MKDIR = $(MKDIR) "$(dir $@)" 2>/dev/null || true
EXT =
Cleanup = clear
CommandCreate = if [ ! -d "$@" ]; then $(MKDIR) "$@"; fi
endif
#===============================================================================
# DIRETÓRIOS E ARQUIVOS-FONTE
#===============================================================================
# Diretórios para código-fonte, objetos e saída
SRC_DIRS = src
BUILD_DIR = build
OUTPUT_DIR = build/bin
TESTS_DIR = tests
# Definir o nome do executável
OUTPUT_NAME = $(notdir $(CURDIR))
OUTPUT = $(OUTPUT_DIR)/$(OUTPUT_NAME)$(EXT)
# Diretórios de inclusão e bibliotecas
INCLUDE_DIRS = include lib/googletest/googletest/include lib/googletest/googletest
INCLUDES = $(patsubst %,-I%, $(INCLUDE_DIRS))
LIB_DIRS = lib
LIBS = $(patsubst %,-L%, $(LIB_DIRS))
# Encontra todos os arquivos .cpp (incluindo subdiretórios) (/*.cpp para apenas o diretório atual)
SOURCES := $(wildcard $(SRC_DIRS)/**/*.cpp)
# Cria lista de objetos a partir dos fontes
OBJECTS := $(patsubst $(SRC_DIRS)/%.cpp,$(BUILD_DIR)/%.o,$(SOURCES))
# Arquivos de dependência gerados
DEPS := $(OBJECTS:.o=.d)
#===============================================================================
# REGRAS PRINCIPAIS
#===============================================================================
.PHONY: all clean run test docs init
# Target principal
all: $(OUTPUT)
# Regra para gerar o executável (linka todos os objetos)
$(OUTPUT): $(OBJECTS) | $(OUTPUT_DIR)
@echo "Linkando executavel $@ com os arquivos: $^"
@$(CXX) -o $@ $^ $(LIBS)
@echo "Compilacao concluida com sucesso!"
@echo Executavel criado em: $(OUTPUT_DIR)/$(OUTPUT_NAME)$(EXT)
#===============================================================================
# REGRA PARA CRIAR OS DIRETÓRIOS (usando o comando específico de cada SO)
#===============================================================================
$(OUTPUT_DIR) $(BUILD_DIR):
@$(CommandCreate)
#===============================================================================
# REGRA PARA COMPILAR OS ARQUIVOS .cpp
#===============================================================================
$(BUILD_DIR)/%.o: $(SRC_DIRS)/%.cpp | $(BUILD_DIR)
@$(OBJ_MKDIR)
@echo "Compilando $<..."
@$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
@echo "$(@F): $<" > $(@:.o=.d)
#===============================================================================
# INCLUSÃO AUTOMÁTICA DE DEPENDÊNCIAS GERADAS
#===============================================================================
-include $(DEPS)
#===============================================================================
# TARGETS AUXILIARES (clean, run, docs, init, etc.)
#===============================================================================
# Limpeza dos arquivos objetos, dependências e diretórios de saída
clean:
@echo "Deletando arquivos objeto..."
ifeq ($(OS),Windows_NT)
@if exist "$(BUILD_DIR)\*.o" (del "$(BUILD_DIR)\*.o")
@echo "Deletando arquivos de dependencia..."
@if exist "$(BUILD_DIR)\*.d" (del "$(BUILD_DIR)\*.d")
@echo "Deletando a pasta $(OUTPUT_DIR)..."
@if exist "$(OUTPUT_DIR)" ($(RM) "$(OUTPUT_DIR)")
@echo "Deletando a pasta $(BUILD_DIR)..."
@if exist "$(BUILD_DIR)" ($(RM) "$(BUILD_DIR)")
else
@$(RM) $(BUILD_DIR)/*.o $(BUILD_DIR)/*.d
@echo "Deletando arquivos de dependencia e objetos..."
@$(RM) -r $(BUILD_DIR) $(OUTPUT_DIR)
@echo "Deletando a pasta $(BUILD_DIR) e $(OUTPUT_DIR)..."
endif
@echo "Limpeza concluida com sucesso!"
# Regra para executar o programa
run: all
@$(Cleanup)
@echo "Executando o programa..."
@$(OUTPUT)
# Regra para gerar documentação
docs:
@$(Cleanup)
@echo "Gerando documentacao..."
@doxygen Doxyfile
@echo "Documentacao gerada com sucesso!"
## Regra para inicializar a estrutura de diretórios
init:
ifeq ($(OS),Windows_NT)
@echo "Criando diretorios..."
@if not exist "$(SRC_DIRS)" ($(MKDIR) "$(SRC_DIRS)/main")
@if not exist "$(INCLUDE_DIRS)" ($(MKDIR) "$(INCLUDE_DIRS)")
@if not exist "$(LIB_DIRS)" ($(MKDIR) "$(LIB_DIRS)")
@if not exist "$(TESTS_DIR)" ($(MKDIR) "$(TESTS_DIR)")
@if not exist "$(TESTS_DIR)\log" ($(MKDIR) "$(TESTS_DIR)\log")
@echo. > "$(SRC_DIRS)\main\main.cpp"
@echo "Diretorios criados com sucesso!"
else
@echo "Criando diretorios..."
@$(MKDIR) "$(SRC_DIRS)/main" "$(INCLUDE_DIRS)" "$(LIB_DIRS)" "$(TESTS_DIR)" "$(TESTS_DIR)/log" 2>/dev/null || echo "Alguns diretórios já existem."
@touch "$(SRC_DIRS)/main/main.cpp"
@echo "Diretorios criados com sucesso!"
endif
@$(Cleanup)
#===============================================================================
# REGRAS PARA TESTES
#===============================================================================
# Variáveis para testes (tudo que estiver na pasta tests)
TEST_SOURCES := $(wildcard $(TESTS_DIR)/*.cpp)
TEST_OBJECTS := $(patsubst $(TESTS_DIR)/%.cpp,$(TESTS_DIR)/%.o,$(TEST_SOURCES))
# Nome do executável de teste; você pode ajustá-lo conforme desejar
TEST_EXECUTABLE := $(TESTS_DIR)/test$(EXT)
# Variáveis para o Google Test
# Certifique-se de que o Google Test esteja na pasta lib/googletest
GTEST_SRC = lib/googletest/googletest/src/gtest-all.cc lib/googletest/googletest/src/gtest_main.cc
GTEST_OBJECTS = $(patsubst %.cc,%.o,$(GTEST_SRC))
# Verifica se há arquivos de teste
ifneq ($(strip $(TEST_OBJECTS)),)
TEST_AVAILABLE := 1
else
TEST_AVAILABLE := 0
endif
lib/googletest/googletest/src/%.o: lib/googletest/googletest/src/%.cc
@echo "Compilando Google Test $<..."
@$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
# Regra para compilar os arquivos de teste
$(TESTS_DIR)/%.o: $(TESTS_DIR)/%.cpp
@echo "Compilando teste $<..."
@$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@
# Regra para linkar o executável de teste
$(TEST_EXECUTABLE): $(TEST_OBJECTS) $(GTEST_OBJECTS)
ifeq ($(TEST_AVAILABLE),1)
@echo "Linkando executavel de teste $@ com GTest..."
@$(CXX) $(CXXFLAGS) $(INCLUDES) -o $@ $^ -pthread
@echo "Teste compilado com sucesso!"
endif
# Regra para compilar os testes
build-tests: $(TEST_EXECUTABLE)
test: $(TEST_EXECUTABLE)
ifeq ($(TEST_AVAILABLE),1)
@echo "Executando os testes..."
@$(TEST_EXECUTABLE)
@echo "Testes concluídos com sucesso!"
else
@echo "Nenhum teste encontrado. Crie arquivos .cpp em '$(TESTS_DIR)' para rodar testes com Google Test."
endif
# Regra para limpar os testes
clean-test:
ifeq ($(TEST_AVAILABLE),1)
@echo "Limpando arquivos de teste..."
@$(RM) $(TESTS_DIR)/*.o $(TESTS_DIR)/*.d $(TEST_EXECUTABLE)
@echo "Arquivos de teste limpos com sucesso!"
else
@echo "Nenhum teste para limpar."
endif