forked from boazsegev/facil.io
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmakefile
334 lines (272 loc) · 10.1 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
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
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
### Output
# binary name and location
NAME=demo
OUT_ROOT=tmp
### Library folders
# the .c and .cpp source files root folder - subfolders are automatically included
LIB_ROOT=lib
# publicly used subfolders in the lib root
LIB_PUBLIC_SUBFOLDERS=facil/core facil/core/types facil/core/types/fiobj facil/services facil/http facil/http/parsers facil/redis
# privately used subfolders in the lib root (this distinction is for CMake)
LIB_PRIVATE_SUBFOLDERS=
### Development folders
# The development, non-library .c file(s) (i.e., the one with `int main(void)`.
MAIN_ROOT=src
# Development subfolders in the main root
MAIN_SUBFOLDERS=
### Build Root
# temporary folder will be cleared out and deleted between fresh builds
# All object files will be placed in this folder
TMP_ROOT=tmp
### Compiler & Linker flags
# any librries required (only names, ommit the "-l" at the begining)
LINKER_LIBS=pthread m
LINKER_LIBS_EXT=
# optimization level.
OPTIMIZATION=-O2 -march=native
# Warnings... i.e. -Wpedantic -Weverything -Wno-format-pedantic
WARNINGS= -Wall -Wextra -Wno-missing-field-initializers -Wpedantic
# any extra include folders, space seperated list
INCLUDE= ./
# any preprocessosr defined flags we want, space seperated list (i.e. DEBUG )
FLAGS:=
### Helpers
# The library details for CMake incorporation. Can be safely removed.
CMAKE_LIBFILE_NAME=CMakeLists.txt
# dumps all library files in one place
DUMP_LIB=libdump
# add DEBUG flag if requested
ifdef DEBUG
$(info * Detected DEBUG environment flag, enforcing debug mode compilation)
FLAGS:=$(FLAGS) DEBUG
# # comment the following line if you want to use a different address sanitizer or a profiling tool.
OPTIMIZATION:=-O0 -march=native -fsanitize=address -fno-omit-frame-pointer
# possibly useful: -Wconversion -Wcomma
# go crazy with clang: -Weverything -Wno-cast-qual -Wno-used-but-marked-unused -Wno-reserved-id-macro -Wno-padded -Wno-disabled-macro-expansion -Wno-documentation-unknown-command -Wno-bad-function-cast -Wno-missing-prototypes
else
FLAGS:=$(FLAGS) NODEBUG
endif
# c compiler
ifndef CC
CC=gcc
endif
# c++ compiler
ifndef CPP
CPP=g++
endif
##############
## OS specific data - compiler, assembler etc.
ifneq ($(OS),Windows_NT)
OS := $(shell uname)
else
$(error *** Windows systems aren\'t supported by this makefile / library.)
endif
ifeq ($(OS),Darwin) # Run MacOS commands
# debugger
DB=lldb
# disassemble tool. Use stub to disable.
DISAMS=otool -tVX
# documentation commands
# DOCUMENTATION=cldoc generate $(INCLUDE_STR) -- --output ./html $(foreach dir, $(LIB_PUBLIC_SUBFOLDERS), $(wildcard $(addsuffix /, $(basename $(dir)))*.h*))
else
# debugger
DB=gdb
# disassemble tool, leave undefined.
# DISAMS=otool -tVX
DOCUMENTATION=
endif
#####################
# Auto computed values
BIN = $(OUT_ROOT)/$(NAME)
LIBDIR_PUB = $(LIB_ROOT) $(foreach dir, $(LIB_PUBLIC_SUBFOLDERS), $(addsuffix /,$(basename $(LIB_ROOT)))$(dir))
LIBDIR_PRIV = $(foreach dir, $(LIB_PRIVATE_SUBFOLDERS), $(addsuffix /,$(basename $(LIB_ROOT)))$(dir))
LIBDIR = $(LIBDIR_PUB) $(LIBDIR_PRIV)
LIBSRC = $(foreach dir, $(LIBDIR), $(wildcard $(addsuffix /, $(basename $(dir)))*.c*))
MAINDIR = $(MAIN_ROOT) $(foreach main_root, $(MAIN_ROOT) , $(foreach dir, $(MAIN_SUBFOLDERS), $(addsuffix /,$(basename $(main_root)))$(dir)))
MAINSRC = $(foreach dir, $(MAINDIR), $(wildcard $(addsuffix /, $(basename $(dir)))*.c*))
FOLDERS = $(LIBDIR) $(MAINDIR)
SOURCES = $(LIBSRC) $(MAINSRC)
BUILDTREE =$(foreach dir, $(FOLDERS), $(addsuffix /, $(basename $(TMP_ROOT)))$(basename $(dir)))
CCL = $(CC)
INCLUDE_STR = $(foreach dir,$(INCLUDE),$(addprefix -I, $(dir))) $(foreach dir,$(FOLDERS),$(addprefix -I, $(dir)))
MAIN_OBJS = $(foreach source, $(MAINSRC), $(addprefix $(TMP_ROOT)/, $(addsuffix .o, $(basename $(source)))))
LIB_OBJS = $(foreach source, $(LIBSRC), $(addprefix $(TMP_ROOT)/, $(addsuffix .o, $(basename $(source)))))
OBJS_DEPENDENCY:=$(LIB_OBJS:.o=.d) $(MAIN_OBJS:.o=.d)
# S2N TLS/SSL library: https://github.com/awslabs/s2n
ifeq ($(shell printf "\#include <s2n.h>\\n int main(void) {}" | $(CC) $(INCLUDE_STR) -ls2n -xc -o /dev/null - >& /dev/null ; echo $$? ), 0)
$(info * Detected the s2n library, setting HAVE_S2N)
FLAGS:=$(FLAGS) HAVE_S2N
LINKER_LIBS_EXT:=$(LINKER_LIBS_EXT) s2n
endif
# add BearSSL/OpenSSL library flags
ifeq ($(shell printf "\#include <bearssl.h>\\n int main(void) {}" | $(CC) $(INCLUDE_STR) -lbearssl -xc -o /dev/null - >& /dev/null ; echo $$? ), 0)
$(info * Detected the BearSSL library, setting HAVE_BEARSSL)
FLAGS:=$(FLAGS) HAVE_BEARSSL
LINKER_LIBS_EXT:=$(LINKER_LIBS_EXT) bearssl
else
ifeq ($(shell printf "\#include <openssl/ssl.h>\\nint main(void) {}" | $(CC) $(INCLUDE_STR) -lcrypto -lssl -xc -o /dev/null - >& /dev/null ; echo $$? ), 0)
$(info * Detected the OpenSSL library, setting HAVE_OPENSSL)
FLAGS:=$(FLAGS) HAVE_OPENSSL
LINKER_LIBS_EXT:=$(LINKER_LIBS_EXT) crypto ssl
endif
endif
# add ZLib library flags
ifeq ($(shell printf "\#include <zlib.h>\\nint main(void) {}" | $(CC) $(INCLUDE_STR) -lz -xc -o /dev/null - >& /dev/null ; echo $$? ), 0)
$(info * Detected the zlib library, setting HAVE_ZLIB)
FLAGS:=$(FLAGS) HAVE_ZLIB
LINKER_LIBS_EXT:=$(LINKER_LIBS_EXT) z
endif
#####################
# Updated flags and final values
FLAGS_STR = $(foreach flag,$(FLAGS),$(addprefix -D, $(flag)))
CFLAGS= -g -std=c11 -fpic $(FLAGS_STR) $(WARNINGS) $(OPTIMIZATION) $(INCLUDE_STR)
CPPFLAGS= -std=c++11 -fpic $(FLAGS_STR) $(WARNINGS) $(OPTIMIZATION) $(INCLUDE_STR)
LINKER_FLAGS=$(foreach lib,$(LINKER_LIBS),$(addprefix -l,$(lib))) $(foreach lib,$(LINKER_LIBS_EXT),$(addprefix -l,$(lib)))
CFALGS_DEPENDENCY=-MT $@ -MMD -MP
########
## Main Tasks
$(NAME): build
build: | create_tree build_objects
build_objects: $(LIB_OBJS) $(MAIN_OBJS)
@$(CCL) -o $(BIN) $^ $(OPTIMIZATION) $(LINKER_FLAGS)
@$(DOCUMENTATION)
lib: | create_tree lib_build
lib_build: $(LIB_OBJS)
@$(CCL) -shared -o $(OUT_ROOT)/libfacil.so $^ $(OPTIMIZATION) $(LINKER_FLAGS)
@$(DOCUMENTATION)
%.o : %.c
ifdef DISAMS
$(TMP_ROOT)/%.o: %.c $(TMP_ROOT)/%.d
@$(CC) -c $< -o $@ $(CFALGS_DEPENDENCY) $(CFLAGS)
@$(DISAMS) $@ > [email protected]
$(TMP_ROOT)/%.o: %.cpp $(TMP_ROOT)/%.d
@$(CPP) -o $@ -c $< $(CFALGS_DEPENDENCY) $(CPPFLAGS)
$(eval CCL = $(CPP))
@$(DISAMS) $@ > [email protected]
else
$(TMP_ROOT)/%.o: %.c $(TMP_ROOT)/%.d
@$(CC) -c $< -o $@ $(CFALGS_DEPENDENCY) $(CFLAGS)
$(TMP_ROOT)/%.o: %.cpp $(TMP_ROOT)/%.d
@$(CC) -c $< -o $@ $(CFALGS_DEPENDENCY) $(CFLAGS)
$(eval CCL = $(CPP))
endif
$(TMP_ROOT)/%.d: ;
-include $(OBJS_DEPENDENCY)
.PHONY : test
test: | clean
@DEBUG=1 $(MAKE) test_build_and_run
-@rm $(BIN)
-@rm -R $(TMP_ROOT)
.PHONY : test_optimized
test_optimized: | clean
@$(MAKE) test_build_and_run
-@rm $(BIN)
-@rm -R $(TMP_ROOT)
.PHONY : test_build_and_run
test_build_and_run: | create_tree test_add_flags test_build
$(BIN)
.PHONY : test_add_flags
test_add_flags:
$(eval CFLAGS:=-coverage $(CFLAGS) -DDEBUG=1 -Werror)
$(eval LINKER_FLAGS:=-coverage -DDEBUG=1 $(LINKER_FLAGS))
.PHONY : test_build
test_build: $(LIB_OBJS)
@$(CC) -c ./tests/shorts.c -o $(TMP_ROOT)/shorts.o $(CFALGS_DEPENDENCY) $(CFLAGS)
@$(CCL) -o $(BIN) $(LIB_OBJS) $(TMP_ROOT)/shorts.o $(OPTIMIZATION) $(LINKER_FLAGS)
.PHONY : clean
clean:
-@rm $(BIN)
-@rm -R $(TMP_ROOT)
-@mkdir -p $(BUILDTREE)
.PHONY : run
run: | build
@$(BIN)
.PHONY : db
db: | clean
DEBUG=1 $(MAKE) build
$(DB) $(BIN)
.PHONY : create_tree
create_tree:
-@mkdir -p $(BUILDTREE)
########
## Helper Tasks
ifndef DUMP_LIB
.PHONY : libdump
libdump: cmake
else
.PHONY : libdump
libdump: cmake
-@rm -R $(DUMP_LIB)
@mkdir $(DUMP_LIB)
@mkdir $(DUMP_LIB)/src
@mkdir $(DUMP_LIB)/include
@mkdir $(DUMP_LIB)/all # except README.md files
-@cp -n $(foreach dir,$(LIBDIR_PUB), $(wildcard $(addsuffix /, $(basename $(dir)))*.[^m]*)) $(DUMP_LIB)/all
-@cp -n $(foreach dir,$(LIBDIR_PRIV), $(wildcard $(addsuffix /, $(basename $(dir)))*.[^m]*)) $(DUMP_LIB)/all
-@cp -n $(foreach dir,$(LIBDIR_PUB), $(wildcard $(addsuffix /, $(basename $(dir)))*.h*)) $(DUMP_LIB)/include
-@cp -n $(foreach dir,$(LIBDIR_PRIV), $(wildcard $(addsuffix /, $(basename $(dir)))*.h*)) $(DUMP_LIB)/include
-@cp -n $(foreach dir,$(LIBDIR_PUB), $(wildcard $(addsuffix /, $(basename $(dir)))*.[^hm]*)) $(DUMP_LIB)/src
-@cp -n $(foreach dir,$(LIBDIR_PRIV), $(wildcard $(addsuffix /, $(basename $(dir)))*.[^hm]*)) $(DUMP_LIB)/src
endif
ifndef CMAKE_LIBFILE_NAME
.PHONY : cmake
cmake:
else
.PHONY : cmake
cmake:
-@rm $(CMAKE_LIBFILE_NAME)
@touch $(CMAKE_LIBFILE_NAME)
@echo 'project(facil.io C)' >> $(CMAKE_LIBFILE_NAME)
@echo 'cmake_minimum_required(VERSION 2.4)' >> $(CMAKE_LIBFILE_NAME)
@echo '' >> $(CMAKE_LIBFILE_NAME)
@echo 'find_package(Threads REQUIRED)' >> $(CMAKE_LIBFILE_NAME)
@echo '' >> $(CMAKE_LIBFILE_NAME)
@echo 'set(facil.io_SOURCES' >> $(CMAKE_LIBFILE_NAME)
@$(foreach src,$(LIBSRC),echo ' $(src)' >> $(CMAKE_LIBFILE_NAME);)
@echo ')' >> $(CMAKE_LIBFILE_NAME)
@echo '' >> $(CMAKE_LIBFILE_NAME)
@echo 'add_library(facil.io $${facil.io_SOURCES})' >> $(CMAKE_LIBFILE_NAME)
@echo 'target_link_libraries(facil.io' >> $(CMAKE_LIBFILE_NAME)
@echo ' PRIVATE Threads::Threads' >> $(CMAKE_LIBFILE_NAME)
@$(foreach src,$(LINKER_LIBS),echo ' PUBLIC $(src)' >> $(CMAKE_LIBFILE_NAME);)
@echo ' )' >> $(CMAKE_LIBFILE_NAME)
@echo 'target_include_directories(facil.io' >> $(CMAKE_LIBFILE_NAME)
@$(foreach src,$(LIBDIR_PUB),echo ' PUBLIC $(src)' >> $(CMAKE_LIBFILE_NAME);)
@$(foreach src,$(LIBDIR_PRIV),echo ' PRIVATE $(src)' >> $(CMAKE_LIBFILE_NAME);)
@echo ')' >> $(CMAKE_LIBFILE_NAME)
@echo '' >> $(CMAKE_LIBFILE_NAME)
endif
# Prints the make variables, used for debugging the makefile
.PHONY : vars
vars:
@echo "CC: $(CC)"
@echo ""
@echo "BIN: $(BIN)"
@echo ""
@echo "LIBDIR_PUB: $(LIBDIR_PUB)"
@echo ""
@echo "LIBDIR_PRIV: $(LIBDIR_PRIV)"
@echo ""
@echo "MAINDIR: $(MAINDIR)"
@echo ""
@echo "FOLDERS: $(FOLDERS)"
@echo ""
@echo "BUILDTREE: $(BUILDTREE)"
@echo ""
@echo "LIBSRC: $(LIBSRC)"
@echo ""
@echo "MAINSRC: $(MAINSRC)"
@echo ""
@echo "LIB_OBJS: $(LIB_OBJS)"
@echo ""
@echo "MAIN_OBJS: $(MAIN_OBJS)"
@echo ""
@echo "OBJS_DEPENDENCY: $(OBJS_DEPENDENCY)"
@echo ""
@echo "CFLAGS: $(CFLAGS)"
@echo ""
@echo "CPPFLAGS: $(CPPFLAGS)"
@echo ""
@echo "LINKER_LIBS: $(LINKER_LIBS)"
@echo ""
@echo "LINKER_FLAGS: $(LINKER_FLAGS)"