#---------------------------------------------------------------------------
# pmlib makefile
#   version: 2D single-core
#---------------------------------------------------------------------------
# <<HEADER>>
#---------------------------------------------------------------------------
TARGET = libpmlib.a

default: $(TARGET)

SRC_DIR = ./sources
OBJ_DIR = ./objects
INC_DIR = ./include

#---------------------------------------------------------------------------
# Path to libraries
#---------------------------------------------------------------------------
MKL_DIR = /home/mek/mmhej/libs/intel-mkl-2013.1.117

#---------------------------------------------------------------------------
# Flags and libraries for compiling
#---------------------------------------------------------------------------
# Fortran compiler
FC      = ifort
# Fortran compiler flags
FFLAGS  = -O5 -free
# library flags
LDFLAGS = -L$(MKL_DIR)/lib -lmkl_intel_lp64 -lmkl_sequential -lmkl_core
# include paths
INCL    = -I$(INC_DIR) -I$(MKL_DIR)/include

# Preprocessor compiler
CPP      = cpp
# Preprocessor compiler flags
# Mandatory flags:
# -D__single or -D__double : specifies single or double precision
# Optional flags: 
# -D__mkl                  : use the intel mkl library for fft's
# -D__fftw                 : use the fftw library for fft's
CPPFLAGS = -D__double -D__mkl

#---------------------------------------------------------------------------
# write scripts
#---------------------------------------------------------------------------
SHELL := /bin/sh
LOG   := compile.log
RUN   := $(SHELL) ./make_output.sh

#---------------------------------------------------------------------------
# Setup build directories
#---------------------------------------------------------------------------
NAMES   := $(notdir $(wildcard $(SRC_DIR)/*.f))
SOURCES := $(NAMES:%.f=$(SRC_DIR)/%.f)
OBJECTS := $(NAMES:%.f=$(OBJ_DIR)/%.o)

$(warning Setup directories...)
$(shell test -d $(OBJ_DIR) || mkdir $(OBJ_DIR))
$(shell test -d $(INC_DIR) || mkdir $(INC_DIR))
$(shell test -e $(LOG) && rm $(LOG))

# Dont delete the given intermediate files
.SECONDARY:

#---------------------------------------------------------------------------
# Preproces
#---------------------------------------------------------------------------
CPCMD = $(CPP) $(CPPFLAGS) $< $@
$(OBJ_DIR)/%.f : $(SRC_DIR)/%.f
	@printf "  CPP  %-42s" $<; \
	$(RUN) "$(CPCMD)" $(LOG) "Preprocessing Error"

#---------------------------------------------------------------------------
# Compile
#---------------------------------------------------------------------------
COMPILECMD = $(FC) $(FFLAGS) $(LDFLAGS) $(INCL) -c -o $@ $<
$(OBJ_DIR)/%.o : $(OBJ_DIR)/%.f
	@printf "  FC   %-42s" $<; \
	$(RUN) "$(COMPILECMD)" $(LOG) "Compile Error"

#---------------------------------------------------------------------------
# Build library
#---------------------------------------------------------------------------
ARCMD = ar crus $@ $(OBJECTS)

$(TARGET): $(OBJECTS)
	@printf "  AR   %-42s" "Creating library archive"; \
	$(RUN) "$(ARCMD)" $(LOG) "Error Creating Archive"; \
	$(shell mv *.mod $(INC_DIR) 2> $(LOG))

#---------------------------------------------------------------------------
# Explicit dependencies
#---------------------------------------------------------------------------
#A
#B
#C
$(OBJ_DIR)/pmlib_communication.f:\
  ./sources/communication/*.f
$(OBJ_DIR)/pmlib_communication.o:\
  $(OBJ_DIR)/pmlib_topology.o\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_write.o
#D
#E
#F
$(OBJ_DIR)/pmlib_finalise.o:\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_write.o\
  $(OBJ_DIR)/pmlib_particles.o\
  $(OBJ_DIR)/pmlib_mesh.o\
  $(OBJ_DIR)/pmlib_topology.o\
  $(OBJ_DIR)/pmlib_poisson.o
$(OBJ_DIR)/pmlib_fourier.f:\
  ./sources/fourier/*.f
$(OBJ_DIR)/pmlib_fourier.o:\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_write.o\
  $(OBJ_DIR)/pmlib_mesh.o\
  $(OBJ_DIR)/pmlib_topology.o\
  $(OBJ_DIR)/pmlib_communication.o
#G
#H
#I
$(OBJ_DIR)/pmlib_interpolation.f:\
  ./sources/interpolation/*.f
$(OBJ_DIR)/pmlib_interpolation.o:\
  $(OBJ_DIR)/pmlib_particles.o\
  $(OBJ_DIR)/pmlib_mesh.o\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_communication.o\
  $(OBJ_DIR)/pmlib_topology.o
#J
#K
#L
#M
$(OBJ_DIR)/pmlib_mesh.f:\
  ./sources/mesh/*.f
$(OBJ_DIR)/pmlib_mesh.o:\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_communication.o\
  $(OBJ_DIR)/pmlib_topology.o
#N
#O
#P
$(OBJ_DIR)/pmlib_parameters.f:\
  ./sources/parameters/*.f
$(OBJ_DIR)/pmlib_parameters.o:\
  $(OBJ_DIR)/pmlib_write.o
$(OBJ_DIR)/pmlib_particles.f:\
  ./sources/particles/*.f
$(OBJ_DIR)/pmlib_particles.o:\
  $(OBJ_DIR)/pmlib_topology.o\
  $(OBJ_DIR)/pmlib_patch.o\
  $(OBJ_DIR)/pmlib_communication.o\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_write.o
$(OBJ_DIR)/pmlib_patch.f:\
  ./sources/patch/*.f
$(OBJ_DIR)/pmlib_patch.o:\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_write.o
$(OBJ_DIR)/pmlib_poisson.f:\
  ./sources/poisson/*.f
$(OBJ_DIR)/pmlib_poisson.o:\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_mesh.o\
  $(OBJ_DIR)/pmlib_topology.o\
  $(OBJ_DIR)/pmlib_patch.o\
  $(OBJ_DIR)/pmlib_communication.o\
  $(OBJ_DIR)/pmlib_fourier.o\
  $(OBJ_DIR)/pmlib_write.o
#Q
#R
$(OBJ_DIR)/pmlib_remesh.f:\
  ./sources/remesh/*.f
$(OBJ_DIR)/pmlib_remesh.o:\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_mesh.o\
  $(OBJ_DIR)/pmlib_particles.o\
  $(OBJ_DIR)/pmlib_patch.o\
  $(OBJ_DIR)/pmlib_topology.o\
  $(OBJ_DIR)/pmlib_write.o
#S
#T
$(OBJ_DIR)/pmlib_topology.f:\
  ./sources/topology/*.f
$(OBJ_DIR)/pmlib_topology.o:\
  $(OBJ_DIR)/pmlib_parameters.o\
  $(OBJ_DIR)/pmlib_patch.o\
  $(OBJ_DIR)/pmlib_write.o
#U
#V
#W
$(OBJ_DIR)/pmlib_write.o:
#X
#Y
#Z

#---------------------------------------------------------------------------
# Clean
#---------------------------------------------------------------------------
clean:
	rm -fr $(OBJ_DIR)
	rm -fr $(INC_DIR)
	rm -f  *.mod 2> $(LOG)
	rm -f  $(TARGET) 
	rm -f  $(LOG)


