-
Notifications
You must be signed in to change notification settings - Fork 87
/
Makefile
183 lines (146 loc) · 5.73 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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#==============================================================================
# Build platform
PLATFORM?=linux
# Build description (Primarily uses Debug/Release)
BUILD?=Release
_BUILDL := $(shell echo $(BUILD) | tr A-Z a-z)
# Platform specific environment variables
-include env.mk
-include env/.all.mk
-include env/.$(_BUILDL).mk
-include env/$(PLATFORM).all.mk
-include env/$(PLATFORM).$(_BUILDL).mk
#==============================================================================
# File/Folder dependencies for the production build recipe (makeproduction)
PRODUCTION_DEPENDENCIES?=
# Extensions to exclude from production builds
PRODUCTION_EXCLUDE?=
# Folder location (relative or absolute) to place the production build into
PRODUCTION_FOLDER?=build
#==============================================================================
# Library directories (separated by spaces)
LIB_DIRS?=
INCLUDE_DIRS?=
# Link libraries (separated by spaces)
LINK_LIBRARIES?=
# Build-specific preprocessor macros
BUILD_MACROS?=
# Build-specific compiler flags to be appended to the final build step (with prefix)
BUILD_FLAGS?=
# Build dependencies to copy into the bin/(build) folder - example: openal32.dll
BUILD_DEPENDENCIES?=
# NAME should always be passed as an argument from tasks.json as the root folder name, but uses a fallback of "game.exe"
# This is used for the output filename (game.exe)
NAME?=game.exe
#==============================================================================
# Project .cpp or .rc files (relative to src directory)
SOURCE_FILES := $(patsubst src/%,%,$(shell find src -name '*.cpp' -o -name '*.c' -o -name '*.rc'))
# Project subdirectories within src/ that contain source files
PROJECT_DIRS := $(patsubst src/%,%,$(shell find src -mindepth 1 -maxdepth 99 -type d))
# Add prefixes to the above variables
_LIB_DIRS := $(patsubst %,-L%,$(LIB_DIRS))
_INCLUDE_DIRS := $(patsubst %,-I%,src/ $(INCLUDE_DIRS))
_BUILD_MACROS := $(patsubst %,-D%,$(BUILD_MACROS))
_LINK_LIBRARIES := $(patsubst %,-l%,$(LINK_LIBRARIES))
#==============================================================================
# Directories & Dependencies
BLD_DIR := bin/$(BUILD)
BLD_DIR := $(patsubst %/,%,$(BLD_DIR))
_EXE := $(BLD_DIR)/$(NAME)
_NAMENOEXT := $(NAME:.exe=)
_NAMENOEXT := $(_NAMENOEXT:.dll=)
OBJ_DIR := $(BLD_DIR)/obj
_OBJS := $(SOURCE_FILES:.rc=.res)
_OBJS := $(_OBJS:.c=.o)
_OBJS := $(_OBJS:.cpp=.o)
OBJS := $(patsubst %,$(OBJ_DIR)/%,$(_OBJS))
OBJ_SUBDIRS := $(patsubst %,$(OBJ_DIR)/%,$(PROJECT_DIRS))
DEP_DIR := $(BLD_DIR)/dep
_DEPS := $(SOURCE_FILES:.rc=.res)
_DEPS := $(_DEPS:.c=.d)
_DEPS := $(_DEPS:.cpp=.d)
DEPS := $(patsubst %,$(DEP_DIR)/%,$(_DEPS))
DEP_SUBDIRS := $(patsubst %,$(DEP_DIR)/%,$(PROJECT_DIRS))
ifeq ($(DUMP_ASSEMBLY),true)
ASM_DIR := $(BLD_DIR)/asm
_ASMS := $(_OBJS:%.res=)
_ASMS := $(_ASMS:.o=.o.asm)
ASMS := $(patsubst %,$(ASM_DIR)/%,$(_ASMS))
ASM_SUBDIRS := $(patsubst %,$(ASM_DIR)/%,$(PROJECT_DIRS))
endif
_DIRECTORIES := bin $(BLD_DIR) $(OBJ_DIR) $(OBJ_SUBDIRS) $(DEP_DIR) $(DEP_SUBDIRS) $(ASM_DIR) $(ASM_SUBDIRS)
_DIRECTORIES := $(sort $(_DIRECTORIES))
_BUILD_DEPENDENCIES := $(filter %.dll,$(BUILD_DEPENDENCIES))
_BUILD_DEPENDENCIES := $(patsubst %,$(BLD_DIR)/%,$(notdir $(_BUILD_DEPENDENCIES)))
#==============================================================================
# Compiler & flags
CC?=g++
RC?=windres.exe
CFLAGS_ALL?=-Wfatal-errors -Wextra -Wall -fdiagnostics-color=never
CFLAGS?=-g $(CFLAGS_ALL)
CFLAGS_DEPS=-MT $@ -MMD -MP -MF $(DEP_DIR)/$*.Td
POST_COMPILE=@mv -f $(DEP_DIR)/$*.Td $(DEP_DIR)/$*.d && touch $@
#==============================================================================
# Build Scripts
all: makebuild
rebuild: clean makebuild
buildprod: makebuild makeproduction
#==============================================================================
define c_cpp_compile =
$(CC) $(CFLAGS_DEPS) $(_BUILD_MACROS) $(CFLAGS) $(_INCLUDE_DIRS) -o $@ -c $<
$(POST_COMPILE)
endef
define dll_so_dependency =
$(foreach dep,$(BUILD_DEPENDENCIES),$(shell cp -r $(dep) $(BLD_DIR)))
endef
# Build Recipes
$(OBJ_DIR)/%.o: src/%.cpp
$(OBJ_DIR)/%.o: src/%.cpp $(DEP_DIR)/%.d | $(_DIRECTORIES)
$(c_cpp_compile)
$(OBJ_DIR)/%.o: src/%.c
$(OBJ_DIR)/%.o: src/%.c $(DEP_DIR)/%.d | $(_DIRECTORIES)
$(c_cpp_compile)
$(OBJ_DIR)/%.res: src/%.rc
$(OBJ_DIR)/%.res: src/%.rc src/%.h | $(_DIRECTORIES)
$(RC) -J rc -O coff -i $< -o $@
$(ASM_DIR)/%.o.asm: $(OBJ_DIR)/%.o
objdump -d -C -Mintel $< > $@
$(BLD_DIR)/%.dll:
$(dll_so_dependency)
$(BLD_DIR)/%.so:
$(dll_so_dependency)
$(_EXE): $(OBJS) $(ASMS) $(BLD_DIR) $(_BUILD_DEPENDENCIES)
ifeq ($(suffix $(_EXE)),.dll)
-rm -f $(BLD_DIR)/lib$(_NAMENOEXT).def
-rm -f $(BLD_DIR)/lib$(_NAMENOEXT).a
$(CC) -shared -Wl,--output-def="$(BLD_DIR)/lib$(_NAMENOEXT).def" -Wl,--out-implib="$(BLD_DIR)/lib$(_NAMENOEXT).a" -Wl,--dll $(_LIB_DIRS) $(OBJS) -o $@ -s $(_LINK_LIBRARIES) $(BUILD_FLAGS)
else
$(CC) $(_LIB_DIRS) -o $@ $(OBJS) $(_LINK_LIBRARIES) $(BUILD_FLAGS)
endif
makebuild: $(_EXE)
@echo '$(BUILD) build target is up to date.'
$(_DIRECTORIES):
mkdir -p $@
.PHONY: clean
clean:
$(RM) $(_EXE)
$(RM) $(DEPS)
$(RM) $(OBJS)
#==============================================================================
# Production recipes
rmbuild:
-rm -f -r $(PRODUCTION_FOLDER)
mkdirbuild:
mkdir -p $(PRODUCTION_FOLDER)
releasetobuild: $(_EXE)
cp $(_EXE) $(PRODUCTION_FOLDER)
makeproduction: rmbuild mkdirbuild releasetobuild
@echo -n 'Adding dynamic libraries & project dependencies...'
$(foreach dep,$(PRODUCTION_DEPENDENCIES),$(shell cp -r $(dep) $(PRODUCTION_FOLDER)))
$(foreach excl,$(PRODUCTION_EXCLUDE),$(shell find $(PRODUCTION_FOLDER) -name '$(excl)' -delete))
@echo ' Done'
#==============================================================================
# Dependency recipes
$(DEP_DIR)/%.d: ;
.PRECIOUS: $(DEP_DIR)/%.d
include $(wildcard $(DEPS))