# CHARMM 26 makefile for GNU compilers (Linux or elsewhere)
ROOT = rootdir
SRC = $(ROOT)/source
FLX = $(ROOT)/tool/preflx
GMS = $(ROOT)/tool/gmscomp_gnu
LIB = $(ROOT)/lib/gnu
EXEC = $(ROOT)/exec/gnu
CC = icc -Dnographics -Dnographics -Dnographics -O -Dgnu -DLINUX $(I8DUM2)
# Note that CC on line 8 and GLIB on line 10, sorry
GLIB =  
CPP = /bin/cat
CCPP = g++ -Dgnu
INCLUDE = 
ADDLIB = 
ADDLIB := $(ADDLIB) $(GLIB)
QLIB =
ENDIAN =
# GNU options for MBO(N)D code:
# note that -fno-automatic -finit-local-zero are dangerous
# options because they mask incorrect behaviour. They are
# here only to simulate SGI compiler behaviour to facilitate
# initial porting from SGI (with -static)
# and eventually should be removed and offending code fixed.
# NOTE: BLAS library is needed by MBO(N) code
# BLAS for Linux/PPro from: http://www.cs.utk.edu/~ghenry/distrib
# BLAS dependency has been removed as of c27b2 and c28a2
ifdef MBOND
MBONDFLG = -fno-automatic -finit-local-zero -O -Wall -Wsurprising -W -DCHARMM
INCLUDE = -I../../source/moldyn
endif

# options for compilation with APBS
ifdef APBS
# these must be defined: APBS_LIB, IAPBS_LIB and APBS_BLAS
ADDLIB := $(ADDLIB) $(IAPBS_LIB)/iapbs.a \
        -L$(APBS_LIB) -lapbsmainroutines -lapbs -lmaloc $(APBS_BLAS)

endif

RANLIB = ranlib
.SUFFIXES: .fcm .src .o
VPATH = fcm

ifdef GNU_F2C
FC := fort77 -O2 -w -malign-double -Nn6000 -Nx1000
LD := fort77 -O2 -w -malign-double
endif

# Compaq fort/ccc on Alpha Linux
ifdef COMPAQ_FORT
FC := fort -nocpp -fast $(I8DUM1)
LD := fort -nocpp -fast $(I8DUM1)
endif

ifdef GNU_G77
FFLAGS = -malign-double -fno-f2c -fno-backslash -O2 -fugly-complex -fno-globals -Wno-globals
#clbiii added to provide ~ 100% speed-up of g77 code over above options.
FFLAGS = -O6 -m486 -malign-double -ffast-math -fomit-frame-pointer -funroll-loops -funroll-all-loops -mcpu=pentiumpro -march=pentiumpro -ffloat-store -fforce-mem -frerun-cse-after-loop -fexpensive-optimizations -fugly-complex -fno-backslash -fno-globals -Wno-globals
#srb -O3 -malign-double -ffast-math -funroll-loops yields the best performance;
# -march= is absent because it does not seem to improve performance, its value
# is compiler version dependent, and what should it be athlon, pentium4 ?
# what code requires -fugly-complex -fno-backslash -fno-globals ?
FFLAGS = -O3 -ffast-math -funroll-loops -fugly-complex -fno-backslash -fno-globals -Wno-globals -ff90
DEFS   = -DGNU
FC := g77 $(FFLAGS) $(DEFS)
LD := g77 $(FFLAGS)
endif

# Absoft f77 v3.4
ifdef ABSOFT_F77_V34
FC := f77 -N9 -O -U -f
LD := f77 -N9 -O -U -f
endif

# pgi pgf77 3.0
ifdef PGI_F77
ifdef BIG_ENDIAN
ENDIAN:= -Mbyteswapio
endif
FC = pgf90 -O2 -Munroll -tp p6 -Mnoframe $(ENDIAN)
LD = pgf90 -O2 -Munroll -tp p6 -Mnoframe
endif

# Absoft  f77 4.4 (f90 v6.0):
# options: f lower case symbolic names, N3 include record length in unformatted
# files, N26 big endian unformatted files, B108 append underscore to external
# procedure names, B100 optimize for PentiumII, N86 optimize address expr.,
# U enable loop unrolling
#
ifdef ABSOFT_F77_V44
FC := f77 -f -N3 -N26 -B108 -O -U -B100 -N86
LD := f77 -O
ADDLIB := $(ADDLIB) -lU77
endif

# PathScale compiler for AMD-64
ifdef PATHSCALE
FC = pathf90 -i8
LD = pathf90 -i8
endif

# gfortran (replacement for g77)
ifdef GFORTRAN
ifdef X86_64
FC = gfortran -DGNU -fdefault-integer-8 -frecord-marker=4
LD = gfortran -DGNU -fdefault-integer-8 -frecord-marker=4
else
FC = gfortran -DGNU
LD = gfortran -DGNU
endif
endif

# AMD-64 g77 compiler
ifdef AMD64
FC = g77 -mcmodel=medium -ffast-math -funroll-loops -march=k8 -fno-globals -Wno-globals
LD = g77 -mcmodel=medium -ffast-math -funroll-loops -march=k8 -fno-globals -Wno-globals
endif

#---------------------------------------------------------------
#     *** IFC ***    IA-32 Intel Fortran Compiler.
#---------------------------------------------------------------
# -tpp7 -axW generates code for Pentium IV processors that will run on 
# other processor types.
ifdef INTEL32_IFC
  ifdef BIG_ENDIAN
    ENDIAN := -convert big_endian
  endif
  FC = ifort -O3 -tpp7 -132 -axW -w95 -cm -align all $(ENDIAN)
# -Vaxlib accesses the Intel Portability library which contains getarg, etc.
  LD = ifort -O3 -tpp7 -axW -static
  LDD = ifort -g -tpp7 -axW -static
  CC = icc -Dnographics -Dnographics -O -Dgnu -DLINUX $(I8DUM2)
endif

#---------------------------------------------------------------
#    *** EFC *** IA-64 Intel Fortran Compiler.
#---------------------------------------------------------------
# -tpp2 generates code for Itanium2 processors that will run on 
# other processor types.
# libPEPCF90 is the Intel Portability library which contains getarg, etc.
ifdef INTEL64_EFC
  ifdef BIG_ENDIAN
    ENDIAN := -convert big_endian
  endif
  CC = ecc -Dnographics -Dgnu $(I8DUM2)
# -ftz flushes denormal results to zero.
  FC = efc -tpp2 -ftz -132 -WB -w95 -cm $(I8DUM1) $(ENDIAN)
# -Vaxlib accesses the Intel Portability library which contains getarg, etc.
  LD = efc -Vaxlib -tpp2 -ftz $(I8DUM1)
  GLIB = 
  QLIB = 
  ADDLIB = 
  ADDLIB := $(ADDLIB) $(GLIB)
  ADDLIB := $(ADDLIB) -lPEPCF90
  CC = icc -Dnographics -Dnographics -O -Dgnu -DLINUX $(I8DUM2)
endif

#---------------------------------------------------------------
# *** IFORT *** Intel Fortran Compiler version 8 and above "
#---------------------------------------------------------------
#                  ifort" replaces ifc/efc.
# -tpp7 -axW generates code for Pentium IV processors that will run on 
# other processor types.
ifdef INTEL_IFORT
  ifdef BIG_ENDIAN
    ENDIAN := -convert big_endian
  endif
  FC = ifort -O3 -tpp7  -132 -axW -w95 -cm -align all $(ENDIAN)   $(I8DUM1) 
#  FC = ifort -O3 -tpp7  -132  -w95 -cm -align all $(ENDIAN)   $(I8DUM1) 
# -Vaxlib accesses the Intel Portability library which contains getarg, etc.
  LD = ifort -O3 -tpp7 -axW -static
  LDD = ifort -g -tpp7 -axW -static
  CC = icc -Dnographics -Dnographics -O -Dgnu -DLINUX $(I8DUM2)
endif

#---------------------------------------------------------------
# *** G95 *** Gnu g95 compiler
ifdef GNU_G95
  FC = g95
  LD = g95
endif

FC := $(FC) $(INCLUDE)

FC1 = $(FC) -c
FC2 = $(FC) -c
FC3 = $(FC) -c
FCR = $(FC) -c -O -K -V +R +T -u
FCD = $(FC) -c -g 
FCRD = $(FC) -c -g +T +R -V -w

ifdef PGI_F77
  FC0 = pgf90 -c $(ENDIAN) 
else
  ifdef ABSOFT_F77_V44
    FC0= f77 -f -N3 -N26 -B108 -c
  else
    ifdef  INTEL32_IFC_IFORT
      FC0 = $(FC) -c -O0
      FC1 = $(FC) -c -O1
      FC2 = $(FC) -c -O3
      FC3 = $(FC) -c -O3
      FCR = $(FC) -c -u -V
      FCD = $(FC) -c -g -O0 -u -traceback
#FCD = $(FC) -c -g -O0 -u -save -zero 
      FCRD = $(FC) -c -g -V -O0 -u -save -zero
    else
      ifdef  INTEL32_IFC_IFORT_I8
        FC0 = $(FC) -c -O0 -i8
        FC1 = $(FC) -c -O1 -i8
   	FC2 = $(FC) -c -O3 -i8
   	FC3 = $(FC) -c -O3 -i8
   	FCR = $(FC) -c -u -V -i8
   	FCD = $(FC) -c -g -O0 -u -traceback -i8
   	FCRD = $(FC) -c -g -V -O0 -u -save -zero -i8
   	LD = ifort -O3 -tpp7 -axW -static -i8
      else
        ifdef INTEL64_EFC
    	  FC0 = $(FC) -c -O0
    	  FC1 = $(FC) -c -O1
    	  FC2 = $(FC) -c -O2
    	  FC3 = $(FC) -c -O3
    	  FCR = $(FC) -c -u -V
    	  FCD = $(FC) -c -g -O0 -u -save -zero
    	  FCRD = $(FC) -c -g -V -O0 -u -save -zero
        else
          ifdef GNU_G95
     	    FC0 = $(FC) -c -O0
     	    FC1 = $(FC) -c -O1
     	    FC2 = $(FC) -c -O2
     	    FC3 = $(FC) -c -O3
     	    FCR = $(FC) -c -g 
     	    FCD = $(FC) -c -g -O0 
     	    FCRD = $(FC) -c -g -V -O0 
          else
            ifdef AMD64
      	      FC0 = $(FC) -c -O0
      	      FC1 = $(FC) -c -O1
      	      FC2 = $(FC) -c -O2
      	      FC3 = $(FC) -c -O3
      	      FCR = $(FC) -c -g 
      	      FCD = $(FC) -c -g -O0 
      	      FCRD = $(FC) -c -g -V -O0 
            else
              ifdef PATHSCALE
       		FC0 = $(FC) -c -O0
       		FC1 = $(FC) -c -O1
       		FC2 = $(FC) -c -O2
       		FC3 = $(FC) -c -O3
       		FCR = $(FC) -c -g 
       		FCD = $(FC) -c -g -O0 
       		FCRD = $(FC) -c -g -V -O0 
              else
                ifdef GFORTRAN
                  FC0 = $(FC) -c -O0
                  FC1 = $(FC) -c -O1
                  FC2 = $(FC) -c -O2
                  FC3 = $(FC) -c -O3
                  FCR = $(FC) -c -g 
                  FCD = $(FC) -c -g -O0 
                  FCRD = $(FC) -c -g -V -O0 
                else
                  FC0 = $(FC) -c -finit-local-zero -fno-automatic
                endif
              endif
            endif
          endif
        endif
      endif
    endif
  endif
endif

ifdef DEBUG
  FC0 = $(FCD) -ftrapuv -check bounds
  FC1 = $(FCD) -ftrapuv -check bounds
  FC2 = $(FCD) -ftrapuv -check bounds
  FC3 = $(FCD) -ftrapuv -check bounds
  LD  = $(LDD) -ftrapuv -check bounds
endif

OBJS = \
        $(LIB)/charmm_main.o \
        $(LIB)/help.o \
        $(LIB)/iniall.o \
        $(LIB)/miscom.o \
        $(LIB)/usersb.o
LIBS = \
	$(LIB)/adumb.a \
	$(LIB)/cadint.a \
	$(LIB)/cff.a \
	$(LIB)/correl.a \
	$(LIB)/dimb.a \
	$(LIB)/dynamc.a \
	$(LIB)/energy.a \
	$(LIB)/gamint.a \
	$(LIB)/gukint.a \
	$(LIB)/gener.a \
	$(LIB)/graphics.a \
	$(LIB)/image.a \
	$(LIB)/io.a \
	$(LIB)/machdep.a \
	$(LIB)/manip.a \
	$(LIB)/mbond.a \
	$(LIB)/mc.a \
	$(LIB)/minmiz.a \
	$(LIB)/misc.a \
	$(LIB)/mmff.a \
	$(LIB)/moldyn.a \
	$(LIB)/molvib.a \
	$(LIB)/nbonds.a \
	$(LIB)/pert.a \
	$(LIB)/quantum.a \
	$(LIB)/rxncor.a \
	$(LIB)/shapes.a \
	$(LIB)/solvation.a \
	$(LIB)/util.a \
	$(LIB)/vibran.a

$(EXEC)/charmm : $(LIBS) $(OBJS)
	$(LD) -o charmm.exe $(LIB)/*.o $(LIBS) $(LIBS) $(LIBS) $(ADDLIB) $(QLIB) $(MSGLIB)
