# Makefile for GNU-make
# Fortran: GNU gfortran 4.9 to 13
#
# new organisation: each *.o depends now only on *.mod files
#                   use of recursive-make
#
# É. Canot -- CNRS -- 20 Nov 2024
#
# make help
#
#  'MODE=silent'  [default]: rules & compiler output are not displayed
#  'MODE=verbose'          : rules & compiler output are displayed
#
#  'CFG=optim'    [default]: optimization + public/private var.
#                            libs: static + shared
#  'CFG=debug'             : debug + profiling + check + traceback +
#                            all var. are public + static libs only
#
#  'MEMTR=no'     [default]: no memory debug
#  'MEMTR=yes'             : keep trace of alloc/dealloc
#
#  'PTRTR=no'     [default]: no pointer debug
#  'PTRTR=yes'             : keep trace of pointing '→'
#
#  'TCOV=no'      [default]: no test coverage
#  'TCOV=yes'              : prepare compilation for test coverage
#
#  'PROF=no'      [default]: profiling not activated
#  'PROF=yes'              : enable profiling of the code
#
#  'FGL=yes'      [default]: compile the graphic part
#  'FGL=no'                : don't compile the graphic part
#
#-----------------------------------------------------------------------
# (these options must be located after the 'make' command)
#

include Makefile.config

# configurable options (architecture dependent)

# for optimization (both for gcc, g++ and gfortran)
OPT_FLAGS = -O3 -funroll-loops
export OPT_FLAGS

# path to shared libraries of GNU compilers
#F90_LIB_DIR = $(GCC_LIB)

export F90_LIB_DIR

ifeq '$(DARWIN)' '"yes"'
  SHARED_EXT=dylib
else
  SHARED_EXT=so
endif

#=======================================================================
# (see at the end for a list of exported variables)

F90CACHE = "no"

# special tag : vendor / f90 abbrev
F90C_TAG = GNU_GFC
export F90C_TAG

INSTALL_DIR := $(INSTALL_DIR)/muesli

DOCS_INSTALL_DIR := $(DOCS_INSTALL_DIR)/muesli

export CFG
export X86_64

# memorize MAKE local options
ifeq '$(CFG)' 'debug'
  MAKE_CFG=CFG=debug
else # 'optim'
  MAKE_CFG=CFG=optim
endif
ifeq '$(MEMTR)' 'yes'
  MAKE_MEMTR=MEMTR=yes
else # 'no'
  MAKE_MEMTR=MEMTR=no
endif
ifeq '$(PTRTR)' 'yes'
  MAKE_PTRTR=PTRTR=yes
else # 'no'
  MAKE_PTRTR=PTRTR=no
endif
ifeq '$(TCOV)' 'yes'
  MAKE_TCOV=TCOV=yes
else # 'no'
  MAKE_TCOV=TCOV=no
endif
ifeq '$(PROF)' 'yes'
  MAKE_PROF=PROF=yes
else # 'no'
  MAKE_PROF=PROF=no
endif
ifeq '$(FGL)' 'no'
  MAKE_FGL=FGL=no
else # 'no'
  MAKE_FGL=FGL=yes
endif

# compilers ------------------------------------------------------------

F90C = $(F90_COMP)
export F90C

FC = $(F90C)
export FC

FPP = $(F90C) -E # a bug of many releases (from 4.5) creates some empty *.s files
                 # (cf. the clean at the end)
FPP_OUT = >

MODULE_ONLY = -fsyntax-only

MOD_TO = -J# no blank after
# MOD_TO: must be used with caution... it adds the specified path to the set of
# pathes for USE... and some confusion may arise...
# moreover, it cannot be used for parallel make ('make -j N')
#
# while a blank after the '-J' option should be possible, the official
# documentation asks to use '-Jdir' (without a blank as separator). Moreover,
# for the f90cache tool, a blank character is not possible after '-J'.

# exported for [FGL]mfplot Makefile
export MOD_TO

# OpenMP flag (specific for each compiler)
OMP_FLAG =# -fopenmp

CC = $(C_COMP)
export CC

CPLUSPLUS = $(CXX_COMP)
export CPLUSPLUS

ifeq '$(MODE)' 'verbose'

  export VERB =
  export MAKE = make

else # 'silent'

  export VERB =@
  export MAKE = make -s

endif

WRAPPER_FLAGS = -DUNDERSCORE
ifeq '$(X86_64)' '"yes"'
  WRAPPER_FLAGS += -D_64_BITS
endif
export WRAPPER_FLAGS

ifeq '$(CFG)' 'debug'

  CC_FLAGS = -g
  CPP_FLAGS =

  FPP_FLAGS = -D_$(F90C_TAG)

  FPP_DEBUG_FLAGS =

  CFG_FLAGS = -fno-range-check \
              -g -fbounds-check -fbacktrace

  ifeq '$(PROF)' 'yes'
    CC_FLAGS += -pg
    CFG_FLAGS += -pg
  endif

#  CFG_FLAGS += -Warray-temporaries -fcheck-array-temporaries # 4.? only

  ifeq '$(TCOV)' 'yes'

    CFG_FLAGS += -fprofile-arcs -ftest-coverage # for test coverage (gcov)

  endif

  FML_LIB = lib/libfml.a
  FGL_LIB = lib/libfgl.a

  ifeq '$(VERB)' '@'

    CFG_FLAGS += -w
    CC_FLAGS += -w

  else # 'verbose'

    CFG_FLAGS += -Wall
    CC_FLAGS += -Wall

  endif

  # static-libgfortran is required to use my show_backtrace
  ifeq '$(STATIC_LIBGFORTRAN)' '"yes"'
    LD_FLAGS = -static-libgfortran
  endif

else # 'optim'

  CC_FLAGS = -w $(OPT_FLAGS)
  CPP_FLAGS = -D_OPTIM

  FPP_FLAGS = -D_$(F90C_TAG) -D_OPTIM
  FPP_DEBUG_FLAGS =

  CFG_FLAGS = -fno-range-check -w $(OPT_FLAGS)
  FML_LIB = lib/libfml.$(SHARED_EXT)
  FGL_LIB = lib/libfgl.$(SHARED_EXT)

  LD_FLAGS =

endif

CFG_FLAGS += -ffree-line-length-none

ifeq '$(STATIC_LIBGFORTRAN)' '"yes"'
  FPP_FLAGS += -D_SHOW_BACKTRACE
else
  ifeq '$(GFORTRAN_HAS_BACKTRACE)' '"yes"'
    FPP_FLAGS += -D_STD_BACKTRACE
  endif
endif

export FPP_FLAGS

PIC_FLAGS =
ifeq '$(X86_64)' '"yes"'
  PIC_FLAGS = -fPIC
  CC_FLAGS += $(PIC_FLAGS) -D_64_BITS
  FPP_FLAGS += -D_64_BITS
  CFG_FLAGS += $(PIC_FLAGS)
endif

# The loc() intrinsic function of this compiler may take address of
# sequenced derived types:
FPP_FLAGS += -D_HAS_LOC

ifeq '$(MEMTR)' 'yes'

  FPP_FLAGS += -D_TRACE_MEM_ALLOC

endif

ifeq '$(NO_X11)' '"yes"'

  FPP_FLAGS += -D_NO_X11
  CC_FLAGS += -D_NO_X11

endif

ifeq '$(IM_CONVERT)' '"yes"'

  FPP_FLAGS += -D_HAS_IM_CONVERT

endif

ifeq '$(DARWIN)' '"yes"'

  FPP_FLAGS += -D_DARWIN
  CC_FLAGS += -D_DARWIN

endif

ifeq '$(READLINE)' '"yes"'

  FPP_FLAGS += -D_READLINE

endif

INCLUDES = -I./inc_dev

ifeq '$(HDF5)' '"yes"'

  FPP_FLAGS += -D_HDF5

  INCLUDES += -I$(HDF5_F90_DIR)

endif

# [option added on 2011-06-30, in order to check the validity
#  of numerical results among all the compilers used]
F90_FLAGS += -fno-sign-zero

F90_FLAGS = $(CFG_FLAGS) $(OMP_FLAG)

LD_FLAGS += $(OMP_FLAG)

export PIC_FLAGS
export CC_FLAGS
export CPP_FLAGS
export F90_FLAGS

# shell tools ----------------------------------------------------------

CHECK_OPTS = sh_tools/check_opts 5

CHECK_VER = sh_tools/check_ver

#=======================================================================

ifeq '$(FGL)' 'no'
all:: check_ver check_opts compat_opts tools fml_core/parameters.inc \
      suitesparse arpack-2 minpack-2 ConvexHull GFT-2 ACM-2 dummy_papi \
      FML_part $(FML_LIB) dist_fml meditor
else
all: check_ver check_opts compat_opts tools fml_core/parameters.inc \
      suitesparse arpack-2 minpack-2 ConvexHull GFT-2 ACM-2 dummy_papi \
      FML_part $(FML_LIB) dist_fml meditor \
      mfplot FGL_part $(FGL_LIB) dist_fgl
endif

compat_opts:
ifeq '$(MAKE_FGL)' 'FGL=yes'
  ifeq '$(MAKE_MEMTR)' 'MEMTR=yes'
    ifeq '$(MAKE_CFG)' 'CFG=optim'
	@echo $(ECHO_OPT) "\n   'CFG=optim', 'FGL=yes' and 'MEMTR=yes' are not compatible!\n"
	exit 1
    endif
  endif
endif
ifeq '$(MAKE_CFG)' 'CFG=optim'
  ifeq '$(PROF)' 'yes'
	@echo $(ECHO_OPT) "\n   'PROF=yes'  can be activated only in debug mode!\n"
	exit 1
  endif
  ifeq '$(MAKE_TCOV)' 'TCOV=yes'
	@echo $(ECHO_OPT) "\n   'CFG=optim' and 'TCOV=yes' are not compatible!\n"
	exit 1
  endif
endif
	@rm -f make_options make_opt.inc
	@echo "make $(MAKE_CFG) $(MAKE_MEMTR) $(MAKE_TCOV) $(MAKE_PTRTR) $(MAKE_PROF)" > make_options
	@echo $(ECHO_OPT) "$(MAKE_CFG)\n$(MAKE_MEMTR)\n$(MAKE_TCOV)\n$(MAKE_PTRTR)\n$(MAKE_PROF)\nGCC_FAMILY_MAJOR=$(GCC_FAMILY_MAJOR)\nGCC_FAMILY_MINOR=$(GCC_FAMILY_MINOR)" > make_opt.inc

ifeq '$(MEMTR)' 'yes'
tools: bin/replace_alloc_dealloc \
       bin/mem_debug_check \
       bin/mem_debug_stats
	@echo $(ECHO_OPT) "\r                                                      \c"
else
  ifeq '$(PTRTR)' 'yes'
tools: bin/pointer_trace
	@echo $(ECHO_OPT) "\r                                                      \c"
  else
tools:
  endif
endif

check_opts:
	@$(CHECK_OPTS) make_options $(MAKE_CFG) $(MAKE_MEMTR) $(MAKE_TCOV) $(MAKE_PTRTR) $(MAKE_PROF)

check_ver:
	@$(CHECK_VER) make_opt.inc $(GCC_FAMILY_MAJOR) $(GCC_FAMILY_MINOR)

fml_core/parameters.inc: fml_core/parameters.inc.in f90_compiler_version ../VERSION
	@cat fml_core/parameters.inc.in | \
		sed -e "s+MUESLI VERSION NOT DEFINED+`cat ../VERSION | head -n 1`+" | \
		sed -e "s+COMPILER VERSION NOT DEFINED+`cat f90_compiler_version | head -n 1`+" \
		> $@

howmake:
	@echo
	$(COLOR_YELLOW)
	@echo $(ECHO_OPT) "  \c"
	@test -f make_options && cat make_options || \
     echo "don't know how make has been called !"
	$(COLOR_NORMAL)
	@echo

help:
	@echo
	$(COLOR_GRAY)
	@echo "  make [MODE=silent|verbose] [CFG=optim|debug] [MEMTR=no|yes] [PTRTR=no|yes] [PROF=no|yes] [FGL=yes|no] <target>"
	@echo "    -------------------------"
	@echo "    'MODE=silent'  [default]: rules & compiler output are not displayed"
	@echo "    'MODE=verbose'          : rules & compiler output are displayed"
	@echo
	@echo "    'CFG=optim'    [default]: optimization + public/private var."
	@echo "                              libs: static + shared"
	@echo "    'CFG=debug'             : debug + profiling + check + traceback +"
	@echo "                              all var. are public + static libs only"
	@echo
	@echo "    'MEMTR=no'     [default]: no memory debug"
	@echo "    'MEMTR=yes'             : keep trace of alloc/dealloc"
	@echo
	@echo "    'TCOV=no'      [default]: no test coverage"
	@echo "    'TCOV=yes'              : prepare compilation for test coverage"
	@echo
	@echo "    'PROF=no'      [default]: profiling not activated"
	@echo "    'PROF=yes'              : enable profiling of the code"
	@echo
	@echo "    'FGL=yes'      [default]: compile the graphic part"
	@echo "    'FGL=no'                : don't compile the graphic part"
	@echo "    -------------------------"
	@echo "    'CFG=optim', 'FGL=yes' and 'MEMTR=yes' are not compatible!"
	@echo "    'CFG=optim' and 'TCOV=yes' are not compatible!"
	$(COLOR_NORMAL)
	@echo

include Makefile.inc

ifeq '$(COLORED_TERM)' '"yes"'
  # escape sequence to active colors in the terminal
  COLOR_NORMAL =@echo $(ECHO_OPT) -n "\033[0m"
  COLOR_RED    =@echo $(ECHO_OPT) -n "\033[1;31m"
  COLOR_PURPLE =@echo $(ECHO_OPT) -n "\033[1;35m"
  COLOR_GRAY   =@echo $(ECHO_OPT) -n "\033[0;37m"
  COLOR_YELLOW =@echo $(ECHO_OPT) -n "\033[1;33m"
endif

suitesparse:
	@echo
	$(COLOR_RED)
	@echo "                      ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
	@echo "                      ┃       num. lib. subparts       ┃"
	@echo "                      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
	$(COLOR_NORMAL)
	@echo
	$(VERB)(cd misc/suitesparse && $(MAKE))

arpack-2:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making Arpack: \c"
	$(VERB)(cd misc/arpack && $(MAKE))

minpack-2:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making Minpack: \c"

ConvexHull:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making ConvexHull: \c"

GFT-2:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making GFT: \c"

ACM-2:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making ACM: \c"
	$(VERB)(cd misc/ACM && $(MAKE))
	@echo $(ECHO_OPT) "\r                                                      \c"
	$(COLOR_PURPLE)
	@echo $(ECHO_OPT) "\r  → done"
	$(COLOR_NORMAL)

mfplot: obj/mod_mfaux.o
	$(COLOR_RED)
	@echo "                      ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
	@echo "                      ┃         MFPLOT subpart         ┃"
	@echo "                      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
	$(COLOR_NORMAL)
	@echo
	@echo $(ECHO_OPT) "\r  ... making MFPLOT: \c"
	$(VERB)(cd fgl/mfplot && $(MAKE))
	@echo $(ECHO_OPT) "\r                                                      \c"
	$(COLOR_PURPLE)
	@echo $(ECHO_OPT) "\r  → done"
	$(COLOR_NORMAL)

dist_fml:
ifeq '$(TCOV)' 'yes'
	@rm -f *.gcno
endif
	@echo $(ECHO_OPT) "\r                                                      \c"
	$(COLOR_PURPLE)
	@echo $(ECHO_OPT) "\r  → done"
	$(COLOR_NORMAL)
	@echo

ifeq '$(CFG)' 'debug'
FGL_OBJS += obj/mod_fgl_mem_debug.o
endif

# debugging purpose in tests/: access to all vars.
# (cf. F90_FLAGS_DEV and test_internal.o build in tests/Makefile)
dist_fgl: inc_dev/fgl.mod
	@rm -f tmp/tmp.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	$(COLOR_PURPLE)
	@echo $(ECHO_OPT) "\r  → done"
	$(COLOR_NORMAL)
	@echo

FML_part:
	@echo
	$(COLOR_RED)
	@echo "                      ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
	@echo "                      ┃            FML part            ┃"
	@echo "                      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
	$(COLOR_NORMAL)
	@echo

ifeq '$(CFG)' 'debug'
  ifeq '$(STATIC_LIBGFORTRAN)' '"yes"'
    FML_OBJS += obj/show_backtrace.o
  endif
endif

dummy_papi: obj/dummy_papi.o

obj/dummy_papi.o: papi/dummy_papi.F90
	$(VERB)$(F90C) $(FPP_FLAGS) $(F90_FLAGS) -c $< -o $@

lib/libfml.a: $(FML_OBJS)
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)rm -f $@
	$(VERB)ar cr $@ $(FML_OBJS) misc/suitesparse/obj/*.o \
		misc/arpack/obj/*.o misc/ACM/obj/*.o obj/dummy_papi.o

LDOPT_FML_SO = -lz -lrt \
	-lreadline -lhistory \
	-Wl,-rpath,$(LAPACK_DIR) -L$(LAPACK_DIR) -llapack \
	-Wl,-rpath,$(BLAS_DIR) -L$(BLAS_DIR) -lblas

ifeq '$(F90_LIB_DIR)' ''
  LDOPT_FML_SO += -lstdc++
else
  LDOPT_FML_SO += -Wl,-rpath,$(F90_LIB_DIR) -L$(F90_LIB_DIR) -lstdc++ -lgfortran
endif

ifeq '$(DARWIN)' '"no"'
lib/libfml.$(SHARED_EXT): $(FML_OBJS)
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) -z execstack -shared -o $@ $(FML_OBJS) \
		misc/suitesparse/obj/*.o \
		misc/arpack/obj/*.o misc/ACM/obj/*.o obj/dummy_papi.o \
		$(LDOPT_FML_SO)
else
lib/libfml.$(SHARED_EXT): $(FML_OBJS)
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) -install_name "$(INSTALL_DIR)/libfml.$(SHARED_EXT)" \
		-dynamiclib -o $@ $(FML_OBJS) misc/suitesparse/obj/*.o \
		misc/arpack/obj/*.o misc/ACM/obj/*.o obj/dummy_papi.o \
		-lz -lreadline -llapack -lblas -lstdc++ -lgfortran
endif

FGL_part:
	@echo
	$(COLOR_RED)
	@echo "                      ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
	@echo "                      ┃            FGL part            ┃"
	@echo "                      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
	$(COLOR_NORMAL)
	@echo

lib/libfgl.a: $(FGL_OBJS)
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)rm -f $@
	$(VERB)ar cr $@ $^

ifeq '$(DARWIN)' '"no"'
lib/libfgl.$(SHARED_EXT): $(FGL_OBJS)
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) -z execstack -shared -o $@ $^ \
		-L./lib -lfml -lmfplot -Wl,-rpath,"\$$ORIGIN"
else
  Z_LIB= -L$(ZLIB_DIR) -lz
ifeq '$(NO_X11)' '"no"'
  X11_LIB= -L$(X11_DIR) -lX11
else
  X11_LIB=
endif
lib/libfgl.$(SHARED_EXT): $(FGL_OBJS)
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) -install_name "$(INSTALL_DIR)/libfgl.$(SHARED_EXT)" \
		-dynamiclib -o $@ $^ \
		./lib/libfml.$(SHARED_EXT) ./lib/libmfplot.$(SHARED_EXT) \
		$(Z_LIB) $(X11_LIB) -lgfortran
endif

obj/get_term_col.o: C/get_term_col.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) -c $< -o $@

obj/show_backtrace.o: show_backtrace.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(CC_FLAGS) -c $< -o $@

obj/set_rounding_mode.o: C/set_rounding_mode.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) -c $< -o $@

obj/fp_exceptions.o: C/fp_exceptions.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) -c $< -o $@

obj/mod_fgl_mem_debug.o: fgl/src/mod_fgl_mem_debug.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) -D_DEVLP $(FPP_FLAGS) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

# this module must be compiled without optimization
obj/mod_ieee.o: mod_ieee.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
ifeq '$(CFG)' 'debug'
ifeq '$(TCOV)' 'yes'
	$(VERB)$(F90C) -D_DEVLP $(FPP_FLAGS) $(INCLUDES) -g -O0 -fno-range-check -fprofile-arcs -ftest-coverage -c $< -o $@ $(MOD_TO)inc_dev
else
	$(VERB)$(F90C) -D_DEVLP $(FPP_FLAGS) $(INCLUDES) -g -O0 -fno-range-check -c $< -o $@ $(MOD_TO)inc_dev
endif
else # 'optim'
ifeq '$(X86_64)' '"yes"'
	$(VERB)$(F90C) -D_DEVLP $(FPP_FLAGS) $(INCLUDES) -fPIC -O0 -fno-range-check -c $< -o $@ $(MOD_TO)inc_dev
else
	$(VERB)$(F90C) -D_DEVLP $(FPP_FLAGS) $(INCLUDES) -O0 -fno-range-check -c $< -o $@ $(MOD_TO)inc_dev
endif
endif

obj/rational_numbers.o: misc/rational_numbers/rational_numbers.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) $(FPP_FLAGS) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/gft_common.o: misc/GFT/gft_common.f90
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/gft_jmfft.o: misc/GFT/gft_jmfft.f90 \
                 obj/gft_common.o
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/gft_set.o: misc/GFT/gft_set.f90 \
               obj/gft_jmfft.o
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/gft_do.o: misc/GFT/gft_do.f90 \
              obj/gft_jmfft.o
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/gft_end.o: misc/GFT/gft_end.f90 \
               obj/gft_common.o
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/gft.o: misc/GFT/gft.f90 \
           obj/gft_jmfft.o \
           obj/gft_set.o \
           obj/gft_do.o \
           obj/gft_end.o
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/minpack.o: misc/minpack/minpack.F90
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/bezier.o: misc/bezier/bezier.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) $(FPP_FLAGS) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/splines.o: misc/splines/splines.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) $(FPP_FLAGS) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/f90_gzlib.o: misc/f90_gzlib/f90_gzlib.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) $(FPP_FLAGS) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/zlib_f90.o: misc/f90_gzlib/zlib_f90.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) -I$(ZLIB_INCL) $(CC_FLAGS) -c $< -o $@

obj/iso_varying_string.o: misc/iso_varying_string/iso_varying_string.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) $(FPP_FLAGS) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/convexhull_mod.o: misc/ConvexHull/convexhull_mod.f90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/mod_ddebd2.o: misc/slatec/mod_ddebd2.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) -Imisc/suitesparse $(FPP_FLAGS) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/mod_slatec_aux.o: misc/slatec/mod_slatec_aux.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) -Iinc_dev $(FPP_FLAGS) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/mod_slatec_fun.o: misc/slatec/mod_slatec_fun.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) -Iinc_dev $(FPP_FLAGS) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/mod_slatec_solve.o: misc/slatec/mod_slatec_solve.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) -Iinc_dev $(FPP_FLAGS) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/RngStream.o: misc/RngStreams/RngStream.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(CC_FLAGS) -c $< -o $@

obj/RngStream_f90wrapper.o: misc/RngStreams/RngStream_f90wrapper.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) -c $< -o $@

obj/umf4_f90wrapper.o: misc/suitesparse/umf4_f90wrapper.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) \
		     -Imisc/suitesparse/AMD/Include \
		     -Imisc/suitesparse/UMFPACK/Include \
		     -Imisc/suitesparse/SuiteSparse_config \
		     -c $< -o $@

obj/amd_f90wrapper.o: misc/suitesparse/amd_f90wrapper.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) \
		     -Imisc/suitesparse/AMD/Include \
		     -Imisc/suitesparse/SuiteSparse_config \
		     -c $< -o $@

obj/cholmod_f90wrapper.o: misc/suitesparse/cholmod_f90wrapper.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) \
		     -Imisc/suitesparse/CHOLMOD/Include \
		     -Imisc/suitesparse/SuiteSparse_config \
		     -c $< -o $@

obj/spqr_f90wrapper.o: misc/suitesparse/spqr_f90wrapper.cpp
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CPLUSPLUS) $(WRAPPER_FLAGS) $(CC_FLAGS) \
			    -Imisc/suitesparse/SuiteSparse_config \
			    -Imisc/suitesparse/CHOLMOD/Include \
			    -Imisc/suitesparse/SPQR/Include \
			    -c $< -o $@

obj/triangle.o: misc/delaunay/2d/triangle.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) -DTRILIBRARY $(CC_FLAGS) -c $< -o $@

obj/triangle_delaunay.o: misc/delaunay/2d/triangle_delaunay.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CPP_FLAGS) $(CC_FLAGS) -c $< -o $@

obj/predicates.o: misc/delaunay/3d/predicates.cxx
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CPLUSPLUS) $(CC_FLAGS) -c $< -o $@

obj/tetgen.o: misc/delaunay/3d/tetgen.cxx
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CPLUSPLUS) $(CC_FLAGS) -DTETLIBRARY -c $< -o $@

obj/tetgen_f90wrapper.o: misc/delaunay/3d/tetgen_f90wrapper.cxx
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CPLUSPLUS) $(WRAPPER_FLAGS) $(CC_FLAGS) -DTETLIBRARY -c $< -o $@

obj/voronoi_f90wrapper.o: misc/voronoi/2d/voronoi_f90wrapper.c \
                          misc/voronoi/2d/jc_voronoi_EC.h
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CPP_FLAGS) $(CC_FLAGS) -c $< -o $@

obj/crc32.o: misc/crc32/crc32.s
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(CC_FLAGS) -c $< -o $@

obj/icrc32.o: misc/crc32/icrc32.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) -c $< -o $@

obj/crc32_adler.o: misc/crc32/crc32_adler.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) -c $< -o $@

obj/readline_c.o: misc/f90readline/readline_c.c
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(CC) $(WRAPPER_FLAGS) $(CC_FLAGS) -c $< -o $@

inc_dev/fml.mod: fml.F90 \
                 obj/mod_fileio.o \
                 obj/mod_funfun.o \
                 obj/mod_polyfun.o
	$(VERB)$(F90C) $(FPP_FLAGS) $(INCLUDES) $(MODULE_ONLY) $< $(MOD_TO)inc_dev

inc_dev/mod_pgplot.mod: mfplot

# theoretically, 'inc_dev/fgl.mod' could appear as useless; it is however
# used in the build of test_internal.o -- cf. tests/Makefile)
inc_dev/fgl.mod: fgl/src/fgl.F90 \
                 inc_dev/mod_plot2d.mod
	$(VERB)$(F90C) $(FPP_FLAGS) $(INCLUDES) $(MODULE_ONLY) $< $(MOD_TO)inc_dev

#--------------------------- final include -----------------------------

bin/subs_in_mod: bin/subs_in_mod.f90
	cd bin; $(MAKE)

# special behavior of gfortran: the final module file 'fml.F90'
# include explicitely all 'used' modules.
include/fml.mod: fml.F90 \
                 inc_dev/mod_fileio.mod \
                 inc_dev/mod_funfun.mod \
                 inc_dev/mod_polyfun.mod \
                 bin/subs_in_mod
	$(VERB)$(F90C) $(FPP_FLAGS) $(INCLUDES) $(MODULE_ONLY) $< $(MOD_TO)include
	@./sh_tools/private_components_in_fml_mod

# special behavior of gfortran: the final module file 'fgl.F90'
# include explicitely all 'used' modules.
include/fgl.mod: fgl/src/fgl.F90 \
                 inc_dev/mod_plot2d.mod \
                 bin/subs_in_mod
	$(VERB)$(F90C) $(FPP_FLAGS) $(INCLUDES) $(MODULE_ONLY) $< $(MOD_TO)include
	@./sh_tools/private_components_in_fgl_mod

#-----------------------------------------------------------------------

# meditor (graphical tool to edit matrices) uses only gcc and Qt lib.
.PHONY: meditor

ifeq '$(QT4_QMAKE)' '"yes"'
meditor: meditor/meditor.pro
	$(COLOR_RED)
	@echo "                      ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
	@echo "                      ┃           misc tools           ┃"
	@echo "                      ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
	$(COLOR_NORMAL)
	@echo
	@(cd meditor && $(QT4DIR)/bin/qmake && $(MAKE))
	@echo $(ECHO_OPT) "\r                                                      \c"
	$(COLOR_PURPLE)
	@echo $(ECHO_OPT) "\r  → done"
	$(COLOR_NORMAL)
	@echo
endif

# tools for special memory debug
bin/replace_alloc_dealloc:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	@cd debug && $(MAKE) replace_alloc_dealloc

bin/mem_debug_check:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	@cd debug && $(MAKE) mem_debug_check

bin/mem_debug_stats:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	@cd debug && $(MAKE) mem_debug_stats

bin/pointer_trace:
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	@cd debug && $(MAKE) pointer_trace

#=============================== rules =================================

.SUFFIXES:
.SUFFIXES: .F90 .f90 .f .o .mod

ifeq '$(MEMTR)' 'yes'

#---------------- MEMORY DEBUG des sources (mem trace) -----------------
tmp/%.f90: %.F90
	$(VERB)$(FPP) -D_DEVLP $(FPP_FLAGS) $< $(FPP_OUT) $@
	@bin/replace_alloc_dealloc $@
	@mv -f tmp/replace_alloc_dealloc.f90 $@

tmp/%.f90: fgl/src/%.F90
	$(VERB)$(FPP) -D_DEVLP $(FPP_FLAGS) -I./tmp $< $(FPP_OUT) $@
	@bin/replace_alloc_dealloc $@
	@mv -f tmp/replace_alloc_dealloc.f90 $@

obj/%.o: tmp/%.f90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

else

  ifeq '$(PTRTR)' 'yes'

#---------------- POINTER DEBUG des sources (ptr trace) ----------------
tmp/%.f90: %.F90
	$(VERB)$(FPP) -D_DEVLP $(FPP_FLAGS) $< $(FPP_OUT) $@

tmp/%.f90: fgl/src/%.F90
	$(VERB)$(FPP) -D_DEVLP $(FPP_FLAGS) -I./tmp $< $(FPP_OUT) $@
	@bin/pointer_trace $@
	@mv -f tmp/pointer_trace_out.f90 $@

obj/%.o: tmp/%.f90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

  else

#-------------------------- normal STUFF -------------------------------

obj/%.o: %.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) -D_DEVLP $(FPP_FLAGS) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

obj/%.o: fgl/src/%.F90
	@echo $(ECHO_OPT) "\r                                                      \c"
	@echo $(ECHO_OPT) "\r  ... making $(notdir $@): \c"
	$(VERB)$(F90C) -I./fgl/src/usr -I./tmp -D_DEVLP $(FPP_FLAGS) $(INCLUDES) $(F90_FLAGS) -c $< -o $@ $(MOD_TO)inc_dev

  endif

endif

# special rule to avoid recompiling (recursive-make)
inc_dev/%.mod: obj/%.o
	@if [ ! -f $@ ]; then \
      rm $< ; \
      $(MAKE) $< ; \
    fi

#=======================================================================

ifeq '$(PAPI)' '"yes"'
  PAPI_LIBS = $(PAPI_DIR)/libpapi.a
else # linux kernel not patched with PERFCTR, or PAPI not installed
  # in this case, dummy_papi.o is integrated in libfml
  PAPI_LIBS =
endif

ifeq '$(NEED_TERMCAP)' '"yes"'
  TERMCAP_LIB = -ltermcap
else # recent READLINE library doesn't include TERMCAP
  TERMCAP_LIB =
endif

ifeq '$(CFG)' 'debug'
  ifeq '$(HDF5)' '"yes"'
    HDF5_LIBS_SUBS = $(HDF5_F90_DIR)/libhdf5_fortran.a -L$(HDF5_1_6) -lhdf5
    HDF5_STAT_LIBS_SUBS = $(HDF5_F90_DIR)/libhdf5_fortran.a $(HDF5_1_6)/libhdf5.a
  endif
  ifeq '$(FGL)' 'no' # FML -- debug
    MUESLI_LIBS_SUBS = -L$(INSTALL_DIR) -lfml
    MUESLI_STAT_LIBS_SUBS = $(INSTALL_DIR)/libfml.a
  else # FML + FGL -- debug
    MUESLI_LIBS_SUBS = -L$(INSTALL_DIR) -lfgl -lfml -lmfplot
    MUESLI_STAT_LIBS_SUBS = $(INSTALL_DIR)/libfgl.a $(INSTALL_DIR)/libfml.a $(INSTALL_DIR)/libmfplot.a
  endif
  ifeq '$(PROF)' 'yes'
    MUESLI_LIBS_SUBS += -pg
    MUESLI_STAT_LIBS_SUBS += -pg
  endif
else # 'optim'
  ifeq '$(HDF5)' '"yes"'
    HDF5_LIBS_SUBS = -Wl,-rpath,$(HDF5_F90_DIR) -L$(HDF5_F90_DIR) -lhdf5_fortran -Wl,-rpath,$(HDF5_1_6) -L$(HDF5_1_6) -lhdf5
    HDF5_STAT_LIBS_SUBS = $(HDF5_F90_DIR)/libhdf5_fortran.a $(HDF5_1_6)/libhdf5.a
  endif
  ifeq '$(FGL)' 'no' # FML -- optim
    MUESLI_LIBS_SUBS = -Wl,-rpath,$(INSTALL_DIR) -L$(INSTALL_DIR) -lfml
    MUESLI_STAT_LIBS_SUBS = $(INSTALL_DIR)/libfml.a
  else # FML + FGL -- optim
    # mfplot already linked in the shared version of libfgl
    MUESLI_LIBS_SUBS = -Wl,-rpath,$(INSTALL_DIR) -L$(INSTALL_DIR) -lfgl -lfml
    MUESLI_STAT_LIBS_SUBS = $(INSTALL_DIR)/libfgl.a $(INSTALL_DIR)/libfml.a $(INSTALL_DIR)/libmfplot.a
  endif
endif

ifeq '$(CFG)' 'debug'
  ifneq '$(FGL)' 'no' # FML + FGL
    ifeq '$(X11_DIR)' '/usr/lib'
      X11_LIBS_SUBS = -lfreetype -lfontconfig -lXrender -lX11
    else ifeq '$(X11_DIR)' '/usr/lib/x86_64-linux-gnu'
      X11_LIBS_SUBS = -lfreetype -lfontconfig -lXrender -lX11
    else
      X11_LIBS_SUBS = -L$(X11_DIR) -lfreetype -lfontconfig -lXrender -lX11
    endif
  endif
else # 'optim'
  # X11 libraries already linked in the shared version of libfml
  X11_LIBS_SUBS =
endif

ifeq '$(CFG)' 'debug'
  ifeq '$(LAPACK_DIR)' '$(BLAS_DIR)'
    ifeq '$(LAPACK_DIR)' '/usr/lib'
      LAPACK_LIBS_SUBS = -llapack -lblas
    else ifeq '$(LAPACK_DIR)' '/usr/lib/x86_64-linux-gnu'
      LAPACK_LIBS_SUBS = -llapack -lblas
    else
      LAPACK_LIBS_SUBS = -Wl,-rpath,$(LAPACK_DIR) -L$(LAPACK_DIR) -llapack -lblas
    endif
    BLAS_LIBS_SUBS =
  else
    ifeq '$(LAPACK_DIR)' '/usr/lib'
      LAPACK_LIBS_SUBS = -llapack
    else ifeq '$(LAPACK_DIR)' '/usr/lib/x86_64-linux-gnu'
      LAPACK_LIBS_SUBS = -llapack
    else
      LAPACK_LIBS_SUBS = -Wl,-rpath,$(LAPACK_DIR) -L$(LAPACK_DIR) -llapack
    endif
    ifeq '$(BLAS_DIR)' '/usr/lib'
      BLAS_LIBS_SUBS = -lblas
    else ifeq '$(BLAS_DIR)' '/usr/lib/x86_64-linux-gnu'
      BLAS_LIBS_SUBS = -lblas
    else
      BLAS_LIBS_SUBS = -Wl,-rpath,$(BLAS_DIR) -L$(BLAS_DIR) -lblas
    endif
  endif
else # 'optim'
  # Blas and Lapack already linked in the shared version of libfml
  LAPACK_LIBS_SUBS =
  BLAS_LIBS_SUBS =
endif

ifeq '$(F90_LIB_DIR)' ''
  F90_LIB_SUBS =
else # not empty
  F90_LIB_SUBS = -Wl,-rpath,$(F90_LIB_DIR) -L$(F90_LIB_DIR) -lgfortran
endif

ifeq '$(HDF5_F90_DIR)' ''
  # avoids "-I" in f90flags which may leads to error
  HDF5_F90_DIR =.
endif

# only for information
BLAS_LIB_CONFIG = $(BLAS_DIR)
LAPACK_LIB_CONFIG = $(LAPACK_DIR)

ifeq '$(CFG)' 'debug'
  ifeq '$(ZLIB_DIR)' '/usr/lib'
    ZLIB_LIBS_SUBS = -lz
  else ifeq '$(ZLIB_DIR)' '/usr/lib/x86_64-linux-gnu'
    ZLIB_LIBS_SUBS = -lz
  else
    ZLIB_LIBS_SUBS = -L$(ZLIB_DIR) -lz
  endif
else # 'optim'
  # Zlib already linked in the shared version of libfml
  ZLIB_LIBS_SUBS =
endif

ifeq '$(CFG)' 'debug'
  ifeq '$(READLINE)' '"yes"'
    ifeq '$(DARWIN)' '"yes"'
      READLINE_LIB += -lreadline
    else
      READLINE_LIB += -lreadline -lhistory
    endif
  endif
else # 'optim'
  # Readline and history already linked in the shared version of libfml
  READLINE_LIB =
endif

ifeq '$(CFG)' 'debug'
  ifeq '$(NEED_LRT)' '"yes"'
    ifeq '$(DARWIN)' '"no"'
      RT_LIB_SUBS += -lrt
    endif
  endif
else # 'optim'
  # RT lib already linked in the shared version of libfml
  RT_LIB_SUBS =
endif

ifeq '$(CFG)' 'debug'
  PTHREAD_LIB = -lpthread
else # 'optim'
  # Pthread lib already linked in the shared version of libfml
  PTHREAD_LIB =
endif

ifeq '$(CFG)' 'debug'
  LIBSTDCPP_SUBS = -lstdc++
else # 'optim'
  # Stdc++ lib already linked in the shared version of libfml
  LIBSTDCPP_SUBS =
endif

ifeq '$(FGL)' 'no'
  STATIC_LIBS = lib/libfml.a
  DYN_LIBS = lib/libfml.so
else
  STATIC_LIBS = lib/libfml.a lib/libmfplot.a lib/libfgl.a
  DYN_LIBS = lib/libfml.so lib/libmfplot.so lib/libfgl.so
endif

muesli-config: muesli-config.in check_opts ../VERSION
	@cat $< | sed -e "s+@PREFIX@+$(INSTALL_DIR)+" \
		| sed -e "s+@F90C@+$(F90_COMP)+" \
		| sed -e "s+@PP_FLAG@+-D_$(F90C_TAG)+" \
		| sed -e "s+@F90FLAGS@+$(F90_FLAGS)+" \
		| sed -e "s+@MOD_INC_FLAG@+-I+" \
		| sed -e "s+@HDF5@+$(HDF5_F90_DIR)+" \
		| sed -e "s+@HDF5_LIBS@+$(HDF5_LIBS_SUBS)+" \
		| sed -e "s+@HDF5_STAT_LIBS@+$(HDF5_STAT_LIBS_SUBS)+" \
		| sed -e "s+@CC@+$(C_COMP)+" \
		| sed -e "s+@CFLAGS@+$(CPP_FLAGS) $(CC_FLAGS) $(WRAPPER_FLAGS)+" \
		| sed -e "s+@MUESLI_LIBS@+$(MUESLI_LIBS_SUBS)+" \
		| sed -e "s+@MUESLI_STAT_LIBS@+$(MUESLI_STAT_LIBS_SUBS)+" \
		| sed -e "s+@BLAS_LAPACK@+$(LAPACK_LIBS_SUBS) $(BLAS_LIBS_SUBS) $(ADD_LIB)+" \
		| sed -e "s+@BLAS_LAPACK_STAT@+$(LAPACK_DIR)/liblapack.a $(BLAS_DIR)/libblas.a $(ADD_LIB)+" \
		| sed -e "s+@BLAS_LIB@+$(BLAS_LIB_CONFIG)+" \
		| sed -e "s+@LAPACK_LIB@+$(LAPACK_LIB_CONFIG)+" \
		| sed -e "s+@X11_LIBS@+$(X11_LIBS_SUBS)+" \
		| sed -e "s+@ZLIB_LIBS@+$(ZLIB_LIBS_SUBS)+" \
		| sed -e "s+@READLINE_LIB@+$(READLINE_LIB)+" \
		| sed -e "s+@PTHREAD_LIB@+$(PTHREAD_LIB)+" \
		| sed -e "s+@RT_LIB@+$(RT_LIB_SUBS)+" \
		| sed -e "s=@LIBSTDC++@=$(LIBSTDCPP_SUBS)=" \
		| sed -e "s+@LD_FLAGS@+$(LD_FLAGS)+" \
		| sed -e "s+@PAPI_LIBS@+$(PAPI_LIBS)+" \
		| sed -e "s+@F90_LIB@+$(F90_LIB_SUBS)+" \
		| sed -e "s+@FGL@+$(FGL)+" \
		| sed -e "s+@TERMCAP@+$(TERMCAP_LIB)+" \
		| sed -e "s+@BUILD_OPTIONS@+$(MAKE_CFG)+" \
		| sed -e "s+@MUESLI_VERSION@+`cat ../VERSION`+" > $@
	@# strip multiple spaces inside echo command
	@sed -i -e '/echo/s/ \+/ /g' $@
	@chmod a+x $@

install: uninstall muesli-config f90_compiler_version ../VERSION
	@test -d $(INSTALL_DIR) || mkdir -p $(INSTALL_DIR)
	@ls include/*.mod > /dev/null 2>&1 && \
		(cp include/fml.mod $(INSTALL_DIR); \
		echo ""; \
		echo "  → module files installed") || :
	@ls lib/* > /dev/null 2>&1 && (cp lib/* $(INSTALL_DIR); \
		echo "  → libraries installed") || :
	@ls $(INSTALL_DIR)/*.so > /dev/null 2>&1 && \
		strip --strip-unneeded --strip-debug $(INSTALL_DIR)/*.so || :
ifneq '$(FGL)' 'no'
	@cp include/fgl.mod $(INSTALL_DIR)
	@cp ../src/fgl/mfplot/rgb.txt $(INSTALL_DIR)
	@cp -R ../src/fgl/mfplot/src/drivers/PDFLibXObj $(INSTALL_DIR)
	@rm -f $(INSTALL_DIR)/PDFLibXObj/*.png
	@rm -f $(INSTALL_DIR)/PDFLibXObj/ToDo
	@mkdir -p $(INSTALL_DIR)/fontconfig
	@cp -R ../src/fgl/mfplot/fontconfig/fonts $(INSTALL_DIR)/fontconfig
	@rm -f $(INSTALL_DIR)/fontconfig/fonts/ISOLatin1.list
	@rm -f $(INSTALL_DIR)/fontconfig/fonts/symbol8859.info
	@mkdir -p $(INSTALL_DIR)/fontconfig/cache
	@cat ../src/fgl/mfplot/fontconfig/fonts.conf.in \
	  | sed -e "s+@FONTS_DIR@+$(INSTALL_DIR)+" \
	  > $(INSTALL_DIR)/fontconfig/fonts.conf
endif
	@echo $(ECHO_OPT) "library source path:\n`pwd`" > $(INSTALL_DIR)/libmuesli.info
	@echo $(ECHO_OPT) "\nlibrary installation path:\n$(INSTALL_DIR)" >> $(INSTALL_DIR)/libmuesli.info
	@echo $(ECHO_OPT) "\nlibrary documentation path:\n$(DOCS_INSTALL_DIR)" >> $(INSTALL_DIR)/libmuesli.info
	@echo $(ECHO_OPT) "\nlibrary release:\n`cat ../VERSION`" >> $(INSTALL_DIR)/libmuesli.info
	@echo $(ECHO_OPT) "\nbuild date:" >> $(INSTALL_DIR)/libmuesli.info
	@date >> $(INSTALL_DIR)/libmuesli.info
	@echo $(ECHO_OPT) "\ncompiler version:" >> $(INSTALL_DIR)/libmuesli.info
	@ls f90_compiler_version > /dev/null 2>&1  && \
		(cat f90_compiler_version >> $(INSTALL_DIR)/libmuesli.info) || :
	@echo $(ECHO_OPT) "\nmake options:" >> $(INSTALL_DIR)/libmuesli.info
	@ls $(STATIC_LIBS) $(DYN_LIBS) > /dev/null 2>&1 && \
		echo "mixed (CFG=optim for shared libs; CFG=debug for archived libs)" >> $(INSTALL_DIR)/libmuesli.info || \
		(ls make_options > /dev/null 2>&1  && (cat make_options >> $(INSTALL_DIR)/libmuesli.info) || :)
	@test -d $(MUESLI_CONFIG_DIR) || mkdir -p $(MUESLI_CONFIG_DIR)
ifeq '$(QT4_QMAKE)' '"yes"'
	@(cd meditor && test -f meditor && cp meditor $(MUESLI_CONFIG_DIR) && \
        echo "  → 'meditor' installed")
endif
	@test -f muesli-config && cp muesli-config $(MUESLI_CONFIG_DIR)
	@mkdir -p $(MAN_INSTALL_DIR)/man1
	@cp ../docs/man/muesli-config.1 $(MAN_INSTALL_DIR)/man1
	@echo "  → man installed"
ifeq '$(MEMTR)' 'yes'
	@rm -f $(MUESLI_CONFIG_DIR)/mem_debug_check $(MUESLI_CONFIG_DIR)/mem_debug_stats
	@cp -f bin/mem_debug_check bin/mem_debug_stats $(MUESLI_CONFIG_DIR)
	@echo "  → 'mem_debug' tools installed"
endif
	@test -d $(DOCS_INSTALL_DIR) || mkdir -p $(DOCS_INSTALL_DIR)
	@ls ../copyright > /dev/null && cp ../copyright $(DOCS_INSTALL_DIR)
	@cd ../docs && ls muesli_ref_manual.pdf muesli_user_guide.pdf > /dev/null \
                    && cp muesli_ref_manual.pdf muesli_user_guide.pdf $(DOCS_INSTALL_DIR)
	@echo "  → documentation installed"
	@echo ""


f90_compiler_version:
	@$(F90_COMP) --version | head -n 1 > f90_compiler_version

uninstall:
	@test -d $(INSTALL_DIR) && (cd $(INSTALL_DIR) && \
		rm -f -R *.mod *.a *.$(SHARED_EXT) *.info *.sh rgb.txt \
		fontconfig/ PDFLibXObj/) || :
	@rm -f $(MUESLI_CONFIG_DIR)/meditor
	@rm -f $(MUESLI_CONFIG_DIR)/muesli-config
	@rm -f $(DOCS_INSTALL_DIR)/*.pdf

FMLclean:
	rm -f $(FML_LIB)
	rm -f inc_dev/fml.mod \
	      inc_dev/mod_core.mod \
	      inc_dev/mod_datafun.mod \
	      inc_dev/mod_elfun.mod \
	      inc_dev/mod_elmat.mod \
	      inc_dev/mod_fileio.mod \
	      inc_dev/mod_matfun.mod \
	      inc_dev/mod_mem_debug.mod \
	      inc_dev/mod_mfarray.mod \
	      inc_dev/mod_mfaux.mod \
	      inc_dev/mod_mfdebug.mod \
	      inc_dev/mod_ops.mod \
	      inc_dev/mod_physunits.mod \
	      inc_dev/mod_polyfun.mod \
	      inc_dev/mod_sparse.mod \
	      inc_dev/mod_specfun.mod \
	      inc_dev/mod_funfun.mod
	rm -f include/fml.mod

clean:
	rm -f *.mod *.o obj/* inc_dev/* *.out tmp/* make_options make_opt.inc \
	   *.gcov
	touch make_opt.inc
ifeq '$(MAKE_FGL)' 'FGL=yes'
	rm -f fgl/mfplot/fontconfig/cache/*
endif
	-cd fgl/mfplot && $(MAKE) clean
	-cd misc/ACM && $(MAKE) clean
	-cd misc/arpack && $(MAKE) clean
	-cd misc/suitesparse && $(MAKE) clean
	-cd tests && $(MAKE) clean
	-cd tests/muesli-config && \
		rm -f *.o # Don't call make ('muesli-config' perhaps not yet available)
	-cd tests/fgl && $(MAKE) clean
	-cd mex && $(MAKE) clean
	-cd sh_tools && $(MAKE) clean

distclean: clean
	rm -f include/* lib/* .depend
	-cd fgl/mfplot && $(MAKE) distclean
	-cd misc/arpack && $(MAKE) distclean
	-cd tests && $(MAKE) distclean
	-cd tests/muesli-config && \
		rm -f test_muesli_config_fml test_muesli_config_fgl # Don't call make ('muesli-config' perhaps not yet available)
	-cd tests/fgl && $(MAKE) distclean
	-cd tests/fgl/pcolor && $(MAKE) distclean
	-cd mex && $(MAKE) distclean
ifeq '$(QT4_QMAKE)' '"yes"'
	-cd meditor && test -f Makefile && $(MAKE) distclean && \
		rm -f Makefile || :
else
	-cd meditor && test -f Makefile && \
		rm -f Makefile moc_meditor.cpp *.o meditor || :
endif
	rm -f muesli-config f90_compiler_version fml_core/parameters.inc
	-cd bin && $(MAKE) clean

#-----------------------------------------------------------------------
# List of exported variables:                (COLOR_* are discarded)
#   MAKE
#   F90CACHE
#   VERB
#   X86_64
#   CFG
#   F90C_TAG
#   F90C
#   FC
#   PIC_FLAGS
#   F90_FLAGS
#   MOD_TO
#   FPP_FLAGS
#   CC
#   CC_FLAGS
#   CPP_FLAGS
#   CPLUSPLUS
#   WRAPPER_FLAGS
#   OPT_FLAGS
#   F90_LIB_DIR
#-----------------------------------------------------------------------
