# Makefile-name: Makefile.app
#############################################################################
#                                                                           #
# (c) Copyright 2003                                                        #
#     inuTech GmbH, Nuremberg, Germany.                                     #
#     All rights reserved.                                                  #
#                                                                           #
#     See http://www.diffpack.com/ for further details.                     #
#                                                                           #
#############################################################################

#
# authors: Hans Petter Langtangen and Trond Vidar Stensby, SINTEF/UiO
#

# This Makefile is intended for application programs using libraries.
# There can only be one main program in each directory since this Makefile
# compiles and links all C++, C, and Fortran files in the current directory.

# **** You will seldom have to modify this file ****

# All variables in this Makefile have default values that are set to
# appropriate values. You should not edit Makefile, but instead
# alter the values of make variables in the files .cmake1 and .cmake2.
# All application directories have these two files, which are
# included in this Makefile. When new versions of the current
# Makefile are issued, these can be recursively copied into the 
# application directories by the CpnewMakefiles command.
# User customizations in .cmake1 and .cmake2 are then still available,
# together with e.g. new functionality in the make system.
#
# A safe way of using Makefile is to always let the script Mkdir
# copy a Makefile and then automatically set up appropriate 
# .cmake1, and .cmake2 files for the current directory.
#
# The items to be modified are usually the variables 
# LIBS, INCLUDEDIRS, SRCDIR, APPL, PACKAGES and PROJECTROOT. 
# LIBS contains the libraries with which the application is to be linked.
# INCLUDEDIRS contains the directories that will be searched for
# include files.
# SRCDIR contains the path to the directory $(PROJECTROOT)/src. 
# PACKAGES contains all packages, in addition to the package under
# PROJECTROOT, that are to be linked with the current application.
# By default, INCLUDEDIRS contains all the include directories in
# all packages.
# APPL is the name of the executable file after compiling and linking.
# (The executable file is called app, by default.  You may prescribe
# app with another name by assigning the value APPL in .cmake1.)


# How should you read this Makefile in order to try to understand 
# what is going on?
# Simply start from the top and read all files that are included
# (.cmake1 for local definition of PROJECTROOT and PACKAGES,
# $(PROJECTROOT)/src/MakeFlags for definition of package-dependent
# compilation and linking flags,
# $(PROJECTROOT)/src/MakeHeader for definition of platform-dependent
# and compiler-dependent variables, 
# $(PROJECTROOT)/src/MakeRules for definition of compilation rules, 
# .cmake2 for user's customization of make variables after default 
# variables are set in MakeHeader, MakeFlags, and MakeRules).
#
# A common problem is to add special system libraries or paths to
# the compilation commands. Such information are set in MakeHeader
# according to the machine and compiler type. The best approach is
# to edit $NOR/etc/Makefiles/MakeHeader (find the appropriate value
# of LIBTYPE, reflecting hardware/compiler, and edit). Then copy
# this MakeHeader file out to all packages by the command CopyMakeHeader.
#
# -----------------------------------------------------------------------

# default root of present project (will normally be overridden in .cmake1):
PROJECTROOT := ../../..

# default is no PACKAGES
PACKAGES := 

# .cmake1 allows us to customize this Makefile

ifeq "$(wildcard .cmake1)" ".cmake1"
   include $(wildcard .cmake1)
else
#  for backward compatibility only (.cmake1 had the name .pdmkroot):
   ifeq "$(wildcard .pdmkroot)" ".pdmkroot"
      include .pdmkroot
   endif
endif


# do we redefine PROJECTROOT and PACKAGES in .cmake1?

# if PROJECTROOT is "." it means that there is no root (i.e. no use of
# other packages - convenient for stand-alone applications) and that
# the files MakeHeader and MakeRules are local; otherwise we
# shall include $(PROJECTROOT)/src/MakeHeader and
# $(PROJECTROOT)/src/MakeRules:

ifneq "$(PROJECTROOT)" "."

#   Check if PROJECTROOT is well defined. Otherwise try ALTROOT

  ifneq "$(wildcard $(PROJECTROOT)/src/MakeHeader)" "$(PROJECTROOT)/src/MakeHeader"
    PROJECTROOT := $(ALTROOT)
  endif

  include $(wildcard $(PROJECTROOT)/src/MakeHeader)
else
# no root, local MakeHeader:
  include $(wildcard MakeHeader)
endif

# Get definition of compiler flags from all packages.
# The MakeFlags files from the different packages should be included
# in the opposite order than listed in the variable $(PACKAGES)

ifneq "$(PACKAGES)" ""
   REVERSE := $(shell $(NOR)/bin/etc/reverse_args $(PACKAGES) )
   include $(foreach dir,$(REVERSE),$(wildcard $(dir)/src/MakeFlags))
endif

# now MakeFlags from each package is included, also include the
# MakeFlags file for the top package (the one under PROJECTROOT):

ifneq "$(PROJECTROOT)" "."
  include $(wildcard $(PROJECTROOT)/src/MakeFlags)
# else: no root implies no local MakeFlags
endif

# now set APPL, SRCS etc. and DIRS to appropriate default values
# before these variables can be modified by the user in the .cmake2 file:
# (see below for explanation of these variables)
DIRS :=
APPL := app
SRCS := $(wildcard ./*.[Ccf]) $(wildcard ./*.cpp) $(wildcard ./*.cxx) $(wildcard ./*.f90)
ALLSRCS := $(SRCS)
TILD := $(wildcard ./*~)

# more customization of this Makefile takes place in .cmake2:

ifeq "$(wildcard .cmake2)" ".cmake2"
   include $(wildcard .cmake2)
else
#  for backward compatibility only (.cmake2 had the name .pdmkvars):
   ifeq "$(wildcard .pdmkvars)" ".pdmkvars"
      include $(wildcard .pdmkvars)
   endif
endif

#------------ the below statements should not be modified ----------------

# the source files are all the .C, .cpp, .cxx, .c, .f and .f90 files in 
# all directories listed under DIRS (often empty) plus
# the value of the SRCS variable as set by the user in .cmake2
# (if SRCS is not touched in .cmake2, it has the default value of all
# .C, .cpp, .cxx, .c, .f and .f90 files in the current dir., see above):
SRCS := $(SRCS) $(foreach dir,$(DIRS),$(wildcard $(dir)/*.[Ccf]) $(wildcard $(dir)/*.cpp) $(wildcard $(dir)/*.cxx) $(wildcard $(dir)/*.f90))

# sometimes the user overrides the SRCS variable - e.g. for compiling
# a single file - and then ALLSRCS indicates all the source files that
# should enter the application (or library):

ALLSRCS := $(ALLSRCS) $(foreach dir,$(DIRS),$(wildcard $(dir)/*.[Ccf]) $(wildcard $(dir)/*.cpp) $(wildcard $(dir)/*.cxx) $(wildcard $(dir)/*.f90))

# the tilde files (to be removed by clean):
TILD := $(TILD) $(foreach dir,$(DIRS),$(wildcard $(dir)/*~))

# remove multiple entries:

SRCS    := $(sort $(SRCS))
ALLSRCS := $(sort $(ALLSRCS))
TILD    := $(sort $(TILD))

INCLUDEDIRS := $(foreach dir,$(DIRS),-I$(dir)) \
               $(INCLUDEDIRS) -I$(PROJECTROOT)/include \
               $(foreach pack,$(PACKAGES),-I$(pack)/include) \
               -I$(DPEXTSOFT)/$(MACHINE_TYPE)/include

# file for results from verification procedures (test problems):
VERIFYLOG := $(PWD)/verify.log

# update SYSLIBS - now USE_X and USE_MOTIF should be properly set
# in the included MakeFlags files (these variables indicate whether 
# we should use X and Motif).
# Notice that if USE_MOTIF is set to true, so is USE_X.
ifeq ($(USE_MOTIF),yes)
  SYSLIBS += $(XMOTIFLIBS)
endif
ifeq ($(USE_X),yes)
  SYSLIBS += $(XLIBS)
endif
# note that USE_MOTIF and USE_X are not intended to be set by the user - the 
# user should set variables like GUIMENU or VTK_GRAPHICS that govern the 
# coupling to libraries *using* X.


#-----------------------------------------------------------------------
# the application is dependent on libraries in the following directories:
#-----------------------------------------------------------------------

# LDPATH contains the directories where ld search for libraries

LDPATH  :=  $(LDPATH) -L$(PROJECTROOT)/lib/$(MACHINE_TYPE)/$(EXT)\
$(foreach pack,$(PACKAGES),-L$(pack)/lib/$(MACHINE_TYPE)/$(EXT)) \
-L$(DPEXTSOFT)/$(MACHINE_TYPE)/lib

SHARED_LDPATH :=  $(SHARED_LDPATH) \
$(SHARED_PATH_OPT)$(PROJECTROOT)/lib/$(MACHINE_TYPE)/$(EXT) \
$(foreach pack,$(PACKAGES), $(SHARED_PATH_OPT)$(pack)/$(MACHINE_TYPE)/$(EXT)) \
$(SHARED_PATH_OPT)$(DPEXTSOFT)/$(MACHINE_TYPE)/lib

# VPATH should contain the same directories as LDPATH
VPATH := $(patsubst -L%,:%,$(LDPATH))
VPATH := $(patsubst -I%,:%,$(VPATH))
VPATH := $(subst $(empty) :,:,$(strip $(VPATH)))

# Only normal (*.a) libraries kan be a part of the dependencies
DEPLIBS :=

# object files:

OBJS := $(subst .C,.o,$(SRCS))
OBJS := $(subst .cpp,.o,$(OBJS))
OBJS := $(subst .cxx,.o,$(OBJS))
OBJS := $(subst .c,.o,$(OBJS))
OBJS := $(subst .f90,.o,$(OBJS))
OBJS := $(subst .f,.o,$(OBJS))

OBJS := $(foreach obj,$(OBJS),$(PREFIX)$(obj))

# ALLOBJS is used when linking, ALLSRCS is used to make ALLOBJS
ALLOBJS := $(subst .C,.o,$(ALLSRCS)) 
ALLOBJS := $(subst .cpp,.o,$(ALLOBJS)) 
ALLOBJS := $(subst .cxx,.o,$(ALLOBJS)) 
ALLOBJS := $(subst .c,.o,$(ALLOBJS))
ALLOBJS := $(subst .f90,.o,$(ALLOBJS))
ALLOBJS := $(subst .f,.o,$(ALLOBJS))

# the PREFIX variable enables output of object files in other
# directories (e.g. /tmp); to use this option, set OUTDIR
# on the command line, e.g.
# make OUTPUT=visible OUTDIR=/tmp MODE=opt

ALLOBJS := $(foreach obj,$(ALLOBJS),$(PREFIX)$(obj))

# dependencies for make depend should be equal to all object files, but
# with .o suffix replaced with .d

DEPFILES    := $(OBJS:.o=.d)

# Make dependencies invisible

ifeq ("$(OUTPUT)","INVISIBLE")
   DEPFILES := $(foreach file,$(DEPFILES),$(dir $(file)).$(notdir $(file)))
endif

# preprocessor files should be equal to all object files, but
# with .o suffix replaced with .E

PREPROFILES := $(OBJS:.o=.E)

# include MakeRules, with make rules for transforming e.g. .cpp to .o:
ifneq "$(PROJECTROOT)" "."
  include $(wildcard $(PROJECTROOT)/src/MakeRules)
else
# no root, local MakeRules:
  include $(wildcard MakeRules)
endif

# in case of link2dp target, DPDIR is the path to the Diffpack files
# (current working directory is default):
ifeq ($(DPDIR),)
  DPDIR := "."
endif
# ALLOBJS_nomain is ALLOBJS without main.o (used in link2dp target):
ALLOBJS_nomain := $(filter-out main.o, $(ALLOBJS))

# Rules for making the application, and rules for clean. depend, ...
# 
#-----------------------------------------------------------------------------

all:	comptype $(APPL)
	@echo
	@echo "---------- application \"$(APPL)\" done ----------"


comptype:
        ifeq ($(CHECK_COMPTYPE),yes)
	@$(NOR)/bin/etc/newcomptype "$(PREFIX)" "$(MACHINE_TYPE)" "$(CXXFLAGS) $(CCFLAGS) \
			$(FFLAGS) $(LDFLAGS)" "$(OBJS)"
        endif

#$(APPL): $(OBJS)
$(APPL): $(OBJS) $(DEPLIBS)
	@echo
	@echo
	@echo "---------- linking $(OBJS) ----------"
	@echo
	@echo
	$(LD) $(LDFLAGS) -o $@ $(ALLOBJS) $(LIBS) $(SYSLIBS)
        ifeq ("$(INSTALL_EXE)","yes")
		@mkdirhier $(PROJECTROOT)/bin/$(MACHINE_TYPE)/$(EXT)
		@mv $@ tmp
		@mv tmp $(PROJECTROOT)/bin/$(MACHINE_TYPE)/$(EXT)/$@
		@echo
		@echo
		@echo "`ls -l $(PROJECTROOT)/bin/$(MACHINE_TYPE)/$(EXT)/$@ | \
		awk '{print $$5, $$6, $$7, $$8, $$9}'`" ;
        endif

# allows a kind of Makefile debugging, write e.g. make debout all
# to first get this list of make variables and compile everything:

vars:
	@echo "Values of important Makefile variables:"
	@echo
	@echo "PROJECTROOT=$(PROJECTROOT)"
	@echo
	@echo "PACKAGES="
	@for i in $(PACKAGES); do echo $$i; done
	@echo
	@echo "source code files: "
	@for i in $(ALLSRCS); do echo $$i; done
	@echo 
	@echo "include directories: "
	@for i in $(INCLUDEDIRS); do echo $$i; done
	@echo 
	@echo "Application libraries to link with: LIBS=$(LIBS)"
	@echo "System libraries to link with: SYSLIBS=$(SYSLIBS)"
	@echo "Search dirs for libraries: LDPATH=$(LDPATH)"
	@echo "Compilation mode: MODE=$(MODE)"
	@echo "C++ compiler: CXX=$(CXX)"
	@echo "Numerical type (real/Complex): NUMT=$(NUMT)"
	@echo "Parallel version of Diffpack: PARALLEL_CODE=$(PARALLEL_CODE)"
	@echo "Menu system GUI: GUIMENU=$(GUIMENU)"
	@echo "Vtk linked to Diffpack: VTK_GRAPHICS=$(VTK_GRAPHICS)"

clean:
	@echo removing `ls -s $(OBJS) $(TILD) $(APPL) $(PREPROFILES) core *.bak SIMULATION.* .SIMULATION* 2> /dev/null`
	@rm -f $(OBJS) $(TILD) $(APPL) $(PREPROFILES) core *.bak SIMULATION.* .SIMULATION*

cleanex:
	@echo removing `ls -s $(PROJECTROOT)/bin/$(MACHINE_TYPE)/$(EXT)/$(APPL) $(TILD) $(APPL) core *.bak 2> /dev/null`
	@rm -f $(TILD) $(APPL) core *.bak
	@rm -f $(PROJECTROOT)/bin/$(MACHINE_TYPE)/$(EXT)/$(APPL)

clobber:
	@echo removing `ls -s $(ALLOBJS) $(DEPFILES) $(TILD) $(APPL) core *.bak SIMULATION.* .SIMULATION* .comptype 2> /dev/null`
	@rm -f $(ALLOBJS) $(DEPFILES) $(TILD) $(APPL) core *.bak SIMULATION.* .SIMULATION* .comptype

depend: $(DEPFILES)
	@echo
	@echo "---------- Dependencies done ----------"

headercp:
	@echo
	@echo "---------- No headercp in application dir ----------"


# Write typical parts of a makefile where Diffpack's include and
# library directories, C++ options etc. are defined:

link2dp:
	@echo "# DP_DIR          : where the Diffpack application is located"
	@echo "#                   (the application can be empty, just using libs)"
	@echo "DP_DIR            := $(DPDIR)"
	@echo
	@echo "# DP_INCLUDEDIRS  : where the Diffpack include files are"
	@echo "DP_INCLUDEDIRS    := $(INCLUDEDIRS)"
	@echo
	@echo "# DP_OBJS         : where the Diffpack object files to be linked"
	@echo "#                   with this application are"
	@echo "DP_OBJS           := $(foreach obj,$(ALLOBJS_nomain),$(DPDIR)/$(obj))"
	@echo
	@echo "# DP_CXXFLAGS     : C++ compiler flags for Diffpack compilation"
	@echo "DP_CXXFLAGS       := $(CXXFLAGS)"
	@echo
	@echo "# DP_LIBS         : Diffpack libraries to link with"
	@echo "DP_LIBS           := $(LIBS)"
	@echo
	@echo "# DP_SYSLIBS      : system libraries needed by Diffpack"
	@echo "DP_SYSLIBS        := $(SYSLIBS)"
	@echo
	@echo "# DP_LDFLAGS      : flags for linking, including -L paths"
	@echo "DP_LDFLAGS        := $(LDFLAGS)"
	@echo
	@echo "# DP_CXX          : C++ compiler for Diffpack"
	@echo "DP_CXX            := $(CXX)"
	@echo
	@echo "# DP_LD           : program for linking Diffpack applications"
	@echo "DP_LD             := $(LD)"
	@echo
	@echo "# In a typical makefile which is supposed to link another"
	@echo "# application to this Diffpack application, you write"
	@echo ""
	@echo "#include DpMakefile.defs"
	@echo ""
	@echo "# The DpMakefile.defs file is made by running"
	@echo "#   Make link2dp MODE=opt DPDIR=../../dpapp > /some/path/DpMakefile.defs"
	@echo "# where DPDIR specifies the directory where the Diffpack"
	@echo "# application is located as seen from /some/path where"
	@echo "# you have the other (non-Diffpack) application."
	@echo
	@echo "# How to compile the Diffpack files and link with them (remove backslashes):"
	@echo
	@echo  "#%.o: %.cpp"
	@echo  '#	$$\(DP_CXX) $$\(DP_CXXFLAGS) -c $$\< '
	@echo
	@echo  "#dpcomp: $$\(DP_OBJS) "
	@echo
	@echo  "#link:"
	@echo  "#	$$\(DP_LD) $$\(DP_LDFLAGS) -o app $$\(DP_OBJS) file1.o file2.o  $$\(DP_LIBS) $$\(DP_SYSLIBS) -lmyspecial_lib "
	@echo

newverify:
	@echo
	@echo "In directory `pwd`"
	@echo Results from last verification registered as reference.
	@$(NOR)/bin/etc/NewVerify

prepro: $(PREPROFILES)
	@echo
	@echo "---------- Preprocessing done ----------"

removelib:
	@echo
	@echo "---------- No removelib in application dir ----------"

verifyall: all verify clean

verify:
	@echo
	@echo "Using input in `pwd`"
	@echo "(Results in $(VERIFYLOG))"
        ifeq ($(MAKELEVEL),0)
	@rm -f verify.log ; touch verify.log
        endif
	@Verify $(VERIFYLOG)

# Include dependencies.

ifneq "$(foreach file,$(DEPFILES),$(wildcard $(file)))" ""
   include $(foreach file,$(DEPFILES),$(wildcard $(file)))
endif

