# The compiler
CC=g++

# Flags
CFLAGS=-Wall -larmadillo -std=c++11 -O3 -fopenmp
DBGFLAGS=-DDBG -g

MKDIR=mkdir -p
RMDIR=rm -rf

# Directories for binaries
BINDIR=./bin
DEBUGDIR=./debug

# Directories for object files
BUILDDIR=./build
BINOBJDIR=$(BUILDDIR)/objs
DEBUGOBJDIR=$(BUILDDIR)/debug

# Directory for latex source
LATEXDIR=./latex

# Source directories
SRC=./src
LIB=./lib
INCLUDE=./include

# Lib files
LIBSRCS=$(notdir $(shell find $(LIB) -type f))
LIBBINOBJS=$(addprefix $(BINOBJDIR)/,  $(LIBSRCS:.cpp=.o))
LIBDEBUGOBJS=$(addprefix $(DEBUGOBJDIR)/,  $(LIBSRCS:.cpp=.o))

# Location for Binaries
EXEC=$(basename $(notdir $(shell find $(SRC) -type f)))
BINS=$(addprefix $(BINDIR)/, $(EXEC))
DEBUGBINS=$(addprefix $(DEBUGDIR)/, $(EXEC))

# List phony targets
.PHONY: all profile debug latex clean binclean objclean latexclean 

# "Commands"
all: $(BINS)

debug: $(DEBUGBINS)

# build latex file
latex:
	$(MAKE) -C $(LATEXDIR)

# Rule for binaries
$(BINDIR)/%: $(BINOBJDIR)/%.o $(LIBBINOBJS)
	$(MKDIR) $(BINDIR)
	$(CC) $^ -o $@ $(CFLAGS) -I$(INCLUDE)

# Rule for debug binaries
$(DEBUGDIR)/%: $(DEBUGOBJDIR)/%.o $(LIBDEBUGOBJS)
	$(MKDIR) $(DEBUGDIR)
	$(CC) $^ -o $@ $(CFLAGS) $(DBGFLAGS) -I$(INCLUDE)

# Rule for object files
$(BINOBJDIR)/%.o: $(SRC)/%.cpp
	$(MKDIR) $(BINOBJDIR)
	echo $(LIBBINOBJS)
	$(CC) -c $^ -o $@ $(CFLAGS) -I$(INCLUDE)

# Rule for debug object files
$(DEBUGOBJDIR)/%.o: $(SRC)/%.cpp
	$(MKDIR) $(DEBUGOBJDIR)
	$(CC) -c $^ -o $@ $(CFLAGS) $(DBGFLAGS) -I$(INCLUDE)

# Rule for object files
$(BINOBJDIR)/%.o: $(LIB)/%.cpp
	$(MKDIR) $(BINOBJDIR)
	$(CC) -c $^ -o $@ $(CFLAGS) -I$(INCLUDE)

# Rule for debug object files
$(DEBUGOBJDIR)/%.o: $(LIB)/%.cpp
	$(MKDIR) $(DEBUGOBJDIR)
	$(CC) -c $^ -o $@ $(CFLAGS) $(DBGFLAGS) -I$(INCLUDE)

# Cleaning
clean: objclean binclean latexclean

latexclean:
	$(MAKE) -C $(LATEXDIR) clean

objclean:
	$(RMDIR) $(BUILDDIR)

binclean:
	$(RMDIR) $(BINDIR) $(DEBUGDIR)
