# ========== SETUP SOURCE FILES ==========

EXCS = main
SRCS = $(wildcard ed/*.cpp) $(wildcard la/*.cpp)
TESTS = $(patsubst %.cpp,%,$(wildcard test/*.cpp))

# ========== SETUP COMPILER FLAGS ==========

# Define compiler and default c++-flags
CC=g++-8
CPPFLAGS=-Wall -g1 -m64 -std=c++17 -Wno-unused
CPPFLAGS_EXTRA=
LDFLAGS=
LDFLAGS_EXTRA=

# include optional make.inc file
include $(make_inc)

# get directory Makefile is located in, we use it as default search path
CPPFLAGS_EXTRA+=-I$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

# ==========  SETUP DEPENDENCY FILE GENERATION ==========

# define dependency directory
DEP_DIR := .deps

# define flags for dependency file generation
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEP_DIR)/$*.d

# define target rule for object file that also generates dependency files
# %.o : %.cpp
%.o : %.cpp $(DEP_DIR)/%.d | $(DEP_DIR)
	@echo building $@
	$(CC) $(DEPFLAGS) $(CPPFLAGS) $(CPPFLAGS_EXTRA) -c $< 

# define target rule for dependency directory
$(DEP_DIR):
	@mkdir -p $@

# and of course we also need a list of dependency files
DEPFILES := $(SRCS:%.cpp=$(DEP_DIR)/%.d)

# make every dependency file a target
$(DEPFILES):
	@echo building $@

# and include the dependency files
include $(wildcard $(DEPFILES))

# ==========  BUILD TARGETS ==========

# target for building executables
$(EXCS): $(EXCS:%=%.o) $(SRCS:%.cpp=%.o)
	@echo building $@ from $^
	$(CC) $(CPPFLAGS) $(CPPFLAGS_EXTRA) $^ -o $@ $(LDFLAGS) $(LDFLAGS_EXTRA)

# target for building tests
$(TESTS): $(TESTS:%=%.o) $(SRCS:%.cpp=%.o)
	@echo building $@ from $^
	$(CC) $(CPPFLAGS) $(CPPFLAGS_EXTRA) $@.o $(SRCS:%.cpp=%.o) -o $@ $(LDFLAGS) $(LDFLAGS_EXTRA)

# ==========  TEST TARGETS ==========

test-la:
	@echo testing linear algebra module
	./test/test_la

test-lattice:
	@echo testing lattice
	./test/test_lattice

test-spin-lattice:
	@echo testing spin lattice
	./test/test_spin_lattice

test-tfim:
	@echo testing tfim
	./test/test_tfim

# ==========  CLEAN TARGETS ==========

clean-excs:
	@echo $(EXCS) | xargs rm -v || true

clean-tests:
	@echo $(TESTS) | xargs rm -v || true
	@find test -iname "*.o" -type f | xargs rm -v || true

clean-deps:
	@rm -rv $(DEP_DIR) || true

clean-objects:
	@find . -iname "*.o" -type f | xargs rm -v || true

.PHONY: build test test-la test-lattice test-spin-lattice test-tfim clean clean-excs clean-tests clean-deps clean-objects

build : $(EXCS) $(TESTS)
test  : test-la test-lattice test-spin-lattice test-tfim
clean : clean-deps clean-objects clean-excs clean-tests
