#**********************************************************
#
# This software is part of J.-S. Caux's ABACUS++ library.
#
# Copyright (c).
#
#-----------------------------------------------------------
#
# File:  Makefile
#
#
#***********************************************************/

# Semver
VERSION = ABACUS_1.0.0

# Directories
BASE_DIR = .
OBJ_DIR = $(BASE_DIR)/obj
HEAD_DIR = $(BASE_DIR)/include
LIB_DIR = $(BASE_DIR)/lib
SRC_DIR = $(BASE_DIR)/src
BIN_DIR = $(BASE_DIR)/bin

# Source file extension
SRC_EXT = cc

# Compiler choice
CXX = g++
CXXFLAGS = -fopenmp
LDFLAGS = -O3 -w -fopenmp
# Compilation command
COMPILE = $(CXX) -I$(BASE_DIR)/include/ -L$(LIB_DIR)/ $(LDFLAGS)

# Compiler choice and command (parallel case)
MPICXX = mpicxx
COMPILE_MPI = mpicxx -I$(BASE_DIR)/include/ -L$(LIB_DIR)/ $(LDFLAGS)


# Enable finding all sources
vpath %.$(SRC_EXT) $(wildcard $(SRC_DIR)/*)
vpath %.h

# List of all source files
SOURCES_ALL = $(shell find $(SRC_DIR) -name '*.$(SRC_EXT)')
# Those involving parallelism
SOURCES_PAR = $(filter %_par.$(SRC_EXT) %_par_Prepare.$(SRC_EXT) %_par_Run.$(SRC_EXT) %_par_Wrapup.$(SRC_EXT) %_server.$(SRC_EXT) %_client.$(SRC_EXT), $(SOURCES_ALL))
# Executables
SOURCES_EXECS_ALL = $(shell find $(SRC_DIR)/EXECS -name '*.$(SRC_EXT)')
# Executables (parallel)
SOURCES_EXECS_PAR = $(filter %_par.$(SRC_EXT) %_par_Prepare.$(SRC_EXT) %_par_Run.$(SRC_EXT) %_par_Wrapup.$(SRC_EXT) %_server.$(SRC_EXT) %_client.$(SRC_EXT), $(SOURCES_EXECS_ALL))
SOURCES_EXECS = $(filter-out $(SOURCES_EXECS_PAR), $(SOURCES_EXECS_ALL))
# ... leaving the basic sources
SOURCES = $(filter-out $(SOURCES_PAR) $(SOURCES_EXECS), $(SOURCES_ALL))

# List of all header files
HEADERS = $(notdir $(shell find $(HEAD_DIR) -name '*.h'))

# Objects to go into library
OBJECTS = $(patsubst %.$(SRC_EXT), $(OBJ_DIR)/%.o, $(notdir $(SOURCES)))

# Executables
EXECUTABLES = $(patsubst %.$(SRC_EXT), $(BIN_DIR)/%, $(notdir $(SOURCES_EXECS)))

# Executables (parallel)
EXECUTABLES_PAR = $(patsubst %.$(SRC_EXT), $(BIN_DIR)/%, $(notdir $(SOURCES_EXECS_PAR)))


# Main target: all executables (and thus the library, and thus all objects)
all: $(EXECUTABLES)

# Build executables
$(EXECUTABLES): $(BIN_DIR)/%: $(SRC_DIR)/EXECS/%.$(SRC_EXT) $(LIB_DIR)/lib$(VERSION).a
	$(COMPILE) $< -o $@ -l$(VERSION)

# Compile all object files
$(OBJ_DIR)/%.o: %.$(SRC_EXT)
	$(COMPILE) -c $< -o $@

# Create the ABACUS library
$(LIB_DIR)/lib$(VERSION).a : $(OBJECTS)
	ar -cr $(LIB_DIR)/lib$(VERSION).a $(OBJECTS)


###########################################
# Parallel version

.PHONY: parallel
parallel : $(EXECUTABLES_PAR)

$(EXECUTABLES_PAR): $(BIN_DIR)/%: $(SRC_DIR)/EXECS/%.$(SRC_EXT) $(LIB_DIR)/lib$(VERSION).a
	$(COMPILE_MPI) $< -o $@ -l$(VERSION)


###########################################
# Cleanup

.PHONY: clean
clean :
	/bin/rm -f $(OBJECTS)
	/bin/rm -f $(LIB_DIR)/lib$(VERSION).a
	/bin/rm -f $(EXECUTABLES)
	/bin/rm -f $(EXECUTABLES_PAR)


###########################################
# Documentation

.PHONY: docs
docs :
	doxygen ABACUS_Doxyfile && make -C docs/latex && cp docs/latex/refman.pdf docs/$(VERSION)_manual.pdf