SRCDIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
JULIAHOME := $(abspath $(SRCDIR)/../..)
BUILDDIR := .
include $(JULIAHOME)/Make.inc

JCFLAGS_COMMON += $(CFLAGS) $(JL_CFLAGS)
JCXXFLAGS_COMMON += $(CXXFLAGS) $(JL_CXXFLAGS)
JCPPFLAGS_COMMON += $(CPPFLAGS) $(JL_CPPFLAGS)
JLDFLAGS += $(LDFLAGS) $(JL_LDFLAGS)

SRCS := hashing timefuncs ptrhash strhash operators utf8 ios htable bitvector \
	int2str libsupportinit arraylist strtod rle eytzinger
ifeq ($(OS),WINNT)
SRCS += asprintf strptime
ifeq ($(ARCH),i686)
SRCS += _setjmp.win32
else ifeq ($(ARCH),x86_64)
SRCS += _setjmp.win64
endif
endif

HEADERS := $(wildcard *.h) $(wildcard *.inc) $(LIBUV_INC)/uv.h

OBJS := $(SRCS:%=$(BUILDDIR)/%.o)
DOBJS := $(SRCS:%=$(BUILDDIR)/%.dbg.obj)

FLAGS_COMMON := $(HFILEDIRS:%=-I%) -I$(LIBUV_INC) -I$(UTF8PROC_INC) -DJL_LIBRARY_EXPORTS_INTERNAL -DUTF8PROC_EXPORTS
FLAGS_COMMON += -Wall -Wno-strict-aliasing -fvisibility=hidden -Wpointer-arith -Wundef
JCFLAGS_COMMON += -Wold-style-definition -Wstrict-prototypes -Wc++-compat

SHIPFLAGS_COMMON += $(FLAGS_COMMON)
DEBUGFLAGS_COMMON += $(FLAGS_COMMON)

default: release

$(BUILDDIR):
	mkdir -p $(BUILDDIR)

$(BUILDDIR)/%.o: $(SRCDIR)/%.c $(HEADERS) | $(BUILDDIR)
	@$(call PRINT_CC, $(CC) $(JCPPFLAGS) $(JCFLAGS) $(SHIPFLAGS) $(DISABLE_ASSERTIONS) -c $< -o $@)
$(BUILDDIR)/%.dbg.obj: $(SRCDIR)/%.c $(HEADERS) | $(BUILDDIR)
	@$(call PRINT_CC, $(CC) $(JCPPFLAGS) $(JCFLAGS) $(DEBUGFLAGS) -c $< -o $@)
$(BUILDDIR)/%.o: $(SRCDIR)/%.S | $(BUILDDIR)
	@$(call PRINT_CC, $(CC) $(JCPPFLAGS) $(SHIPFLAGS) -c $< -o $@)
$(BUILDDIR)/%.dbg.obj: $(SRCDIR)/%.S | $(BUILDDIR)
	@$(call PRINT_CC, $(CC) $(JCPPFLAGS) $(DEBUGFLAGS) -c $< -o $@)

$(BUILDDIR)/host/Makefile:
	mkdir -p $(BUILDDIR)/host
	@# add Makefiles to the build directories for convenience (pointing back to the source location of each)
	@printf "%s\n" '# -- This file is automatically generated in julia/Makefile -- #' > $@
	@printf "%s\n" 'BUILDDIR=$(BUILDDIR)/host' >> $@
	@printf "%s\n" 'BUILDING_HOST_TOOLS=1' >> $@
	@printf "%s\n" 'include $(SRCDIR)/Makefile' >> $@

release: $(BUILDDIR)/libsupport.a regenerate-compile_commands
debug: $(BUILDDIR)/libsupport-debug.a regenerate-compile_commands

$(BUILDDIR)/libsupport.a: $(OBJS) | $(BUILDIR)
	rm -rf $@
	@$(call PRINT_LINK, $(AR) -rcs $@ $^)

$(BUILDDIR)/libsupport-debug.a: $(DOBJS) | $(BUILDDIR)
	rm -rf $@
	@$(call PRINT_LINK, $(AR) -rcs $@ $^)

$(BUILDDIR)/host/libsupport.a: $(BUILDDIR)/host/Makefile
	$(MAKE) -C $(BUILDDIR)/host libsupport.a

$(BUILDDIR)/host/libsupport-debug.a: $(BUILDDIR)/host/Makefile
	$(MAKE) -C $(BUILDDIR)/host libsupport-debug.a

# Common flag patterns for all clang tooling (clang-sa, clang-tidy, compile-database)
CLANG_TOOLING_S_FLAGS = $(CLANGSA_FLAGS) $(DEBUGFLAGS_CLANG) $(JCPPFLAGS_CLANG)
CLANG_TOOLING_C_FLAGS = $(CLANGSA_FLAGS) $(DEBUGFLAGS_CLANG) $(JCPPFLAGS_CLANG) $(JCFLAGS_CLANG)

# Included files in support
INCLUDED_SUPPORT_FILES := hashing.c:MurmurHash3.c

# Compilation database generation
.PHONY: regenerate-compile_commands
regenerate-compile_commands:
	@TMPFILE=$$(mktemp $(abspath $(BUILDDIR)/compile_commands.json.XXXXXX)); \
	{ \
		CLANG_TOOLING_S_FLAGS="$$($(JULIAHOME)/contrib/escape_json.sh clang $(JCPPFLAGS) $(DEBUGFLAGS))"; \
		CLANG_TOOLING_C_FLAGS="$$($(JULIAHOME)/contrib/escape_json.sh clang $(JCPPFLAGS) $(JCFLAGS) $(DEBUGFLAGS))"; \
		echo "["; \
		first=true; \
		for src in $(SRCS); do \
			[ "$$first" = "true" ] && first=false || echo ","; \
			if [ -f $(SRCDIR)/$$src.S ]; then \
				cmd="$${CLANG_TOOLING_S_FLAGS}, \"$$src.S\""; \
				file_path="$$src.S"; \
			else \
				cmd="$${CLANG_TOOLING_C_FLAGS}, \"$$src.c\""; \
				file_path="$$src.c"; \
			fi; \
			printf '{\n  "directory": "%s",\n  "file": "%s",\n  "arguments": [%s]\n}' "$(abspath $(SRCDIR))" "$$file_path" "$$cmd"; \
		done; \
		for included_pair in $(INCLUDED_SUPPORT_FILES); do \
			[ "$$first" = "true" ] && first=false || echo ","; \
			including_file=$${included_pair%%:*}; \
			included_file=$${included_pair##*:}; \
			cmd="$${CLANG_TOOLING_C_FLAGS}, \"$$including_file\""; \
			printf '{\n  "directory": "%s",\n  "file": "%s",\n  "arguments": [%s]\n}' "$(abspath $(SRCDIR))" "$$included_file" "$$cmd"; \
		done; \
		echo "]"; \
	} > $$TMPFILE; \
	if ! cmp -s $$TMPFILE $(BUILDDIR)/compile_commands.json; then \
		mv $$TMPFILE $(BUILDDIR)/compile_commands.json; \
	else \
		rm -f $$TMPFILE; \
	fi

compile-database: regenerate-compile_commands
	@echo "Compilation database created for src/support"

clean:
	rm -f $(BUILDDIR)/*.o
	rm -f $(BUILDDIR)/*.dbg.obj
	rm -f $(BUILDDIR)/*.a
	rm -f $(BUILDDIR)/*~ *#
	rm -f $(BUILDDIR)/core*
	rm -f $(BUILDDIR)/libsupport.a
	rm -f $(BUILDDIR)/libsupport-debug.a
	rm -f $(BUILDDIR)/compile_commands.json*
	rm -f $(BUILDDIR)/host/*

.PHONY: compile-database
