CC = LANG=C g++
LFLAGS += -lssl -lcrypto -lrt
CFLAGS += -Wall -Werror

LFLAGS += $(shell grep 'EXTRA_LFLAGS' conf/config.in | cut -d: -f2-)

HEADERS = $(wildcard *.hpp) $(wildcard *.inc) $(wildcard *.in) $(wildcard conf/*.inc) $(wildcard conf/*.in)
ALL_SOURCES = $(wildcard *.cpp)
ALL_OBJECTS = $(patsubst %.cpp,%.o,$(ALL_SOURCES))

MAIN_FILES = main ac acl aio bump certs callout chain chroot common config ctx dns fdtable files hash hooks io ipc mkcert poll pool proxy queue reconfigure sni sock ssl ssl_common stats stats_file tout
CERTD_FILES = certd common config diskcache files hash hooks mkcert pool stats ssl_common sock
CERTDD_FILES = certdd

ifdef GPROF
    CFLAGS += -pg
    LFLAGS += -pg
endif

ifdef RELEASE
    CFLAGS += -O2 -DNDEBUG
else
    CFLAGS += -O0 -g
endif

ifdef TEST
ifneq ($(MAKECMDGOALS),test)
$(error TEST only for test)
endif
    CFLAGS += -DSSLBD_TEST
    LFLAGS += -lcppunit
    MAIN_OBJECTS = $(filter-out main.%,$(addsuffix .o,test $(MAIN_FILES)))
else
ifeq ($(MAKECMDGOALS),test)
$(error test only for TEST)
endif
    MAIN_OBJECTS = $(addsuffix .o,$(MAIN_FILES))
endif

CERTD_OBJECTS = $(addsuffix .o,$(CERTD_FILES))
CERTDD_OBJECTS = $(addsuffix .o,$(CERTDD_FILES))

BGREEN = "\\033[1\;32m"
GREEN = "\\033[32m"
NORM = "\\033[0m"


################################################################################


.PHONY: all
all: sslbd certd certdd
    $(info Ignored: $(filter-out $(MAIN_OBJECTS) $(CERTD_OBJECTS) $(CERTDD_OBJECTS),$(patsubst %.cpp,%.o,$(wildcard *.cpp))))


.PHONY: %-run
%-run: clean %
    ./$(word 2,$^) conf/$(word 2,$^).conf 2>&1

.PHONY: %-valgrind
%-valgrind: clean %
    @rm -f valgrind.$(word 2,$^).supp
    cat *.supp > valgrind.$(word 2,$^).supp
    valgrind \
        --gen-suppressions=all --suppressions=valgrind.$(word 2,$^).supp --leak-check=full --show-reachable=yes --track-origins=yes --track-fds=yes \
        ./$(word 2,$^) conf/$(word 2,$^).conf 2>&1
    rm valgrind.$(word 2,$^).supp

.PHONY: %-gdb
%-gdb: clean %
    gdb -ex run --args ./$(word 2,$^) conf/$(word 2,$^).conf

.PHONY: test
test: sslbd-valgrind
    which cppcheck &>/dev/null && cppcheck -q --enable=all . || true


gmon.txt: gmon.out
    gprof sslbd $(<) > $(@)

docs: $(ALL_SOURCES) $(HEADERS)
    mkdir -p $(@)
    echo "OUTPUT_DIRECTORY = $(@); PROJECT_NAME = sslbd; INPUT = .; QUIET = YES; EXTRACT_ALL = YES; EXTRACT_STATIC = YES; EXTRACT_PRIVATE = YES; WARNINGS = YES; GENERATE_LATEX = NO;" \
         "BUILTIN_STL_SUPPORT = YES; TYPEDEF_HIDES_STRUCT = YES; SOURCE_BROWSER = YES; STRIP_CODE_COMMENTS = NO; REFERENCED_BY_RELATION = YES; REFERENCES_RELATION = YES; HTML_OUTPUT = ./;" \
         "GENERATE_TREEVIEW = YES;" \
         "HAVE_DOT = `which dot >/dev/null 2>&1 && echo YES || echo NO`; CALL_GRAPH = YES; CALLER_GRAPH = YES;" \
    | tr ';' '\n' \
    | doxygen -

view-docs: docs
    firefox docs/index.html &>/dev/null &


sslbd: $(MAIN_OBJECTS)
certd: $(CERTD_OBJECTS)
certdd: $(CERTDD_OBJECTS)
sslbd certd certdd:
    @echo "$(BGREEN)$(@)$(NORM)"
    $(CC) \
    -o $(@) \
    $(^) \
    $(LFLAGS)

%.o: %.cpp $(HEADERS) Makefile
    @echo "$(GREEN)$(@)$(NORM)"
    $(CC) -c \
    $(CFLAGS) \
    $(<) \
    -o $(@)


.PHONY: clean
clean:
    rm -rf $(ALL_OBJECTS) sslbd certd certdd docs valgrind.*.supp gmon.* *.gmon.*