-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
218 lines (184 loc) · 7.59 KB
/
Copy pathMakefile
File metadata and controls
218 lines (184 loc) · 7.59 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
LINUX_CXX := clang++
LINUX_CC := clang
ifneq ($(OS),Windows_NT)
WINDOWS_CXX := x86_64-w64-mingw32-g++
WINDOWS_CC := x86_64-w64-mingw32-gcc
else
WINDOWS_CXX := g++
WINDOWS_CC := gcc
endif
FLAGS_DEBUG_COMMON := -g -O0 -D DEBUGGING
FLAGS_DEBUG_LINUX := # -fsanitize=address
FLAGS_DEBUG_WINDOWS := # Nothing yet
FLAGS_RELEASE_COMMON := -O3
FLAGS_RELEASE_WINDOWS := # Nothing yet
FLAGS_RELEASE_LINUX := # Nothing yet
FLAGS_CXX_COMMON := -Wall -std=c++23
FLAGS_CC_COMMON := -Wall -std=c11
FLAGS_WINDOWS := # Nothing yet
FLAGS_LINUX := # Nothing yet
LDFLAGS_LINUX := -Lsrc/lib/Linux -lgetargs
LDFLAGS_WINDOWS := -lstdc++exp -Lsrc/lib/Windows -lgetargs
INCLUDE := -I src -I src/include
DIR_ROOT := build
DIR_LINUX := Linux
DIR_WINDOWS := Windows
DIR_DEBUG := Debug
DIR_RELEASE := Release
DIR_OBJS := .objs
NAME_BASE := makemake
# LINUX
ifneq ($(OS),Windows_NT)
export NAME ?= $(NAME_BASE)
export BUILD_ARCH ?= $(DIR_LINUX)
export DEBUG_FLAGS ?= $(FLAGS_DEBUG_COMMON) $(FLAGS_DEBUG_LINUX)
export RELEASE_FLAGS ?= $(FLAGS_RELEASE_COMMON) $(FLAGS_RELEASE_LINUX)
export CXX_FLAGS ?= $(FLAGS_CXX_COMMON) $(FLAGS_LINUX)
export CC_FLAGS ?= $(FLAGS_CC_COMMON) $(FLAGS_LINUX)
export LD_FLAGS ?= $(LDFLAGS_LINUX)
export CXX_COMPILER ?= $(LINUX_CXX)
export C_COMPILER ?= $(LINUX_CC)
else # WINDOWS
export NAME ?= $(NAME_BASE).exe
export BUILD_ARCH ?= $(DIR_WINDOWS)
export DEBUG_FLAGS ?= $(FLAGS_DEBUG_COMMON) $(FLAGS_DEBUG_WINDOWS)
export RELEASE_FLAGS ?= $(FLAGS_RELEASE_COMMON) $(FLAGS_RELEASE_WINDOWS)
export CXX_FLAGS ?= $(FLAGS_CXX_COMMON) $(FLAGS_WINDOWS)
export CC_FLAGS ?= $(FLAGS_CC_COMMON) $(FLAGS_WINDOWS)
export LD_FLAGS ?= $(LDFLAGS_WINDOWS)
export CXX_COMPILER ?= $(WINDOWS_CXX)
export C_COMPILER ?= $(WINDOWS_CC)
endif
export BUILD_VERSION ?= $(DIR_RELEASE)
export VERSION_FLAGS ?= $(RELEASE_FLAGS)
export BUILD_DIR ?= $(DIR_ROOT)/$(BUILD_ARCH)/$(BUILD_VERSION)
export BUILD_OBJS ?= $(BUILD_DIR)/$(DIR_OBJS)
export CLEAN_ARCH ?= .+
export CLEAN_VERSION ?= .+
VPATH := $(SRC_DIRS)
SRC := src
SRC_DIRS := \
$(SRC)/makefile \
$(SRC)/system \
CC_SRCS := $(foreach directory,$(SRC_DIRS),$(wildcard $(directory)/*.c))
CXX_SRCS := $(foreach directory,$(SRC_DIRS),$(wildcard $(directory)/*.cpp))
export CC_OBJS ?= $(addprefix $(BUILD_OBJS)/,$(subst .c,.o,$(CC_SRCS:$(SRC)/%=%)))
export CXX_OBJS ?= $(addprefix $(BUILD_OBJS)/,$(subst .cpp,.obj,$(CXX_SRCS:$(SRC)/%=%)))
export RESET ?= \\x1b[0m
export BLACK ?= \\x1b[1;30m
export RED ?= \\x1b[1;31m
export GREEN ?= \\x1b[1;32m
export YELLOW ?= \\x1b[1;33m
export BLUE ?= \\x1b[1;34m
export MAGENTA ?= \\x1b[1;35m
export CYAN ?= \\x1b[1;36m
export WHITE ?= \\x1b[1;37m
export DEFAULT ?= \\x1b[1;39m
.PHONY: build linux windows release debug build_dirs .__clean_target .__clean_all clean mostlyclean disable_colors
build:
@ printf "$(DEFAULT)::Architecture - $(BLUE)$(BUILD_ARCH)$(RESET)\n"
@ printf "$(DEFAULT)::Version - $(BLUE)$(BUILD_VERSION)$(RESET)\n"
@ printf "$(DEFAULT)::C Compile Command - $(YELLOW)$(C_COMPILER) $(CC_FLAGS) $(VERSION_FLAGS) $(INCLUDE)$(RESET)\n"
@ printf "$(DEFAULT)::C++ Compile Command - $(YELLOW)$(CXX_COMPILER) $(CXX_FLAGS) $(VERSION_FLAGS) $(INCLUDE)$(RESET)\n"
@ $(MAKE) -s $(BUILD_DIR)/$(NAME)
@ printf "$(DEFAULT)::Program Location - $(GREEN)$(DIR_ROOT)/$(BUILD_ARCH)/$(BUILD_VERSION)/$(NAME)$(RESET)\n"
linux: ;@:
$(eval NAME = $(NAME_BASE))
$(eval BUILD_ARCH = $(DIR_LINUX))
$(eval DEBUG_FLAGS = $(FLAGS_DEBUG_COMMON) $(FLAGS_DEBUG_LINUX))
$(eval RELEASE_FLAGS = $(FLAGS_RELEASE_COMMON) $(FLAGS_RELEASE_LINUX))
$(eval CXX_FLAGS = $(FLAGS_CXX_COMMON) $(FLAGS_LINUX))
$(eval CC_FLAGS = $(FLAGS_CC_COMMON) $(FLAGS_LINUX))
$(eval LD_FLAGS = $(LDFLAGS_LINUX))
$(eval CXX_COMPILER = $(LINUX_CXX))
$(eval C_COMPILER = $(LINUX_CC))
$(eval TARGET_CALLED = 1)
$(eval CLEAN_ARCH = $(DIR_LINUX))
windows: ;@:
$(eval NAME = $(NAME_BASE).exe)
$(eval BUILD_ARCH = $(DIR_WINDOWS))
$(eval DEBUG_FLAGS = $(FLAGS_DEBUG_COMMON) $(FLAGS_DEBUG_WINDOWS))
$(eval RELEASE_FLAGS = $(FLAGS_RELEASE_COMMON) $(FLAGS_RELEASE_WINDOWS))
$(eval CXX_FLAGS = $(FLAGS_CXX_COMMON) $(FLAGS_WINDOWS))
$(eval CC_FLAGS = $(FLAGS_CC_COMMON) $(FLAGS_WINDOWS))
$(eval LD_FLAGS = $(LDFLAGS_WINDOWS))
$(eval CXX_COMPILER = $(WINDOWS_CXX))
$(eval C_COMPILER = $(WINDOWS_CC))
$(eval TARGET_CALLED = 1)
$(eval CLEAN_ARCH = $(DIR_WINDOWS))
release: ;@:
$(eval VERSION_FLAGS = $(RELEASE_FLAGS))
$(eval BUILD_VERSION = $(DIR_RELEASE))
$(eval TARGET_CALLED = 1)
$(eval CLEAN_VERSION = $(DIR_RELEASE))
debug: ;@:
$(eval VERSION_FLAGS = $(DEBUG_FLAGS))
$(eval BUILD_VERSION = $(DIR_DEBUG))
$(eval TARGET_CALLED = 1)
$(eval CLEAN_VERSION = $(DIR_DEBUG))
build_dirs:
@ -mkdir -p $(BUILD_DIR)
# Cleaning Functions
CLEAN = find $(DIR_ROOT) -type $(1) $(2) -not -path "*.git/*" -delete -print 2>/dev/null
CLEAN_OBJS = $(call CLEAN,$(1),-regex '.+\.objs_.+/.+' $(2))
CLEAN_DIRTY = $(call CLEAN_OBJS,$(1),$(DIRTY_SRC_DIRS:%=-not -path "*%*"))
CLEAN_PRINT = \
$(eval MAKE_TARGET != if [[ -n "$(1)" && "$(1)" != " " ]]; then printf "$(1)"; else printf "NOTHING_TO_CLEAN"; fi) \
$(MAKE) -s $(foreach cleaned,$(MAKE_TARGET),$(cleaned).clean)
# Cleans directories based on previous targets
# (e.g: 'make windows clean' will clean 'build/Windows/', but 'make windows debug clean' will only clean 'build/Windows/Debug/')
.__clean_target: ;@:
$(eval CLEAN_FILES != $(call CLEAN,f,-regex '$(DIR_ROOT)/$(CLEAN_ARCH)/$(CLEAN_VERSION)/.*'))
$(eval CLEAN_DIRS != $(call CLEAN,d,-regex '$(DIR_ROOT)/$(CLEAN_ARCH)/$(CLEAN_VERSION)'))
$(eval EMPTY_DIRS != $(call CLEAN,d,-empty -regex '$(DIR_ROOT)/$(CLEAN_ARCH)'))
@ $(call CLEAN_PRINT,$(EMPTY_DIRS))
# Cleans the entire 'build/' directory (default behaviour for 'clean')
.__clean_all: ;@:
$(eval CLEAN_FILES != $(call CLEAN,f,-regex '$(DIR_ROOT)/.*'))
$(eval CLEAN_DIRS != $(call CLEAN,d,-regex '$(DIR_ROOT)/.*'))
$(eval EMPTY_DIR != find ./ -type d -not -path "*.git*" -empty -delete -print 2>/dev/null)
@ $(call CLEAN_PRINT,$(EMPTY_DIR))
# What 'clean' does depends on if it's called by itself, or after other targets
clean:
@ if [ "$(TARGET_CALLED)" == "1" ]; then \
$(MAKE) -s .__clean_target; \
else \
$(MAKE) -s .__clean_all; \
fi
# 'mostlyclean' doesn't clean files from 'DIRTY_SRC_DIRS'
mostlyclean:
$(eval CLEAN_FILES != $(call CLEAN_DIRTY,f))
$(eval CLEAN_DIRS != $(call CLEAN_DIRTY,d -empty))
@ $(call CLEAN_PRINT, $(CLEAN_FILES)$(CLEAN_DIRS))
disable_colors:
$(eval RESET := "")
$(eval BLACK := "")
$(eval RED := "")
$(eval GREEN := "")
$(eval YELLOW := "")
$(eval BLUE := "")
$(eval MAGENTA := "")
$(eval CYAN := "")
$(eval WHITE := "")
$(eval DEFAULT := "")
@ printf "::Output colors disabled\n"
# C++ Object Files
$(BUILD_OBJS)/%.obj: $(SRC)/%.cpp | build_dirs
@ printf "::Compiling $(BLUE)$@$(RESET)\n"
@ -mkdir -p $(dir $@)
$(CXX_COMPILER) $(CXX_FLAGS) $(VERSION_FLAGS) $(INCLUDE) -c $< -o $@
# C Object Files
$(BUILD_OBJS)/%.o: $(SRC)/%.c | build_dirs
@ printf "::Compiling $(BLUE)$@$(RESET)\n"
@ -mkdir -p $(dir $@)
$(C_COMPILER) $(CC_FLAGS) $(VERSION_FLAGS) $(INCLUDE) -c $< -o $@
# Program Linking
$(BUILD_DIR)/$(NAME): $(CC_OBJS) $(CXX_OBJS)
@ printf "::Linking $(GREEN)$@$(RESET)\n"
$(CXX_COMPILER) $(CXX_FLAGS) $(VERSION_FLAGS) $(INCLUDE) $^ -o $@ $(LD_FLAGS)
# Prints a unique cleanup message
NOTHING_TO_CLEAN.clean:
@ printf "::Nothing left to clean\n"
# Prints a cleanup message
%.clean:
@ printf "::Cleaned $(RED)$*$(RESET)\n"