# $Header$ -*-makefile-*-

# Purpose: Makefile for libnco_c++ module nco_c++
# Requires GNU Make---AT&T Make chokes on GNU syntax

# Copyright (C) 1994--2016 Charlie Zender
# License: GNU General Public License (GPL) Version 3
# See http://www.gnu.org/copyleft/gpl.html for full license text

# Quickie test copies:
# scp ~/nco/src/nco_c++/Makefile.old esmf.ess.uci.edu:nco/src/nco_c++
# scp ~/nco/src/nco_c++/Makefile.old soot.ess.uci.edu:nco/src/nco_c++
# scp ~/nco/src/nco_c++/Makefile.old goldhill.cgd.ucar.edu:nco/src/nco_c++

# Usage:
# cd ~/nco/src/nco_c++;make -f Makefile.old NETCDF4=Y OMP=Y dpn_cln cln all # neige
# cd ~/nco/src/nco_c++;make -f Makefile.old NETCDF4=N OMP=Y dpn_cln cln all # givre, virga
# cd ~/nco/src/nco_c++;SZ_LIB=/sopt/lib make -f Makefile.old NETCDF4=N OMP=Y SZ=Y dpn_cln cln all # greenplanet
# cd ~/nco/src/nco_c++;make -f Makefile.old NETCDF4=Y OMP=N dpn_cln cln all # ashes, elnino
# cd ~/nco/src/nco_c++;make -f Makefile.old NETCDF4=N OMP=Y dpn_cln cln all # esmf, sand
# cd ~/nco/src/nco_c++;make -f Makefile.old NETCDF4=N OMP=N dpn_cln cln all # sand, tephra
# cd ~/nco/src/nco_c++;make -f Makefile.old NETCDF4=Y OMP=Y UDUNITS2=Y dpn_cln cln all # cygwin

# 64-bit ABI netCDF3 on NCAR AIX systems (bluefire):
# cd ${HOME}/nco/src/nco_c++;NETCDF_LIB='/usr/local/lib64/r4i4' make -f Makefile.old --jobs=1 ABI=64 all;cd -
# 64-bit ABI netCDF4 on NCAR AIX systems (bluefire):
# cd ${HOME}/nco/src/nco_c++;CURL_LIB='/contrib/curl/7.21.2/lib' HDF5_ROOT='/contrib/hdf5-1.8.7_seq' NETCDF_ROOT='/contrib/netcdf/4.1.3_seq' SZ_LIB='/contrib/szip/lib' make -f Makefile.old --jobs=1 ABI=64 NETCDF4=Y OPTS=D SZ=Y all;cd -

# In rule 
# foobar.o : foo.c bar.c
# $@ is target = foobar.o
# $< is first dependency = foo.c
# $^ is name of all dependencies = foo.c bar.c
# $* is stem of match, and so much more

# Recursively expanded variables are defined with `=':
# Values are installed verbatim and expanded when substitution occurs
# Variable may be used before it is defined and expansion will be correct
# However variable may not be modified (e.g., appended) after definition

# Simply expanded variables are defined with `:=':
# Values are immediately expanded at the time variable is defined
# Variables must be defined before being used
# Variables may be modified without causing infinite recursion

# Top-level tokens defining directory structure
# These tokens may be over-ridden by environment variables or when invoking make, e.g. make DODS=Y
MY_BLD_DIR := ../../bld
MY_INC_DIR := ${HOME}/include
ifndef PVM_ARCH
 PVM_ARCH := $(shell ${MY_BLD_DIR}/pvmgetarch)
endif
ifndef MY_BIN_DIR
 MY_BIN_DIR := ../../bin
endif
ifndef MY_LIB_DIR
 MY_LIB_DIR := ../../lib
endif
ifndef MY_OBJ_DIR
 MY_OBJ_DIR := ../../obj
endif
ifndef MY_DAT_DIR
 MY_DAT_DIR := ../../data
endif
ifndef MY_BLD_DIR
 MY_BLD_DIR := .
endif
ifndef MY_DOC_DIR
 MY_DOC_DIR := .
endif
ifndef MY_DPN_DIR
 MY_DPN_DIR := ${MY_OBJ_DIR}
endif

# Primary tokens which determine build options
# Specify non-default when invoking make, e.g. make DODS=Y
ifndef ${ABI}
# 32- vs. 64-bit ABI: 32=32-bit mode (default), 64=64-bit mode if available
 ABI := 64
endif # endif ABI
ifndef ANTLR
 ANTLR := runantlr
endif # endif ANTLR
ifndef ANTLR_ROOT
 ANTLR_ROOT := /usr/local
endif
ifndef ANTLR_INC
 ANTLR_INC := ${ANTLR_ROOT}/include # Directory containing AST.hpp
endif
ifndef ANTLR_LIB
 ANTLR_LIB := ${ANTLR_ROOT}/lib # Directory containing libantlr.a
endif
ifndef ${CCACHE}
 CCACHE := N
endif # CCACHE
ifndef DAP
 DAP := Y
endif # DAP
ifndef ${DBG}
# Debugging token N=No (default) Y=Yes
 DBG := N
endif # endif DBG
ifndef GCC_RCH_ARG
 GCC_RCH_ARG :=
endif # endif GCC_RCH_ARG
ifndef I18N
 I18N := Y
 MY_SHR_DIR := ${HOME}/share
 MY_ES_DIR := ${MY_SHR_DIR}/locale/es/LC_MESSAGES
 MY_FR_DIR := ${MY_SHR_DIR}/locale/fr/LC_MESSAGES
endif # endif I18N
ifndef ICC_RCH_ARG
 ICC_RCH_ARG :=
endif # endif ICC_RCH_ARG
ifndef MK_DPN
 MK_DPN = ${CPP} -M # NB: Recursive expansion required
 MK_DPN_CXX = ${CXX} -M # NB: Recursive expansion required
endif # endif MK_DPN
ifndef ${MPI} # MPI
 MPI := N
endif # endif MPI
ifndef ${MPI_FAKE} # MPI
 MPI_FAKE := N
endif # endif MPI_FAKE
ifndef ${NETCDF4} # netCDF4 support
 NETCDF4 := N
endif # endif NETCDF4
ifndef NETCDF_ROOT
 NETCDF_ROOT := /usr/local
endif
ifndef NETCDF4_ROOT
 NETCDF4_ROOT := ${NETCDF_ROOT}
endif
ifndef NETCDF_INC
ifdef INC_NCAR
 NETCDF_INC := ${INC_NCAR} # NCAR module path
else # endelse INC_NCAR
 NETCDF_INC := ${NETCDF_ROOT}/include # Directory containing netcdf.h
endif # endif INC_NCAR
endif # endif NETCDF_INC
ifndef NETCDF_LIB
ifdef LIB_NCAR
 NETCDF_LIB := ${LIB_NCAR} # NCAR module path
else # endelse LIB_NCAR
 NETCDF_LIB := ${NETCDF_ROOT}/lib # Directory containing libnetcdf.a
endif # endif LIB_NCAR
endif # endif NETCDF_LIB
ifndef ${OMP} # OpenMP
 OMP := N
endif # endif OMP
ifndef OPTS
 OPTS := O
endif # endif OPTS
ifndef ${PNETCDF} # pnetCDF support
 PNETCDF := N
endif # endif PNETCDF
ifndef ${PRC}
# Precision token D=Double (default) S=Single
 PRC := S
endif # endif PRC
ifndef PVM_ARCH
 PVM_ARCH := $(shell ${HOME}/sh/pvmgetarch)
endif
ifndef SZ
# Link to Szip library
 SZ := N
endif
ifndef STC
# Created statically linked executable
 STC := N
endif
ifndef UDUNITS
# Use UDUnits functionality
 UDUNITS := N
endif
ifndef UDUNITS2
# Use UDUnits2 functionality
 UDUNITS2 := N
endif
ifndef UNAMES
 UNAMES := $(shell uname -s)
endif
ifndef USR_TKN
 USR_TKN := -DABORT_ON_ERROR
endif # endif USR_TKN
ifndef VRS_SNG
 VRS_SNG := $(shell date +%Y%m%d)
endif # endif VRS_SNG

# Derived-tokens based on primary tokens
# These tokens should not be altered by hand
ifneq (${null},$(findstring LINUX,${PVM_ARCH}))
# Decide among the plethora of Linux compilers
ifndef LINUX_CXX
# C++ compiler for Linux
 LINUX_CXX := g++
 #LINUX_CXX := clang
 #LINUX_CXX := como
 #LINUX_CXX := icpc
 #LINUX_CXX := insure
 #LINUX_CXX := pgCC
endif # endif LINUX_CXX
ifndef LINUX_CC
# C compiler for Linux
 LINUX_CC := gcc -std=c99 -pedantic -D_BSD_SOURCE -D_POSIX_SOURCE
 #LINUX_CC := clang
 #LINUX_CC := como --c99
 #LINUX_CC := icc -std=c99 -D_BSD_SOURCE -D_POSIX_SOURCE
 #LINUX_CC := insure
 #LINUX_CC := pgcc
endif # endif LINUX_CC
ifndef LINUX_FC
# Fortran compiler for Linux
 LINUX_FC := g95
 #LINUX_FC := gfortran
 #LINUX_FC := lf95
 #LINUX_FC := ifort
 #LINUX_FC := pgf90
endif # endif LINUX_CC
ifeq (${PVM_ARCH},LINUXAMD64)
ifndef LINUX_CXX
# GCC 3.3 fails in atomicity.h with -O, -O0, and -O2 so use 3.4 instead 
 LINUX_CXX := g++
endif # endif LINUX_CXX
ifndef LINUX_CC
 LINUX_CC := gcc -std=c99 -pedantic -D_BSD_SOURCE -D_POSIX_SOURCE
endif # endif LINUX_CC
ifndef LINUX_FC
 LINUX_FC := g95
endif # endif LINUX_FC
endif # endif LINUXAMD64
ifeq (${PVM_ARCH},LINUXALPHA)
 LINUX_FC := g77
endif # endif LINUXALPHA
endif # endif LINUX
ifeq (${PRC},D)
 USR_TKN := -DPRC_DBL ${USR_TKN}
else
 USR_TKN := -DPRC_FLT ${USR_TKN}
endif # endif PRC

# NB: CPP_TKN is recursively expanded variable, define only when components are ready
CPP_TKN = ${USR_TKN} -D${PVM_ARCH} -DNO_NETCDF_2 -DNCO_VERSION='${VRS_SNG}' -DHOSTNAME='${HOST}' -DUSER='${USER}' -DNCO_ABORT_ON_ERROR

ifeq (${SZ},Y)
# 20150515: -lsz needed (at least by icc) on rhea
ifdef SZ_LIB
 SZ_LIB_FLG := -L${SZ_LIB} -lsz
else
 SZ_LIB_FLG := -lsz
endif # end if SZ_LIB
endif # end if SZ

# At this point we change NETCDF_INC from a directory to a flag
NC_CFLAGS := $(shell nc-config --cflags)
NC_LDFLAGS := $(shell nc-config --libs)
NCO_LDFLAGS := -L${MY_LIB_DIR} -lnco -lnco_c++

ifeq (${PNETCDF},Y)
# Enable pnetCDF functionality
 NC_CFLAGS := $(shell /usr/local/parallel/bin/nc-config --cflags)
 NC_LDFLAGS := $(shell /usr/local/parallel/bin/nc-config --libs)
 MPI_CFLAGS := -I/usr/include/openmpi-x86_64
 MPI_LDFLAGS := -L/usr/lib64/openmpi/lib -lmpi
endif # endif PNETCDF

ifdef LIB_NCAR
 NC_LDFLAGS := ${LIB_NCAR} ${NC_LDFLAGS}
endif

OTHER_CFLAGS := ${NC_CFLAGS} ${MPI_CFLAGS} ${GSL_INC_FLG} ${UDUNITS_INC_FLG}
OTHER_LDFLAGS := ${NCO_LDFLAGS} ${NC_LDFLAGS} ${MPI_LDFLAGS} ${GSL_LIB_FLG} ${SZ_LIB_FLG} ${UDUNITS_LIB_FLG}

# NB: Do NOT add comment lines, e.g., # This is a comma, to character definitions
null :=
space := ${null} ${null}
comma := ,
newline := \n
# We replace `/' by `cszzsc', call perl, then replace `cszzxc' by `/'
# Unique character(s) to substitute for ${slash} before passing to perl regex
slash_rx := cszzsc
# Unique character(s) to replace by ${slash_rx} before passing to perl regex
slash := /
MY_OBJ_DIR_RX := $(subst ${slash},${slash_rx},${MY_OBJ_DIR})
MY_DPN_DIR_RX := $(subst ${slash},${slash_rx},${MY_DPN_DIR})

ifeq (${PVM_ARCH},WIN32)
 BNR_SFX := .exe
else
 BNR_SFX := ${null}
endif 

# Source file names with directories removed
# List source targets alphabetically by "category":
MDL_SRC := nco_utl.cc nco_fl.cc nco_dmn.cc nco_var.cc nco_att.cc nco_hgh.cc # libnco_c++
MDL_SRC += tst.cc # Test program
# Directories to search for source files
MDL_PTH := . ${HOME}/include
# Dependency list for executable
MDL_OBJ := $(addprefix ${MY_OBJ_DIR}/,$(addsuffix .o, $(basename ${MDL_SRC}))) 
# Dependency (make) file for each object file
MDL_DPN := $(addprefix ${MY_DPN_DIR}/,$(addsuffix .d, $(basename ${MDL_SRC}))) 
# VPATH helps make find dependencies (which are not pathname qualified) in *.d file
VPATH := $(subst ${space},:,${MDL_PTH})
# Prepend -I to use for compiler argument
CPP_PTH := $(foreach dir,${MDL_PTH},-I${dir})

# Variables having to do with binary executables created by module
MDL_BIN_TRG := tst # Binary targets
MDL_BIN_SYM_LNK := # Symbolic links
MDL_BIN_STB := ${MDL_BIN_TRG} ${MDL_BIN_SYM_LNK} # All C++ files in MY_BIN_DIR
MDL_BIN := $(addprefix ${MY_BIN_DIR}/,${MDL_BIN_STB}) # dst_cln removes these files

# Variables having to do with header files created by module
# List header targets alphabetically by "category":
MDL_INC_TRG := libnco_c++.hh nco_utl.hh nco_fl.hh nco_dmn.hh nco_var.hh nco_att.hh nco_hgh.hh # libnco_c++
MDL_INC_SYM_LNK := # Symbolic links
MDL_INC_STB = ${MDL_INC_TRG} ${MDL_INC_SYM_LNK} # All header files in ${MY_INC_DIR}
MDL_INC = $(addprefix ${MY_INC_DIR}/,${MDL_INC_STB}) # dst_cln removes these files

# Redefine default C and C++ pattern rules
${MY_OBJ_DIR}/%.o : %.c
	${CC} ${CPPFLAGS} ${CFLAGS} -c $< -o ${MY_OBJ_DIR}/$(notdir $@)
${MY_OBJ_DIR}/%.o : %.cc
	${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o ${MY_OBJ_DIR}/$(notdir $@)

# Default Fortran pattern rules: CRAY and RS6K must override these rules
${MY_OBJ_DIR}/%.o : %.F
	${FC} -c ${FFLAGS} ${CPPFLAGS} -o ${MY_OBJ_DIR}/$(notdir $@) $<
${MY_OBJ_DIR}/%.o : %.f
	${FC} -c ${FFLAGS} -o ${MY_OBJ_DIR}/$(notdir $@) $<

# Rules for installing header files
${MY_INC_DIR}/%.h : %.h
	cp -f -p $(notdir $@) $@
${MY_INC_DIR}/%.hh : %.hh
	cp -f -p $(notdir $@) $@

# Rules for installing i18n files
%.po : %.cc
	xgettext --default-domain=$* --join-existing $<
${MY_ES_DIR}/%.mo : %.po
#	Linux version accepts more arguments than Solaris version
#	msgfmt --output-file=$@ --statistics $<
	msgfmt -o $@ $<

# Automatically generate a dependency file for each source file
# $* is the stem, e.g., f
# $@ is the filename of the target, e.g., f.d
# Linux gcc may return an extra `.F' on Fortran names, e.g., `hello.F.o: hello.F'
# (.F)? gets rid of this extran `.F'
${MY_DPN_DIR}/%.d : %.F
# Following command makes, e.g., f.d begin "f.o f.d : f.F ..."
# Since f.o is not preceded by ${MY_OBJ_DIR}, objects are not recompiled when sources are touched.
#	${CPP} -M ${CPPFLAGS} $< | perl -p -e 's/$*\.F\.o/$*.o $@/g;' > $@
# Following command makes, e.g., f.d begin "/home/zender/obj/LINUX/f.o f.d : f.F ..."
# This works fairly well, but is a hack
# First pattern substitutes MY_OBJ_DIR_RX, which has placeholders for slashes
# Second pattern substitutes slashes for the placeholders
	${CPP} -M ${CPPFLAGS} $< | perl -p -e 's/$*(\.F)?\.o/${MY_OBJ_DIR_RX}\/$*.o ${MY_DPN_DIR_RX}\/$(notdir $@)/g;s/${slash_rx}/\${slash}/g' > $@
# Following command makes, e.g., f.d begin "${MY_OBJ_DIR}/f.o f.d : f.F ..."
# This would be the ideal command but I cannot get dollar sign to cooperate
#	${CPP} -M ${CPPFLAGS} $< | perl -p -e 's/$*\.F\.o/\${dollar}MY_OBJ_DIR\/$*.o $@/g;' > $@

${MY_DPN_DIR}/%.d : %.f
	${CPP} -M ${CPPFLAGS} $< | perl -p -e 's/$*\.o/${MY_OBJ_DIR_RX}\/$*.o ${MY_DPN_DIR_RX}\/$(notdir $@)/g;s/${slash_rx}/\${slash}/g' > $@

${MY_DPN_DIR}/%.d : %.c
#	${CPP} -M ${CPPFLAGS} $< | perl -p -e 's/$*\.o/$*.o $@/g;' > $@
	${CPP} -M ${CPPFLAGS} $< | perl -p -e 's/$*\.o/${MY_OBJ_DIR_RX}\/$*.o ${MY_DPN_DIR_RX}\/$(notdir $@)/g;s/${slash_rx}/\${slash}/g' > $@

${MY_DPN_DIR}/%.d : %.cc
# NB: Use ${CXX} rather than ${CPP} on C++ files for now because, e.g., SUNMP cpp does not 
# preprocess .cc files quite correctly
#	${CPP} -M ${CPPFLAGS} $< | perl -p -e 's/$*\.o/$*.o $@/g;' > $@
	${CXX} -M ${CPPFLAGS} $< | perl -p -e 's/$*\.o/${MY_OBJ_DIR_RX}\/$*.o ${MY_DPN_DIR_RX}\/$(notdir $@)/g;s/${slash_rx}/\${slash}/g' > $@

# First LDFLAGS is for typical C programs with netCDF, math, and networking
# Second LDFLAGS enables C/Fortran linking

# Manually define autotools tokens normally defined in HAVE_CONFIG_H
# Initialize OS-specific tokens to empty
CPP_TKN_OS := 
CPP_TKN_OS := -DHAVE_REGEX_H -DNCO_HAVE_REGEX_FUNCTIONALITY
ifneq (${PVM_ARCH},CRAY)
 CPP_TKN_OS += -DHAVE_MKSTEMP
endif # CRAY
ifneq (${null},$(findstring ${PVM_ARCH},FREEBSDLINUXALPHALINUXAMD64LINUXARMMACOSXWIN32))
 CPP_TKN_OS += -DHAVE_GETOPT_H -DHAVE_GETOPT_LONG
# UDUNITS_DAT OK to be empty for now
endif # !LINUX
ifneq (${null},$(findstring ${PVM_ARCH},AIXSGIMP64))
 CPP_TKN_OS += -DNEED_GETOPT_LONG
endif # !(AIX || SGI)
ifneq (${null},$(findstring AIX,${PVM_ARCH}))
# Visual age compiler headers must occur before g++ headers
 CPP_TKN_OS += -I/usr/vacpp/include
endif # AIX
ifeq (${DAP},Y)
 CPP_TKN_OS += -DENABLE_DAP
endif # !DAP
ifeq (${MPI},Y)
ifneq (${MPI_FAKE},Y)
 CPP_TKN_OS += -DENABLE_MPI
endif # MPI_FAKE
endif # !MPI
ifeq (${UDUNITS},Y)
 CPP_TKN_OS += -DENABLE_UDUNITS -DHAVE_UDUNITS_H
ifeq (${UDUNITS2},Y)
 CPP_TKN_OS += -DHAVE_UDUNITS2_H
endif # !UDUNITS2
endif # !UDUNITS

ifeq (${null},$(findstring SGI,${PVM_ARCH}))
 CPP_TKN_OS += -DHAVE_CSTDLIB
endif # SGI

# Works on AIX and AIX46K
ifneq (${null},$(findstring AIX,${PVM_ARCH}))
# AIX calls executable antlr not runantlr
ANTLR := antlr
# 20030804: Always use re-entrant (_r) compilers---Jim Edwards NCAR/IBM 
CC := xlc_r -qlanglvl=extc99
#CC := gcc -std=c99 -pedantic -D_BSD_SOURCE -D_POSIX_SOURCE
CXX := xlC_r
# CXX := g++
# fxm: 20040311 should this be cpp? gcc -M?
CPP := xlc -c -qlanglvl=extc99
ifneq (${null},$(findstring xl,${CC}))
# Visual Age compiler headers must occur before g++ headers
 CPP_TKN_OS += -I/usr/vacpp/include
endif # xlC compilers
# Add /usr/local/include for libintl.h explicitly until netCDF is moved there
CPPFLAGS += ${CPP_TKN} ${CPP_TKN_OS} ${CPP_PTH} ${OTHER_CFLAGS} -I/usr/local/include
FC := xlf95_r
LD := ld
LDFLAGS += -bh:5 ${OTHER_LDFLAGS}
LEX := flex
LINT := lint
YACC := bison
# AIX VA Compiler Collection
ifneq (${null},$(findstring xl,${CC}))
# Visual Age compiler defaults specified in /etc/vac.cfg
# Additional switch to fix compiler warnings on csz.c
# -qarch=auto : Automatically detect architecture of compiling machine and assume execution on same machine
# -qlonglong allow long long integers (and strtoll(), strtoull()) (default on in C not C++)
# -qmaxmem=num Limit memory used by space intensive optimizations to <num> kilobytes
# -qspill=size Size in B of register allocation spill area, mie needs > 1040 B
# -qsrcmsg prints transgressing source line with finger
# -qsuppress=1501-245 : Suppress RLIM_INFINITY memory message due to ulimits
# -qtune=auto : Optimize executable for architecture detected during compilation
 CFLAGS := -qlonglong -qmaxmem=8192 -qspill=2048 -qsrcmsg -qsuppress=1501-245
 FFLAGS := -NS2000 -qfixed=132
# -bh:5 suppresses annoying messages from xlC linker WARNING: Duplicate symbol: ...
 LDFLAGS += -bh:5
#LDFLAGS += -lxlf90 # Required for linking Fortran objects
ifeq (${OMP},Y)
# -qsmp=noauto : Turn on SMP/OMP code generation but do no automatic parallelization
# -qsmp=omp : Use industry standard OMP without IBM extensions
 OMP_FLG_C := -qsmp=omp
 OMP_FLG_F := -qsmp=omp
else
 CPP_DFN += -U_OPENMP
 FC := xlf95
endif # endif OMP
ifeq (${OPTS},O)
# -O : -O3 is safe, -O5 is dangerous
# -qstrict: Ensure that -O3 optimizations do not alter program semantics
# -Q : Inline all appropriate subprograms
 CFLAGS += -O3 -qstrict -Q
 FFLAGS += -O3 -qstrict -Q
endif
ifeq (${OPTS},D)
 CFLAGS += -g
 FFLAGS += -g
endif
ifeq (${OPTS},X)
# -qflttrap generates instructions for floating point exceptions
# -qidirfirst uses headers found in -I directories first
# -qmakedep creates .d file
# -qwarn64 check for possible long-to-integer or pointer-to-integer truncation
# -qhalt=e stop compiler if error severity equals or exceeds i, w, e, s, u
 CFLAGS += -g -qflttrap -qidirfirst -qwarn64 -qcheck=all -qhalt=s
 FFLAGS += -g
endif
ifeq (${ABI},64)
 AR := ar -X 64
 CFLAGS += -q64
 FFLAGS += -q64
 LDFLAGS += -q64 
else
 CPPFLAGS += -D_LARGE_FILES
endif # endif ABI
# Additional flags for AIX:
# -M Generate information to be included in a "make" description file; output goes to .u file
# -c Do not send object files to the linkage editor
# -P Preprocess but do not compile; output goes to .i file
# Using -P causes additional warning messages about lm 
# Not using -P causes *.o files to be created twice
${MY_DPN_DIR}/%.d : %.c
	${MK_DPN} ${CPPFLAGS} $< ;perl -p -e 's/$*\.o/${MY_OBJ_DIR_RX}\/$*.o ${MY_DPN_DIR_RX}\/$(notdir $@)/g;s/${slash_rx}/\${slash}/g' $*.u > $@ ; \
	rm -f $*.i $*.o $*.u;
${MY_DPN_DIR}/%.d : %.cc
	${MK_DPN} ${CPPFLAGS} $< ;perl -p -e 's/$*\.o/${MY_OBJ_DIR_RX}\/$*.o ${MY_DPN_DIR_RX}\/$(notdir $@)/g;s/${slash_rx}/\${slash}/g' $*.u > $@ ; \
	rm -f $*.i $*.o $*.u;
endif # endif AIX VA Compiler Collection
# GNU Compiler Collection
ifeq (${CXX},g++)
 CFLAGS := -Wall -Wunused
ifeq (${OPTS},O)
 CFLAGS += -O -g ${GCC_RCH_ARG}
endif
ifeq (${OPTS},D)
 CFLAGS += -g
endif
ifeq (${OPTS},R)
 CFLAGS += 
endif
ifeq (${OPTS},X)
 CFLAGS += -g -O
 LDFLAGS += /usr/local/lib/ccmalloc-g++.o -L/usr/local/lib -lccmalloc -ldl
endif
ifeq (${ABI},64)
 CC += -maix64 
 CXX += -maix64 
endif # endif ABI
 CXXFLAGS := ${CFLAGS}
endif # endif GNU Compiler Collection
# -q64: Select 64-bit compiler mode (required for accessing large files)
# -qwarn64: Warn on possible long-to-integer or pointer-to-integer truncation
CXXFLAGS := ${CFLAGS}
ifeq (${OMP},Y)
 CFLAGS += ${OMP_FLG_C}
 CXXFLAGS += ${OMP_FLG_C}
 FFLAGS += ${OMP_FLG_F}
# LD behavior assumes C source code
 LDFLAGS := ${OMP_FLG_C} ${LDFLAGS}
endif # endif OMP
endif
# endif AIX

ifeq (${PVM_ARCH},ALPHA)
ifeq (${OMP},Y)
 OMP_FLG := -omp
endif # endif OMP
CXX := cxx -std strict_ansi
#CXX := cxx -std ansi -D__NO_USE_STD_IOSTREAM
CC := cc
CFLAGS := ${OMP_FLG}
# OSF1 is for CCM compatibility
CPPFLAGS += ${CPP_TKN} ${CPP_TKN_OS} -DOSF1 ${CPP_PTH} ${OTHER_CFLAGS}
FC := f90
FFLAGS := -c ${OMP_FLG} -automatic -fpe3
FIXEDFLAGS := -extend_source
FREEFLAGS := -DHIDE_SHR_MSG -free
LD := ld
LDFLAGS += ${OMP_FLG} ${OTHER_LDFLAGS}
LEX := flex
LINT := lint
YACC := bison
ifeq (${PRC},D)
 FFLAGS += -r8 -i4
endif
ifeq (${OPTS},O)
 CFLAGS += -O2 -ansi_alias
 FFLAGS += -O3 -inline speed
endif
ifeq (${OPTS},D)
 CFLAGS += -g -check_bounds -check -check_omp
 FFLAGS += -g3 -C
endif
ifeq (${OPTS},X)
 CFLAGS := -g -N 132
 FFLAGS := -g -check bounds -check omp_bindings -check overflow -check underflow
endif
CXXFLAGS := ${CFLAGS}
${MY_OBJ_DIR}/%.o : %.F90
	${FC} -c ${FREEFLAGS} ${FFLAGS} ${CPPFLAGS} -o ${MY_OBJ_DIR}/$(notdir $@) $<
${MY_OBJ_DIR}/%.o : %.F
	${FC} -c ${FIXEDFLAGS} ${FFLAGS} ${CPPFLAGS} -o ${MY_OBJ_DIR}/$(notdir $@) $<
endif
# endif ALPHA

ifeq (${PVM_ARCH},CRAY)
CXX := g++
CC := cc
CPP := cpp
CPPFLAGS += ${CPP_TKN} ${CPP_TKN_OS} ${CPP_PTH} ${OTHER_CFLAGS}
FC := f90
LD := ld
LDFLAGS += ${OTHER_LDFLAGS}
LDFLAGS += -L/lib -lf
LEX := lex
LINT := lint
YACC := yacc
ifeq (${OPTS},O)
 CFLAGS += -O
 FFLAGS := -N 132
endif
ifeq (${OPTS},D)
 CFLAGS += -g
 FFLAGS := -g -N 132
endif
ifeq (${OPTS},X)
 CFLAGS += -g -N 132
 FFLAGS := -g -N 132 -e i
endif
# 1997/10/21 Added -P to suppress #line # directives on Fortran files
${MY_OBJ_DIR}/%.o : %.F
	${CPP} -P ${CPPFLAGS} $< > $(patsubst %.F,%.f,$(notdir $<))
	${FC} -c ${FFLAGS} $(patsubst %.F,%.f,$(notdir $<)) 
	-mv -f $(notdir $@) ${MY_OBJ_DIR}
	rm -f $(patsubst %.F,%.f,$(notdir $<)) 
${MY_OBJ_DIR}/%.o : %.f
	${FC} -c ${FFLAGS} $<
	mv -f $(notdir $@) ${MY_OBJ_DIR}
endif
# endif CRAY

# Works on LINUX, LINUXALPHA, LINUXAMD64, LINUXARM, and FREEBSD and MACOSX
ifneq (${null},$(findstring ${PVM_ARCH},LINUXALPHALINUXAMD64LINUXARMFREEBSDMACOSX))
CXX := ${LINUX_CXX}
CC := ${LINUX_CC}
CPP := ${CXX}
# HAVE_INLINE is GNU standard to activate inline functions (used by GSL)
CPPFLAGS += ${CPP_TKN} ${CPP_TKN_OS} -DHAVE_INLINE ${CPP_PTH} ${OTHER_CFLAGS} 
FC := ${LINUX_FC}
LD := ld
LDFLAGS += ${OTHER_LDFLAGS}
ifeq (${PVM_ARCH},MACOSX)
 LDFLAGS += -lresolv
endif # endif MACOSX
LEX := flex
LINT := lint
YACC := bison
# Comeau C Compiler
ifeq (${CXX},como)
 CFLAGS := 
 LDFLAGS := ${COMOROOT}/libcomo/libcomo.a ${LDFLAGS}
ifeq (${OPTS},O)
 CFLAGS += -O
endif
ifeq (${OPTS},D)
 CFLAGS += -g
endif
ifeq (${OPTS},R)
 CFLAGS +=
endif
ifeq (${OPTS},X)
 CFLAGS += -g
endif
 CXXFLAGS := ${CFLAGS}
endif # endif Comeau C Compiler
# GNU Compiler Collection or LLVM
# 20140204: gcc and clang should receive identical options
ifeq (g++,$(firstword ${CXX}))
 GCC_OR_CLANG := Y
endif
ifeq (clang,$(firstword ${CXX}))
 GCC_OR_CLANG := Y
endif
ifeq (${GCC_OR_CLANG},Y)
 CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
 CFLAGS := -Wall -Wno-unused-variable
# Compilation flags for numerical routines recommended by GSL 1.3 manual, p. 397
 CFLAGS += -Werror -Wall -W -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -fno-common -g -O4
# Compilation flags recommended by GSL that I like and use:
# -D_BSD_SOURCE: Support 4.3 BSD Unix extensions to ANSI C (prevents nameser.h warnings)
# -D_POSIX_SOURCE: Support POSIX.1 standard additions to ANSI C (prevents fileno warnings)
# -pedantic: Disallow non-ISO constructs (including type long long) (sometimes useful)
# -Werror: Consider warnings as errors
# -W: Extra warnings, including missing return values, comparison of signed with unsigned
# -Wall: Warn about common programming problems
# -Wmissing-prototypes: Warn if missing prototypes
# -Wshadow: Warn if local variable has same name as other local variable
# -Wpointer-arith: Warn if pointer arithmetic on types without size, e.g., void
# -Wcast-qual: Warn if const qualifier removed from pointer
# -Wcast-align: Warn if casting pointer to type of different size
# -Wwrite-strings: Apply const-qualifier to string constants, die if overwritten
# -fno-common: Prevent global variables from being simultaneously defined in different files
# -g: Put debugging symbols in executable
# -O4: Turn on optimization so uninitialized variables are flagged. Downside: optimizes-out many debugging symbols
# Compilation flags recommended by GSL that I do not like and do not use:
# -ansi: Support only strict ANSI C. Equivalent to -std=c89, conflicts with -std=c99
# --no-alias? -fstrict-aliasing
# -Waggregate-return: Warn if functions return aggregates like structures or unions
# -Wconversion: Warn if converting signed to unsigned. Intended for obsolete, non-prototyped code. Triggers fabsf(), sqrtf(), warnings.
# -Wnested-externs: Warn if extern is encountered within function. C only?
# -Wstrict-prototypes: Warn if inconsistent prototypes. C only?
# -Wtraditional: Warn if constructs differ between traditional and ANSI C. C only?
# -Dinline=: inline is not an ANSI keyword, must undefine inline to work with -ansi
# -fshort-enums: Make enums as short as possible, ususally non-int. Do not ever invoke this! This breaks ABI and causes subtle problems
ifeq (${OMP},Y)
ifneq (clang,$(firstword ${CXX}))
# 20140526 clang does not recognize/utilize -fopenmp
 OMP_FLG_C := -fopenmp
 OMP_FLG_F := -fopenmp
 LDFLAGS += -lgomp -lpthread
endif # endif clang
endif # endif OMP
ifeq (clang,$(firstword ${CXX}))
# 20140531 avoid clang error that -O4 is ame as -O3
 CFLAGS := $(subst -O4,-O3,${CFLAGS})
 LDFLAGS += -lstdc++
endif # endif clang
ifeq (${OPTS},O)
 CFLAGS += -O -g ${GCC_RCH_ARG}
endif
ifeq (${OPTS},D)
 CFLAGS += -g
endif
ifeq (${OPTS},R)
 CFLAGS += 
endif
ifeq (${OPTS},X)
 CFLAGS += -g -O
endif
ifneq (${null},$(findstring AMD64,${PVM_ARCH}))
ifeq (${ABI},64)
 CFLAGS += -m64
 FFLAGS += -m64
 LDFLAGS += -m64
endif # endif ABI
endif # endif LINUXAMD64
 CXXFLAGS := ${CFLAGS}
endif # endif GNU Compiler Collection or LLVM
# Intel (Kai) C++ Compiler
ifeq (icpc,$(firstword ${CXX}))
# -cxxlib-gcc: link using C++ run-time libraries provided with GCC (default) (generated code is binary compatible with g++)
# -lcprts : Eliminates most undefined references when linking with -cxxlib-gcc
# -cxxlib-icc: link using C++ run-time libraries provided by Intel (generated code is not binary compatible with g++)
# -fast: enable -xP -O3 -ipo -static
# -ipo[n]: enable multi-file IP optimizations (between files)
# -no-gcc: do not define  __GNUC__, __GNUC_MINOR__, and __GNUC_PATCHLEVEL__ macros
# -static: prevents linking with shared libraries
# -std=c99: Enable C99 support for C programs
# -aX<codes>: generate generic IA32 code and code specialized for processors specified by <codes> where codes are one or more of following:
# B: Intel Pentium M and compatible Intel processors
# K: Intel Pentium III and compatible Intel processors
# N: Intel Pentium 4 and compatible Intel processors
# P: Intel Pentium 4 processors with SSE3 extensions
# W: Intel Pentium 4 and compatible Intel processors
# -x<codes>: same as -aX only no generic code, run exclusively on <codes>
# -Wall: enable all warnings
# -Werror:force warnings to be reported as errors
# -w0: display errors (same as -w)
# -w1: display warnings and errors (DEFAULT)
# -w2: display remarks, warnings, and errors
# -wd<L1>[,<L2>,...] disable diagnostics L1 through LN
# remark #981: operands are evaluated in unspecified order
# remark #810: conversion from "double" to "float" may lose significant bits
# remark #1572: floating-point equality and inequality comparisons are unreliable
 CFLAGS := -w1
 CPPFLAGS += -I${IA32ROOT}/include -I${IA32ROOT}/include/c++
 LDFLAGS := -L${IA32ROOT}/lib ${LDFLAGS} -lsvml
 OMP_FLG_C := -openmp -openmp_report0
ifeq (${OPTS},O)
 CFLAGS += -O3 -g ${ICC_RCH_ARG}
endif
ifeq (${OPTS},D)
 CFLAGS += -g
endif
ifeq (${OPTS},R)
 CFLAGS +=
endif
ifeq (${OPTS},X)
 CFLAGS += -g -Wall -wd810,981,1572 -inline_debug_info
endif
 CXXFLAGS := ${CFLAGS}
endif # endif Intel (Kai) C++ Compiler
# Intel (Kai) Fortran Compiler
ifeq (${FC},ifort)
# -132: specify 132 column lines for fixed form sources (same as -extend_source)
# -axW: generate generic IA32 code and specialized code exclusively for Pentium 4 processors (requires linking to libsvml.a)
# -fast: enable -xP -O3 -ipo -static
# -fpconstant: extend precision of single precision constants assigned to double precision variables to double precision
# -fpp2: necessary, but not sufficient, for  OpenMP
# -ftz: enable/disable flush denormal results to zero
# -ip: enable single-file IP optimizations
# -ipo: enable multi-file IP optimizations
# -module: specifies path to place .mod files
# -mp: maintain floating point precision (disables some optimizations) (deprecated 20090129)
# -nus: do not append an underscore to external subroutine names
# -vec_report1: indicate vectorized loops (DEFAULT)
# -tune pn4: optimize for Pentium(R) 4 processor (DEFAULT)
# -us: append an underscore to external subroutine names
# -vms: enable VMS and DEC statement extensions
# -w95: supress warnings for non-standard fortran (which includes OpenMP)
 FFLAGS := -extend_source -fpconstant -fpp2 -implicitnone -w95
# -lsvml needed with -[a]xW
 LDFLAGS_F += -lsvml
 OMP_FLG_F := -openmp
ifeq (${PRC},D)
 FFLAGS += -i4 -r8
else
 FFLAGS += -i4
endif
ifeq (${OPTS},O)
 FFLAGS += -O3 -g -vec_report1 -ftz ${ICC_RCH_ARG}
endif
ifeq (${OPTS},D)
 FFLAGS += -g
endif
ifeq (${OPTS},R)
 FFLAGS += 
endif
ifeq (${OPTS},X)
# -C: extensive runtime diagnostics
# -e95 issues warnings for non-standard fortran (which includes OpenMP)
 FFLAGS += -g -C -e95
endif
endif # end Intel (Kai) Fortran Compiler
# Portland Group C++ Compiler
ifeq (${CXX},pgCC)
# Enable Large File Support (LFS) by default
 CFLAGS := -Mlfs
 LDFLAGS += -Mlfs
 OMP_FLG_C := -mp
ifeq (${OPTS},D)
 CFLAGS += -g
endif
ifeq (${OPTS},O)
 CFLAGS += -fast
endif
ifeq (${OPTS},R)
 CFLAGS += 
endif
ifeq (${OPTS},X)
 CFLAGS += -g -Mbounds
endif
 CXXFLAGS := ${CFLAGS}
endif # endif Portland Group C++ Compiler
# Portland Group Fortran Compiler
ifeq (${FC},pgf90)
 FFLAGS := -Mextend -Mnosecond_underscore -byteswapio -Mrecursive -Mdalign -Ktrap=fp -Mlfs
 OMP_FLG_F := -mp
ifeq (${PRC},D)
 FFLAGS += -Mr8 -Mi4
endif
ifeq (${OPTS},O)
 FFLAGS += -fast
endif
ifeq (${OPTS},D)
 FFLAGS += -g
endif
ifeq (${OPTS},R)
 FFLAGS += 
endif
ifeq (${OPTS},X)
 FFLAGS += -g -Mbounds
endif
endif # endif Portland Group Fortran Compiler
# G77 Fortran compiler
ifeq (${FC},g77)
 FFLAGS := -ffixed-line-length-132 -fno-second-underscore
ifeq (${OPTS},O)
 FFLAGS += -O
endif
ifeq (${OPTS},D)
 FFLAGS += -g -fdebug-kludge
endif
ifeq (${OPTS},R)
 FFLAGS += -fdebug-kludge
endif
ifeq (${OPTS},X)
 FFLAGS := -g -O -fdebug-kludge -fbounds-check
endif
endif # endif G77 Fortran compiler
ifeq (${OMP},Y)
 CFLAGS += ${OMP_FLG_C}
 CXXFLAGS += ${OMP_FLG_C}
 FFLAGS += ${OMP_FLG_F}
# LD behavior assumes C source code
 LDFLAGS := ${OMP_FLG_C} ${LDFLAGS}
endif # endif OMP
endif
# endif LINUX, LINUXALPHA, LINUXAMD64, LINUXARM, and FREEBSD and MACOSX

ifeq (${PVM_ARCH},MACOSXOLD)
CXX := c++
CC := cc
CFLAGS := -Wall
CPP := ${CC}
CPPFLAGS := ${CPP_TKN} ${CPP_TKN_OS} ${CPP_PTH} ${OTHER_CFLAGS}
FC := f90
LD := ld
LDFLAGS += ${OTHER_LDFLAGS} -lresolv -lm
LEX := flex
LINT := lint
YACC := bison
ifeq (${OPTS},O)
 CFLAGS += -O
endif
ifeq (${OPTS},D)
 CFLAGS += -g
endif
ifeq (${OPTS},R)
 CFLAGS += 
endif
ifeq (${OPTS},X)
 CFLAGS += -g -O
 LDFLAGS += /usr/local/lib/ccmalloc-gcc.o -L/usr/local/lib -lccmalloc -ldl
endif
CXXFLAGS := ${CFLAGS}
ifeq (${OMP},Y)
 CFLAGS += ${OMP_FLG}
 FFLAGS += ${OMP_FLG}
 LDFLAGS := ${OMP_FLG} ${LDFLAGS}
endif # endif OMP
endif
# endif MACOSXOLD

ifeq (${PVM_ARCH},NECSX)
ifeq (${OMP},Y)
 OMP_FLG := -Popenmp
endif # endif OMP
CXX := c++
#CC := c++ -Xa
CC := cc
CPP := c++ -E
#CPP := /usr/lib/cpp
CPPFLAGS := ${CPP_TKN} ${CPP_TKN_OS} ${OTHER_CFLAGS}
FC := f90
LD := ld
LDFLAGS += ${OTHER_LDFLAGS} -lm
ifeq ($(USE_FORTRAN_ARITHMETIC),Y)
# LDFLAGS += -L/lib -lf
endif
LEX := lex
LINT := lint
YACC := yacc
ifeq (${OPTS},O)
 CFLAGS += -h2 -hmath vector -hxint
# CFLAGS += -Cvopt -math vector -xint
 FFLAGS = -Cvopt -f3
endif
ifeq (${OPTS},D)
 CFLAGS += -g
 FFLAGS = -g -f3
endif
ifeq (${OPTS},X)
 CFLAGS += -h0 -g -hstack=nan
# CFLAGS += -Cdebug -init stack=nan
 FFLAGS = -Cdebug -eR -f3 -Wf"-init stack=nan heap=nan"
endif
MK_DPN = /usr/local/bin/mkdep.perl /usr/lib/cpp # NECSX try this
${MY_DPN_DIR}/%.d : %.c
	${MK_DPN} ${CPPFLAGS} $< | perl -p -e 's/$*\.o/${MY_OBJ_DIR_RX}\/$*.o ${MY_DPN_DIR_RX}\/$(notdir $@)/g;s/${slash_rx}/\${slash}/g' > $@
endif
# endif NECSX

ifeq (${PVM_ARCH},RS6K)
CXX := g++
CC := gcc -ansi
CPP := /lib/cpp -P
CPPFLAGS := ${CPP_TKN} ${CPP_TKN_OS} ${OTHER_CFLAGS}
FC := xlf
LD := ld
LDFLAGS += ${OTHER_LDFLAGS} -lm
ifeq ($(USE_FORTRAN_ARITHMETIC),Y)
 LDFLAGS += -lxlf90 -lxlf
endif
LEX := lex
LINT := lint
YACC := yacc
ifeq (${OPTS},O)
 CFLAGS += -O2
 CPP := ${CPP} ${CPPFLAGS}
 PREPROCESS.F := ${CPP} ${CPPFLAGS}
 FFLAGS := -O -NS2000 -qfixed=132
endif
ifeq (${OPTS},D)
 CFLAGS += -g
 CPP := ${CPP} ${CPPFLAGS}
 PREPROCESS.F := ${CPP} ${CPPFLAGS}
 FFLAGS := -g -NS2000 -qfixed=132
endif
${MY_OBJ_DIR}/%.o : %.F
	${CPP} ${CPPFLAGS} $< ${MY_OBJ_DIR}/$(basename $<).f 
	${FC} -c ${FFLAGS} -o ${MY_OBJ_DIR}/$(notdir $@) ${MY_OBJ_DIR}/$(basename $<).f
${MY_OBJ_DIR}/%.o : %.f
	${FC} -c ${FFLAGS} -o ${MY_OBJ_DIR}/$(notdir $@) $<
endif
# endif RS6K

# SGI6, SGI64, SGIMP64
ifneq (,$(findstring SGI,${PVM_ARCH}))
CXX := CC -LANG:std
CC := cc -c99
# 20000302: -w suppresses warnings which will swamp linker
#CXX := g++ -w
#CC := gcc
CPPFLAGS += ${CPP_TKN} ${CPP_TKN_OS} ${CPP_PTH} ${OTHER_CFLAGS}
FC := f90 -cpp
LD := ld
LDFLAGS += ${OTHER_LDFLAGS}
LEX := flex
LINT := lint
YACC := bison
ifeq (${PVM_ARCH},SGI6)
 GCC_ABI_FLG := -mabi=32
 GCC_LDFLAGS_SZ_SPC := ${GCC_ABI_FLG} -mips3 
 SGI_ABI_FLG := -n32 -mips3 ${OMP_FLG}
else # SGI64, SGIMP64
ifeq (${ABI},64)
 GCC_ABI_FLG := -mabi=64
 GCC_LDFLAGS_SZ_SPC := ${GCC_ABI_FLG} -mips4 -L/usr/local/lib/mabi=64
 SGI_ABI_FLG := -64 -mips4 ${OMP_FLG}
else # ABI=32
 GCC_ABI_FLG := -mabi=32
 GCC_LDFLAGS_SZ_SPC := ${GCC_ABI_FLG} -mips4
 SGI_ABI_FLG := -n32 -mips4 ${OMP_FLG}
endif # endif ABI
endif # endif SGI64, SGIMP64
ifeq (gcc,$(firstword ${CC}))
 LDFLAGS := $(GCC_LDFLAGS_SZ_SPC) ${OTHER_LDFLAGS} -lm
 CFLAGS := ${GCC_ABI_FLG} -Wall
ifeq (${OPTS},O)
 CFLAGS += -O2
endif
ifeq (${OPTS},R)
 CFLAGS += 
endif
ifeq (${OPTS},D)
 CFLAGS += -g
endif
ifeq (${OPTS},X)
 CFLAGS += -g -O
endif
 CXXFLAGS := ${CFLAGS}
endif
# endif CC=gcc
ifeq (CC,$(firstword ${CXX}))
# SGI Native C++ headers are in /usr/include/CC
 LDFLAGS := ${SGI_ABI_FLG} ${OTHER_LDFLAGS} -lm
 CFLAGS := ${SGI_ABI_FLG}
ifeq (${OPTS},O)
 CFLAGS += -O2
endif
ifeq (${OPTS},R)
 CFLAGS += 
endif
ifeq (${OPTS},D)
 CFLAGS += -g
endif
ifeq (${OPTS},X)
 CFLAGS += -g -trapuv
endif
 CXXFLAGS := ${CFLAGS}
endif
# endif CC=cc
# Fortran flags
FFLAGS := ${SGI_ABI_FLG} -extend_source
ifeq (${OPTS},O)
 FFLAGS += -O2
endif
ifeq (${OPTS},R)
 FFLAGS += 
endif
ifeq (${OPTS},D)
 FFLAGS += -g
endif
ifeq (${OPTS},X)
 FFLAGS += -g -check_bounds -trapuv
endif
# end fortran flags
endif
# endif SGI6, SGI64, SGIMP64

ifeq (${UNAMES},SunOS) 
#CXX := CC
#CC := cc
CXX := g++
CC := gcc
CFLAGS := -Wall
CPP := cpp
CPPFLAGS := ${CPP_TKN} ${CPP_TKN_OS} ${CPP_PTH} ${OTHER_CFLAGS} 
FC := f90 -DHIDE_SHR_MSG
#FFLAGS := -xs -stackvar -e -Qoption f90comp -r8const
FFLAGS := -xs -stackvar -e 
LD := ld
LDFLAGS := ${OTHER_LDFLAGS} -lsunmath -lsocket -lnsl
#LDFLAGS += -lF77 -lM77 -lresolv
LEX := lex
LINT := lint
YACC := yacc
ifeq (${ABI},64)
# Sun compiler
ifeq (${CC},cc)
 CFLAGS := -xarch=v9
 FFLAGS := -xarch=v9
 LDFLAGS += -xarch=v9
endif # endif Sun compiler
# GNU Compiler Collection
ifeq (gcc,$(firstword ${CC}))
 CFLAGS += -mabi=64
 FFLAGS += -mabi=64
 LDFLAGS += -mabi=64
endif # endif GNU Compiler Collection
endif # endif ABI
ifeq (${OPTS},O)
 CFLAGS += -O2
 FFLAGS += -fast
endif
ifeq (${OPTS},D)
 CFLAGS += -g
 FFLAGS += -g
endif
ifeq (${OPTS},X)
 CFLAGS += -g 
 FFLAGS += -g
# NB: 19980601 -C (range-checking) is not supported by Sun f90
ifeq (${FC},f77)
 FFLAGS += -C
endif
endif
 CXXFLAGS := ${CFLAGS}
endif
# endif SunOS=SUN4SOL2,SUNMP

ifeq (${PVM_ARCH},WIN32)
CXX := g++
CC := gcc -ansi
CPP := cpp
# NB: nameser.h needs -Di386, but gcc sends -Di586 (on pentiums)
CPP_TKN_OS += -Di386 -DNEED_STRCASECMP -DNEED_STRDUP -I/usr/include
CPPFLAGS += ${CPP_TKN} ${CPP_TKN_OS} ${CPP_PTH} ${OTHER_CFLAGS}
FC := g77
LD := ld
LDFLAGS += ${OTHER_LDFLAGS} -lm
LEX := flex
LINT := lint
YACC := bison
ifeq (${OPTS},O)
 CFLAGS += -O
endif
ifeq (${OPTS},D)
 CFLAGS += -g
endif
endif
# endif WIN32

ifneq (${null},$(findstring LINUX,${PVM_ARCH}))
ifeq (${CCACHE},Y)
# Prefix CC and CXX with ccache
 CC := ccache ${CC}
 CXX := ccache ${CXX}
endif # !CCACHE
endif # !LINUX

ifeq ($(STC),Y)
# Created statically linked executable
 LDFLAGS := -static ${LDFLAGS}
endif # endif STC

# Define any remaining variables
libnco_c++ := ${MY_LIB_DIR}/libnco_c++

# Default targets
all: ${MDL_BIN_TRG} inc lib dat tst
# .PHONY tells make to remake the following non-file targets 
.PHONY: all cln dst_cln debug ${MDL_BIN_TRG}
# Delete default suffixes---this should increase speed
.SUFFIXES: 
# Define suffixes that matter
.SUFFIXES: .cc .c .o .F .d
# Delete targets that were not successfully made
.DELETE_ON_ERROR:
lib_dir :
	- if ! test -d ${MY_LIB_DIR}; then mkdir ${MY_LIB_DIR}; fi
bin_dir :
	- if ! test -d ${MY_BIN_DIR}; then mkdir ${MY_BIN_DIR}; fi
obj_dir :
	- if ! test -d ${MY_OBJ_DIR}; then mkdir ${MY_OBJ_DIR}; fi

# Targets in bin
TST_OBJ := ${MY_OBJ_DIR}/tst.o
tst:	${MY_BIN_DIR}/tst lib
${MY_BIN_DIR}/tst:	${TST_OBJ}
	${CXX} -o $@ ${TST_OBJ} ${LDFLAGS}
	chmod 755 $@

bin : ${MDL_BIN_TRG}
bin_cln: 
	rm -f ${MDL_BIN}
# Targets in bld
bld_cln :
	cd ${MY_BLD_DIR}; rm -f TAGS
# Targets in dat
data:	dat
dat:	./in.nc ${MY_DAT_DIR}/in.nc 
${MY_DAT_DIR}/in.nc: ${MY_DAT_DIR}/in.cdl
	ncgen -b -o $@ $<
./in.nc: ${MY_DAT_DIR}/in.cdl
	ncgen -b -o $@ $<
dat_cln :
	rm -f in.nc foo.nc
# Targets in dpn
dpn : ${MDL_DPN}
dpn_cln :
	rm -f ${MDL_DPN}
# Targets in dpn
dst : 
	cd ..; tar cvzf /var/ftp/pub/zender/nco_c++/nco_c++.tar.gz ./nco_c++;
# Targets in inc
inc : ${MDL_INC}
inc_cln :
	rm -f ${MDL_INC}
# Targets in lib
lib : inc ${libnco_c++}.a
${libnco_c++}.a : inc ${libnco_c++}.a(${MY_OBJ_DIR}/nco_att.o) \
	${libnco_c++}.a(${MY_OBJ_DIR}/nco_dmn.o) \
	${libnco_c++}.a(${MY_OBJ_DIR}/nco_fl.o) \
	${libnco_c++}.a(${MY_OBJ_DIR}/nco_hgh.o) \
	${libnco_c++}.a(${MY_OBJ_DIR}/nco_var.o) \
	${libnco_c++}.a(${MY_OBJ_DIR}/nco_utl.o)
# NB: Do not place comments in the middle of a rule, or have \ at the end
lib_cln :
	rm -f ${libnco_c++}.a ${libnco_c++}.la ${libnco_c++}.so*
# Targets in obj
obj : ${MDL_OBJ}
obj_cln :
	rm -f ${MDL_OBJ}

# Housekeeping
clean : cln
cln : dat_cln dpn_cln obj_cln
debug: dbg
dbg:
	@printf "ABI = ${ABI}\n"
	@printf "ANTLR = ${ANTLR}\n"
	@printf "AR = ${AR}\n"
	@printf "BNR_SFX = ${BNR_SFX}\n"
	@printf "CC = ${CC}\n"
	@printf "CCACHE = ${CCACHE}\n"
	@printf "CFLAGS = ${CFLAGS}\n"
	@printf "CPP = ${CPP}\n"
	@printf "CPPFLAGS = ${CPPFLAGS}\n"
	@printf "CPP_PTH = ${CPP_PTH}\n"
	@printf "CPP_TKN = ${CPP_TKN}\n"
	@printf "CXX = ${CXX}\n"
	@printf "CXXFLAGS = ${CXXFLAGS}\n"
	@printf "DAP = ${DAP}\n"
	@printf "DAP_ROOT = ${DAP_ROOT}\n"
	@printf "DBG = ${DBG}\n"
	@printf "FC = ${FC}\n"
	@printf "FFLAGS = ${FFLAGS}\n"
	@printf "FL_FMT = ${FL_FMT}\n"
	@printf "GCC_RCH_ARG = ${GCC_RCH_ARG}\n"
	@printf "HOST = ${HOST}\n"
	@printf "HOSTNAME = ${HOSTNAME}\n"
	@printf "ICC_RCH_ARG = ${ICC_RCH_ARG}\n"
	@printf "LAMMPICC = ${LAMMPICC}\n"
	@printf "LAMMPICXX = ${LAMMPICXX}\n"
	@printf "LDFLAGS = ${LDFLAGS}\n"
	@printf "LEX = $(LEX)\n"
	@printf "LINUX_CC = $(LINUX_CC)\n"
	@printf "LINUX_CXX = $(LINUX_CXX)\n"
	@printf "MDL_BIN_TRG = ${MDL_BIN_TRG}\n"
	@printf "MDL_DPN = ${MDL_DPN}\n"
	@printf "MDL_MPI_TRG = ${MDL_MPI_TRG}\n"
	@printf "MDL_OBJ = ${MDL_OBJ}\n"
	@printf "MDL_PTH = ${MDL_PTH}\n"
	@printf "MDL_RPM_NST_NM = ${MDL_RPM_NST_NM}\n"
	@printf "MDL_SRC = ${MDL_SRC}\n"
	@printf "MPICC = ${MPICC}\n"
	@printf "MPICH_CC = ${MPICH_CC}\n"
	@printf "MPICH_CXX = ${MPICH_CXX}\n"
	@printf "MPICXX = ${MPICXX}\n"
	@printf "MPI_PRC = ${MPI_PRC}\n"
	@printf "MPI_PRC_SNG = ${MPI_PRC_SNG}\n"
	@printf "MY_BIN_DIR = ${MY_BIN_DIR}\n"
	@printf "MY_BLD_DIR = ${MY_BLD_DIR}\n"
	@printf "MY_BLD_DIR = ${MY_BLD_DIR}\n"
	@printf "MY_DAT_DIR = ${MY_DAT_DIR}\n"
	@printf "MY_DOC_DIR = ${MY_DOC_DIR}\n"
	@printf "MY_DPN_DIR = ${MY_DPN_DIR}\n"
	@printf "MY_INC_DIR = ${MY_INC_DIR}\n"
	@printf "MY_LIB_DIR = ${MY_LIB_DIR}\n"
	@printf "MY_SHR_DIR = ${MY_SHR_DIR}\n"
	@printf "MY_OBJ_DIR = ${MY_OBJ_DIR}\n"
	@printf "NCO_LDFLAGS = $(NCO_LDFLAGS)\n"
	@printf "NCO_LIBS = $(NCO_LIBS)\n"
	@printf "NCO_VRS = ${NCO_VRS}\n"
	@printf "NC_LDFLAGS = $(NC_LDFLAGS)\n"
	@printf "NC_LIBS = $(NC_LIBS)\n"
	@printf "NETCDF4 = ${NETCDF4}\n"
	@printf "NETCDF4_ROOT = ${NETCDF4_ROOT}\n"
	@printf "NETCDF_INC = ${NETCDF_INC}\n"
	@printf "NETCDF_LIB = ${NETCDF_LIB}\n"
	@printf "NETCDF_ROOT = ${NETCDF_ROOT}\n"
	@printf "OMP = ${OMP}\n"
	@printf "OPTS = ${OPTS}\n"
	@printf "PNETCDF = ${PNETCDF}\n"
	@printf "PRC = ${PRC}\n"
	@printf "PVM_ARCH = ${PVM_ARCH}\n"
	@printf "RPM = ${RPM}\n"
	@printf "SRC_LST = $(SRC_LST)\n"
	@printf "STC = ${STC}\n"
	@printf "THR_NBR = ${THR_NBR}\n"
	@printf "THR_NBR_SNG = ${THR_NBR_SNG}\n"
	@printf "TMP_LDFLAGS = ${TMP_LDFLAGS}\n"
	@printf "TMP_LIBS = ${TMP_LIBS}\n"
	@printf "UDUNITS = $(UDUNITS)\n"
	@printf "UDUNITS_INC_FLG = $(UDUNITS_INC_FLG)\n"
	@printf "UDUNITS_LIB_FLG = $(UDUNITS_LIB_FLG)\n"
	@printf "UNAMES = ${UNAMES}\n"
	@printf "VPATH = ${VPATH}\n"
	@printf "VRS_SNG = ${VRS_SNG}\n"
	@printf "YACC = ${YACC}\n"
distclean : dst_cln
dst_cln : cln bld_cln lib_cln
install : inc 
tags : 
	etags *.cc *.c *.com *.F *.F90 *.h *.hh Makefile
uninstall : dst_cln bin_cln inc_cln lib_cln

# Create dependency files only if they will not be immediately deleted
INCLUDE_DPN := TRUE
GOALS_WHICH_DELETE_DEPENDENCY_FILES := cln clean dir distclean dst_cln dpn_cln tags uninstall
ifeq (,$(findstring $(MAKECMDGOALS),${GOALS_WHICH_DELETE_DEPENDENCY_FILES}))
 INCLUDE_DPN := TRUE
else
 INCLUDE_DPN := FALSE
endif
ifeq (${INCLUDE_DPN},TRUE)
-include ${MDL_DPN}
endif
