# COPYRIGHT
#
#  Copyright 2007 Johannes Kaestner (kaestner@theochem.uni-stuttgart.de),
#  Tom Keal (thomas.keal@stfc.ac.uk)
#  Joanne Carr (joanne.carr@stfc.ac.uk)
#
#  This file is part of DL-FIND.
#
#  DL-FIND is free software: you can redistribute it and/or modify
#  it under the terms of the GNU Lesser General Public License as 
#  published by the Free Software Foundation, either version 3 of the 
#  License, or (at your option) any later version.
#
#  DL-FIND is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public 
#  License along with DL-FIND.  If not, see 
#  <http://www.gnu.org/licenses/>.
#

# Note: using -module (or equivalent) to tell dl_find where to put its .mod files,
# and -I<include_path> to tell it where to find the .mod files from crystal and 
# another -I<include path> for its own .mod files.

# GNU make features used: VPATH, MAKECMDGOALS, conditional execution

# no memory usage stats available.
ifdef DLF-PPFLAGS
   PPFLAGS=$(DLF-PPFLAGS)
else
   PPFLAGS = -DOLDALLOC
endif
ALLOC = old
# DEXT is now set in the CRYSTAL include files.
## if g95, intel, gfortran
#DEXT = F90
## if portland
#DEXT = F95
OBJDIR = $(ARCH)/objects
# ARCH is exported from the crystal make process.
PARA = $(MAKECMDGOALS)# a gnu make feature
#VPATH=/home/vbn92651/cry_dl_find/obj/Linux-pgf/std/
# vpath, set on the crystal side, is also a gnu make feature, as is conditional execution (the ifeq's used below)
ARCHIVE = ar rcv
RANLIB = ar ts

.SUFFIXES:
.SUFFIXES: .f90 .o .mod

# modules used by more than one file
OBJ_MOD = $(OBJDIR)/dlf_stat_module.o $(OBJDIR)/dlf_global_module.o $(OBJDIR)/dlf_allocate.o $(OBJDIR)/dlf_util.o \
          $(OBJDIR)/dlf_sort.o

# Objects that work without numerical libraries 
OBJ_NOLAPACK = $(OBJDIR)/dl-find.o $(OBJDIR)/dlf_convergence.o $(OBJDIR)/dlf_checkpoint.o $(OBJDIR)/dlf_svnversion.o\
       $(OBJDIR)/dlf_formstep.o $(OBJDIR)/dlf_scalestep.o \
       $(OBJDIR)/dlf_lbfgs.o $(OBJDIR)/dlf_time.o \
       $(OBJDIR)/dlf_task.o $(OBJDIR)/dlf_neb.o $(OBJDIR)/dlf_qts.o $(OBJDIR)/dlf_dimer.o $(OBJDIR)/dlf_conint.o $(OBJDIR)/dlf_coords.o \
       $(OBJDIR)/dlf_parallel_opt.o $(OBJDIR)/dlf_microiter.o $(OBJDIR)/dlfind_crystal.o

# Objects that need LAPACK linked in
OBJ_LAPACK = $(OBJDIR)/dlf_hdlc_matrixlib.o $(OBJDIR)/dlf_hdlc_primitive.o $(OBJDIR)/dlf_hdlc_constraint.o \
         $(OBJDIR)/dlf_hdlc_hdlclib.o $(OBJDIR)/dlf_hdlc_interface.o $(OBJDIR)/dlf_linalg.o

OBJ =  $(OBJ_NOLAPACK) $(OBJ_LAPACK) 

DLFINDLIB = libdlf.a

ifeq ($(findstring parallel,$(PARA)),parallel)
     EXTRAS = $(OBJDIR)/dlf_mpi.o   
else
     EXTRAS = $(OBJDIR)/dlf_serial.o   
endif

$(DLFINDLIB): $(OBJ_MOD) $(EXTRAS) $(OBJ)   
	$(ARCHIVE) $(DLFINDLIB) $(OBJ_MOD) $(EXTRAS) $(OBJ)
	$(RANLIB) $(DLFINDLIB)

parallel: $(DLFINDLIB)

obj:	$(OBJ_MOD) $(OBJ) 

dlf_svnversion.f90: FORCE 
	cp dlf_svnversion.head dlf_svnversion.f90
	-svnversion -n . >> dlf_svnversion.f90
	echo '"' >> dlf_svnversion.f90
	echo "end subroutine dlf_svnversion" >> dlf_svnversion.f90

FORCE:

#
# The main rule for compiling f90 files:
#
$(OBJDIR)/%.o: %.f90
	@mkdir -p $(OBJDIR)
ifeq ($(ALLOC),old)
	   sed -e"s/call allocate *(/ aLLocate(/g" \
               -e"/ aLLocate(/s/,/(/" \
               -e"/ aLLocate(/s/\(.*\))/\1))/" \
               -e"s/call deallocate *(/deallocate(/" $*.f90 > $(OBJDIR)/$*_d.$(DEXT)
else
	  cp $*.f90 $(OBJDIR)/$*_d.$(DEXT)
endif	
#
# remove $(OBJDIR)/dlf_mpi_d.$(DEXT) if compiling the serial version, 
# and $(OBJDIR)/dlf_serial_d.$(DEXT) if the parallel one.
#
ifeq ($(findstring parallel,$(PARA)),parallel)
	@rm -f $(OBJDIR)/dlf_serial_d.$(DEXT)
else
	@rm -f $(OBJDIR)/dlf_mpi_d.$(DEXT)
endif
# the $(MODPREFIX)$(OBJDIR) must not have a space between the two variables (to cover -module <path> and -qmod=<path>, for instance)
	$(F90) $(F90FLAGSD) $(INCFLAG)$(OBJDIR) $(MODPREFIX)$(OBJDIR) $(PPFLAGS) -c $(OBJDIR)/$*_d.$(DEXT) -o $(OBJDIR)/$*.o
	@#rm $*_d.$(DEXT)
	@echo 

#
# Utilities
#
clean:
	rm -f $(OBJ_MOD) $(OBJ) $(OBJDIR)/*.mod $(OBJDIR)/main.o $(OBJDIR)/*_d.?9? $(OBJDIR)/dlf_mpi.o $(OBJDIR)/dlf_serial.o $(OBJDIR)/dlfind_crystal.o libdlf.a

# remove all module directories and executables
clean_all:
	rm -r g95 pg intel gfortran
	rm -f libdlf.a

doc:
	robodoc

#dependencies from g95 -M:
$(OBJDIR)/dlf_stat_module.o $(OBJDIR)/dlf_stat.mod $(OBJDIR)/dlf_parameter_module.mod: dlf_stat_module.f90
$(OBJDIR)/dlf_global_module.o $(OBJDIR)/dlf_global.mod: $(OBJDIR)/dlf_parameter_module.mod dlf_global_module.f90
$(OBJDIR)/dlf_allocate.o $(OBJDIR)/dlf_allocate.mod: $(OBJDIR)/dlf_parameter_module.mod dlf_allocate.f90
$(OBJDIR)/dlf_util.o $(OBJDIR)/dlf_store.mod $(OBJDIR)/bspline.mod: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_parameter_module.mod dlf_util.f90
$(OBJDIR)/dl-find.o: $(OBJDIR)/dlf_store.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_stat.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dl-find.f90
$(OBJDIR)/dlf_convergence.o $(OBJDIR)/dlf_convergence.mod: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_convergence.f90
$(OBJDIR)/dlf_checkpoint.o $(OBJDIR)/dlf_checkpoint.mod: $(OBJDIR)/dlf_stat.mod $(OBJDIR)/dlf_parameter_module.mod $(OBJDIR)/dlf_global.mod dlf_checkpoint.f90
$(OBJDIR)/dlf_svnversion.o: dlf_svnversion.f90
$(OBJDIR)/dlf_formstep.o $(OBJDIR)/dlf_hessian.mod $(OBJDIR)/dlf_formstep_module.mod: $(OBJDIR)/dlf_stat.mod $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_formstep.f90
$(OBJDIR)/dlf_scalestep.o $(OBJDIR)/dlf_linesearch.mod $(OBJDIR)/dlf_scalestep_module.mod: $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_scalestep.f90
$(OBJDIR)/dlf_lbfgs.o $(OBJDIR)/lbfgs_module.mod: $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_lbfgs.f90
$(OBJDIR)/dlf_time.o $(OBJDIR)/dlf_time.mod: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_time.f90
$(OBJDIR)/dlf_task.o $(OBJDIR)/dlf_task_module.mod: $(OBJDIR)/dlf_store.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_stat.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_task.f90
$(OBJDIR)/dlf_qts.o $(OBJDIR)/dlf_qts.mod: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_neb.mod $(OBJDIR)/dlf_parameter_module.mod dlf_qts.f90
$(OBJDIR)/dlf_neb.o $(OBJDIR)/dlf_neb.mod: $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlf_stat.mod $(OBJDIR)/bspline.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_neb.f90
$(OBJDIR)/dlf_dimer.o $(OBJDIR)/dlf_dimer.mod: $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlf_stat.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_dimer.f90
$(OBJDIR)/dlf_conint.o $(OBJDIR)/dlf_conint.mod: $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlf_hessian.mod $(OBJDIR)/dlf_stat.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_conint.f90
$(OBJDIR)/dlf_coords.o: $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_coords.f90
$(OBJDIR)/dlf_hdlc_matrixlib.o $(OBJDIR)/dlfhdlc_matrixlib.mod: $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_hdlc_matrixlib.f90
$(OBJDIR)/dlf_hdlc_primitive.o $(OBJDIR)/dlfhdlc_primitive.mod: $(OBJDIR)/dlfhdlc_matrixlib.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_hdlc_primitive.f90
$(OBJDIR)/dlf_hdlc_constraint.o $(OBJDIR)/dlfhdlc_constraint.mod: $(OBJDIR)/dlfhdlc_matrixlib.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_hdlc_constraint.f90
$(OBJDIR)/dlf_hdlc_hdlclib.o $(OBJDIR)/dlfhdlc_hdlclib.mod: $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlfhdlc_constraint.mod $(OBJDIR)/dlfhdlc_primitive.mod $(OBJDIR)/dlfhdlc_matrixlib.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_hdlc_hdlclib.f90
$(OBJDIR)/dlf_hdlc_interface.o: $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlfhdlc_hdlclib.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_hdlc_interface.f90
$(OBJDIR)/dlf_linalg.o: $(OBJDIR)/dlfhdlc_matrixlib.mod $(OBJDIR)/dlf_parameter_module.mod dlf_linalg.f90
$(OBJDIR)/dlf_parallel_opt.o: $(OBJDIR)/dlf_sort_module.mod $(OBJDIR)/dlf_checkpoint.mod $(OBJDIR)/dlf_allocate.mod $(OBJDIR)/dlf_stat.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_parallel_opt.f90
$(OBJDIR)/dlf_sort.o $(OBJDIR)/dlf_sort_module.mod: $(OBJDIR)/dlf_parameter_module.mod dlf_sort.f90
$(OBJDIR)/dlf_serial.o: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_serial.f90
$(OBJDIR)/dlf_mpi.o: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_mpi.f90
$(OBJDIR)/dlf_mpi_module.mod: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_mpi.f90 dlf_serial.f90
$(OBJDIR)/main.o $(OBJDIR)/driver_module.mod: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod main.f90
$(OBJDIR)/dlfind_crystal.o: gradient_memory.mod dlfind_module.mod basato_module.mod paral1_module.mod numbers.mod $(OBJDIR)/dlf_mpi_module.mod $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlfind_crystal.f90 
$(OBJDIR)/dlf_microiter.o: $(OBJDIR)/dlf_global.mod $(OBJDIR)/dlf_parameter_module.mod dlf_microiter.f90



# They might look like:
#dlf_linalg.o: dlfhdlc_matrixlib.mod dlf_parameter_module.mod dlf_linalg.f90
#main.o driver_module.mod: dlf_parameter_module.mod main.f90
#$(OBJDIR)/main.o $(OBJDIR)/driver_module.mod: $(OBJDIR)/dlf_parameter_module.mod main.f90
