#---------------------------------------------------------------------------
# pmlib makefile
#   version: 2D single-core
#---------------------------------------------------------------------------
#                  __    __
#    ___  _ _     / /__ / /
#   | _ \/ ` \ _ / // // _ \
#   | ,_/_,_,_\  \_/\_/\___/
#   |_|                      Mads M. Hejlesen* and Jens H. Walther*^
#                            * Technical University of Denmark
#                            ^ ETH-Zurich
#
#---------------------------------------------------------------------------
# Copyright (c) 2014 Technical University of Denmark, 
#                    Department of Mechanical Engineering
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>
#
# Contact: mmhej@mek.dtu.dk or jhwa@mek.dtu.dk
#---------------------------------------------------------------------------

TARGET = libpmlib.a

default: $(TARGET)

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

#---------------------------------------------------------------------------
# Flags and libraries for compiling
#---------------------------------------------------------------------------
FC      = gfortran
FFLAGS  = -O5 -ffree-form -ffree-line-length-none
LDFLAGS = 
INCL    = -I$(INC_DIR) 

CPP      = cpp
#CPPFLAGS = -D__single
CPPFLAGS = -D__double

#---------------------------------------------------------------------------
# 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)

