blob: 251736b51e602b15004e0b8e6e7259289973f172 [file] [log] [blame] [raw]
### 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/services facil/http facil/http/parsers facil/redis
# privately used subfolders in the lib root (this distinction is for CMake)
LIB_PRIVATE_SUBFOLDERS=facil/core/types/fiobj
### Development folders
# The development, non-library .c file(s) (i.e., the one with `int main(void)`.
MAIN_ROOT=./dev
# 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
# any extra include folders, space seperated list
INCLUDE= ./
# any preprocessosr defined flags we want, space seperated list (i.e. DEBUG )
FLAGS:= FIOBJ_NESTING_PROTECTION=0
### 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
FLAGS:=$(FLAGS) DEBUG
OPTIMIZATION:=$(OPTIMIZATION) -fsanitize=address -fno-omit-frame-pointer
else
FLAGS:=$(FLAGS) NODEBUG
endif
##############
## OS specific data - compiler, assembler etc.
ifneq ($(OS),Windows_NT)
OS := $(shell uname)
endif
ifeq ($(OS),Darwin) # Run MacOS commands
# c compiler
CC=gcc
# c++ compiler
CPP=g++
# debugger
DB=lldb
# disassemble tool. Use stub to disable.
DISAMS=otool -tVX
# documentation commands
# DOCUMENTATION=cldoc generate $(INCLUDE_STR) -- --output ./html $(foreach dir, $(SRCDIR), $(wildcard $(addsuffix /, $(basename $(dir)))*.h*))
else
# c compiler
CC=gcc
# c++ compiler
CPP=g++
# 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)))
# 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)
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)
FLAGS:=$(FLAGS) HAVE_OPENSSL
LINKER_LIBS_EXT:=$(LINKER_LIBS_EXT) crypto ssl
endif
endif
# add ZLib library flags
# ifeq ($(shell printf "\#include \\"zlib.h\\"\\n int main(void) {}" | $(CC) $(INCLUDE_STR) -lz -xc -o /dev/null - >& /dev/null ; echo $$? ), 0)
ifeq ($(shell printf "\#include <zlib.h>\\nint main(void) {}" | $(CC) $(INCLUDE_STR) -lz -xc -o /dev/null - >& /dev/null ; echo $$? ), 0)
FLAGS:=$(FLAGS) HAVE_ZLIB
LINKER_LIBS_EXT:=$(LINKER_LIBS_EXT) z
endif
FLAGS_STR = $(foreach flag,$(FLAGS),$(addprefix -D, $(flag)))
MAIN_OBJS = $(foreach source, $(MAINSRC), $(addprefix $(TMP_ROOT)/, $(addsuffix .o, $(basename $(source)))))
LIB_OBJS = $(foreach source, $(LIBSRC), $(addprefix $(TMP_ROOT)/, $(addsuffix .o, $(basename $(source)))))
# the computed C flags
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)))
########
## Main Tasks
$(NAME): build
build: $(LIB_OBJS) $(MAIN_OBJS)
@$(CCL) -o $(BIN) $^ $(OPTIMIZATION) $(LINKER_FLAGS)
@$(DOCUMENTATION)
lib: libdump $(LIB_OBJS)
@$(CCL) -shared -o $(OUT_ROOT)/libfacil.so $^ $(OPTIMIZATION) $(LINKER_FLAGS)
@$(DOCUMENTATION)
ifdef DISAMS
$(TMP_ROOT)/%.o: %.c
@$(CC) -o $@ -c $^ $(CFLAGS)
@$(DISAMS) $@ > $@.s
$(TMP_ROOT)/%.o: %.cpp
@$(CPP) -o $@ -c $^ $(CPPFLAGS)
$(eval CCL = $(CPP))
@$(DISAMS) $@ > $@.s
else
$(TMP_ROOT)/%.o: %.c
@$(CC) -o $@ -c $^ $(CFLAGS)
$(TMP_ROOT)/%.o: %.cpp
@$(CPP) -o $@ -c $^ $(CPPFLAGS)
$(eval CCL = $(CPP))
endif
.PHONY : clean
clean:
-@rm $(BIN)
-@rm -R $(TMP_ROOT)
-@mkdir -p $(BUILDTREE)
.PHONY : run
run: | build
@$(BIN)
.PHONY : db
db: | clean build
$(DB) $(BIN)
########
## 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: $(OBJS)"
@echo ""
@echo "MAIN_OBJS: $(OBJS)"
@echo ""
@echo "CFLAGS: $(CFLAGS)"
@echo ""
@echo "CPPFLAGS: $(CPPFLAGS)"
@echo ""
@echo "LINKER_LIBS: $(LINKER_LIBS)"
@echo ""
@echo "LINKER_FLAGS: $(LINKER_FLAGS)"