#
##Copyright University of Reims Champagne-Ardenne
#Authors and Contributors: Corentin LEFEBVRE, Johanna KLEIN, Emmanuel PLUOT,
#                          Hugo Roussel, Gaetan RUBEZ, Hassan KHARTABIL,
#                          Jean-Charles BOISSON and Eric HENON
#(24/07/2017)
##jean-charles.boisson@univ-reims.fr, eric.henon@univ-reims.fr
#
##This software is a computer program whose purpose is to 
#detect and prepare the plot of molecular interactions
#from electron density and IGM reference using promolecular
#electron density.
#
##This software is governed by the CeCILL-C license under French law and
#abiding by the rules of distribution of free software.  You can  use, 
#modify and/ or redistribute the software under the terms of the CeCILL-C
#license as circulated by CEA, CNRS and INRIA at the following URL
#"http://www.cecill.info". 
#
##As a counterpart to the access to the source code and  rights to copy,
#modify and redistribute granted by the license, users are provided only
#with a limited warranty  and the software's author,  the holder of the
#economic rights,  and the successive licensors  have only  limited
#liability. 
#
##In this respect, the user's attention is drawn to the risks associated
#with loading,  using,  modifying and/or developing or reproducing the
#software by the user in light of its specific status of free software,
#that may mean  that it is complicated to manipulate,  and  that  also
#therefore means  that it is reserved for developers  and  experienced
#professionals having in-depth computer knowledge. Users are therefore
#encouraged to load and test the software's suitability as regards their
#requirements in conditions enabling the security of their systems and/or 
#data to be ensured and,  more generally, to use and operate it in the 
#same conditions as regards security. 
#
##The fact that you are presently reading this means that you have had
#knowledge of the CeCILL-C license and that you accept its terms.
#
#
# COMMENT or UNCOMMENT appropriately the lines below 
# in order to match your compiler environement
# (GNU, or INTEL, or NVIDIA) 
# DEFAULT = GNU compiler with OpenMP

######## Indicate the family of your C++ compiler #######
# 3 choices :a)GNU or Clang on Mac OS b) INTEL c)NVIDIA
# #######################################################

##### choice a) for either GNU or Clang #############
CppCompilerFamily=GNU

##### choice b)  #############
#CppCompilerFamily=INTEL

##### choice c)  #############
#CppCompilerFamily=NVIDIA
# (Note: since 2020 "PGI Compilers and Tools" technology is a part of the Nvidia HPC SDK product)

######## Indicate the path to your compiler, including its name
# please make attention to correspondance with CppCompilerFamily
# if GNU path to g++, if INTEL path to icpc, ...

##### choice a)  for GNU #############
CppCompilerExec=g++

##### choice a') for Clang (Mac OS) #############
#CppCompilerExec=clang++

##### choice b)  for INTEL #############
#CppCompilerExec=icpx

##### choice c)  for NVIDIA #############
# Since 2020 "PGI Compilers and Tools" technology is a part of the Nvidia HPC SDK product 
#CppCompilerExec=nvc++


######## Indicate the version of your C++ compiler i.e. below and above :
#  a) version 5 for g++ (5_and_above or 4_and_below)
#  b) 2015 version for intel (2015_and_above or 2014_and_below)
#  c) no need for portland (any)


##### choice a) for either GNU or Clang #############
#CppCompilerVersion=4_and_below
CppCompilerVersion=5_and_above


##### choice b)  #############
#CppCompilerVersion=2014_and_below
#CppCompilerVersion=2015_and_above

##### (no) choice c)  #############
#CppCompilerVersion=any

######## Indicate if you want to use OpenMP or not: YES or NO

OpenMP=YES
#OpenMP=NO

################################################################
# NO NEED TO MAKE MODIFICATIONS IN THE REST OF THE FILE ########
################################################################

#for GNU >= 5 and INTEL "-Ofast" disabled for "-O3"
#due to some instabilities for double managment

ifeq "$(CppCompilerFamily)" "GNU"
 	CFLAGS= -Werror -Wall -ansi -pedantic
#	CFLAGS= -Werror -Wall -ansi -pedantic -fsanitize=address 
#	CFLAGS= -Wall -ansi -pedantic

#	CFLAGS+= -std=c++11 -Wno-stringop-truncation
#	CFLAGS+= -std=c++11

	ifeq "$(CppCompilerExec)" "clang++"
		CFLAGS+= -std=c++11
	else
		CFLAGS+= -std=c++11 -Wno-stringop-truncation
	endif

	ifeq "$(CppCompilerVersion)" "4_and_below"
		CFLAGS+= -O2
	else
		CFLAGS+= -O3
	endif
endif

ifeq "$(CppCompilerFamily)" "INTEL"
	CFLAGS= -Werror -Wall -ansi -pedantic -O3
	CFLAGS+= -std=c++11
endif

ifeq "$(CppCompilerFamily)" "NVIDIA"
	#CFLAGS= -fast -alias=ansi
	CFLAGS= -fast -pedantic -std=c++11 -fstrict-aliasing
endif

ifeq "$(OpenMP)" "YES"

	ifeq "$(CppCompilerFamily)" "GNU"
		CFLAGS+= -fopenmp
		LDFLAGS= -fopenmp
	endif

	ifeq "$(CppCompilerFamily)" "INTEL"
		ifeq "$(CppCompilerVersion)" "2014_and_below"
			CFLAGS+= -openmp
			LDFLAGS= -openmp
		else
			CFLAGS+= -qopenmp -qoverride-limits
			LDFLAGS= -qopenmp
		endif
	endif

	ifeq "$(CppCompilerFamily)" "NVIDIA"
		CFLAGS+= -mp
		LDFLAGS= -mp
	endif
else
	CFLAGS+= -DNo_OpenMP
endif	

# For cpp files
SRCdir=src

# For header files
INCdir=$(SRCdir)/include

# For object files
OBJdir=objectFiles

#Does not forget the "include" directory
CFLAGS+=-I $(INCdir)

#For debugging or profiling
#CFLAGS+= -g

#Name of the executable can be adapted
EXEC=IGMPLOT

#The original objects (V1.0)
OBJ = $(OBJdir)/igmplot.o $(OBJdir)/reader.o $(OBJdir)/output.o $(OBJdir)/vmdFileGenerator.o

#JC Removing inline methods ==> cpp corresponding to .h implementation
OBJ+= $(OBJdir)/LocalData.o $(OBJdir)/Results.o $(OBJdir)/NCISolver.o $(OBJdir)/Node.o $(OBJdir)/ProgData.o

#JC ADD for WF
OBJ+= $(OBJdir)/WFreader.o

#JC ADD for eig3
OBJ+= $(OBJdir)/eig3.o

#JC ADD for toolbox
OBJ+= $(OBJdir)/toolbox.o

#JC ADD ADF library
OBJ+= $(OBJdir)/ADF_ArrayList.o $(OBJdir)/ADF_KFReader.o

#JC If any .o has been (re)created ==> move it to OBJdir
$(EXEC): show_configuration $(OBJ)
	-@echo "Linking    $(EXEC)"
	-@for i in *.o ; do if [ $$i != "*.o" ] ; then mv $$i $(OBJdir) ; fi ; done
	-@$(CppCompilerExec) -o $@ $(OBJ) $(LDFLAGS)

#JC all cpp need a corresponding h (for igmplot, it is empty)
#   but any modification in cpp or h ==> compilation
$(OBJdir)/%.o: $(SRCdir)/%.cpp $(INCdir)/%.h
	-@echo "Generating $@"
	-@mkdir -p $(OBJdir)
	-@$(CppCompilerExec) $(CFLAGS) -c $<

#JC just for showing which are the choices (and be sure not to make anything odd)
show_configuration:
	@echo ""
	@echo "CppCompilerFamily  = $(CppCompilerFamily)"
	@echo "CppCompilerExec    = $(CppCompilerExec)"
	@echo "CppCompilerVersion = $(CppCompilerVersion)"
	@echo "OpenMP             = $(OpenMP)"
	@echo "CFLAGS             = $(CFLAGS)"
	@echo "LDLAGS             = $(LDFLAGS)"
	@echo ""

###------------------------------
### Cleaning
###------------------------------------------------------------

clean:
	-@rm -rf $(OBJdir)
#if compilation failed, some object files can be here
	-@rm -rf *.o

clean_all: clean clean_doc cleanSource
	-@rm -rf $(EXEC)

cleanSource:
	-@find . \( -name "*~" -o -name "*.old" -o -name "#*" \) -print -exec rm \{\} \;


SAMPLE_DIR=../samples

# Never automatically called
clean_samples: cleanSource
	-@rm -f log; for i in $(SAMPLE_DIR)/*_example       ; do if [ -d $$i ] ; then rm -f $$i/*.vmd  $$i/*.txt $$i/*.gnu $$i/out-* $$i/runinfo $$i/*cube $$i/*dat $$i/*.log $$i/._* 2>> /dev/null ; fi ; done
	-@           for i in $(SAMPLE_DIR)/*_example/test* ; do if [ -d $$i ] ; then rm -f $$i/*.vmd  $$i/*.txt $$i/*.gnu $$i/out-* $$i/runinfo $$i/*cube $$i/*dat $$i/*.log $$i/._* 2 $$i/*-coord.xyz>> /dev/null ; fi ; done

###------------------------------
### Docs
###------------------------------------------------------------

DOC_OUTPUT_LOG = doc_output.log
DOC_ERRORS_LOG = doc_errors.log

doc:
	-@mkdir -p docs

# Launch documentation generation
	-@if [ `command -v doxygen` ] ; then printf "Documentation generation ... "  ; rm -f $(DOC_ERRORS_LOG); doxygen Doxyfile 2> $(DOC_ERRORS_LOG) 1> $(DOC_OUTPUT_LOG);\
	else echo "doxygen is not available, documentation can not be generated" ; fi

# Check if there are some warnings/errors
	-@if [ -s $(DOC_ERRORS_LOG) ]; then printf "KO\n==> There are some errors/warnings during documentation generation, see $(DOC_ERRORS_LOG)\n" ;\
	else printf "OK\nEverything works fine\n"; rm -f $(DOC_ERRORS_LOG) $(DOC_OUTPUT_LOG); fi

clean_doc:
	-@rm -rf docs $(DOC_ERRORS_LOG) $(DOC_OUTPUT_LOG)


###------------------------------
### Help
###------------------------------------------------------------

help:
	@echo ""
	@echo "Available targets:"
	@echo "  $(EXEC) (default target)     : full compilation of the projet"
	@echo "  show_configuration           : description of the current configuration (type of compiler, OpenMP activation and path to the compiler)"
	@echo "  doc                          : generate the source code documentation thanks to doxygen (makes nothing if doxygen does not exist)"
	@echo "  clean                        : remove object files (.o) but the igmplot executable remains"
	@echo "  clean_all                    : remove object files (.o), igmplot executable and generated documentation (if exists)"
	@echo "  clean_samples                : clear all samples output data (for making a new released for instance, ...)"
	@echo ""

.PHONY:  $(EXEC) show_configuration clean clean_all cleanSource doc clean_doc help clean_samples
