#!/bin/csh -f
#**************************************************************
# MKMK (Makefile maker)
#**************************************************************
set Version = "Version 2.0"
set Date    = "September-23-2010"
set Author  = "Seongjai Kim, skim@math.msstate.edu"

#set echo

@ link = 1
@ iopt = 1
@ message = 0
set HDRINC =

if ( $#argv > 0 ) then
   foreach i ( $* )
      set ic = ( `echo $i | sed -e 's/=.*//' | tr A-Z a-z` )
      if ( "$i" == "-l" || "$i" == "-link" ) then
         @ link = 0
      else if ( "$i" == "-o" || "$i" == "-opt" ) then
         @ iopt = 0
      else if ( "$i" == "-lo" || "$i" == "-ol" ) then
         @ link = 0 ; @ iopt = 0
      else if ( "$i" == "h"  || "$i" == "help" || \
                "$i" == "-h" || "$i" == "-help" ) then
         goto PRINTMESSAGE
      else if ( "$ic" == "h" || "$ic" == "head" || "$ic" == "header" ) then
         set HC = ( `echo $i | sed -e 's/.*=//' | sed -e 's/\,/\ /'` )
         foreach tmp ( $HC )
            if ( -e $tmp ) then
               set HDRINC = ( $HDRINC $tmp )
            endif
         end
      endif
   end
endif

#=========================================
#  Basic Setting
#=========================================

set MAKEFILE = 'Makefile'
echo "MKMK - Automatic Makefile Maker"
echo "$Version; $Author; $Date"
echo "\
PWD=`pwd`"

if ( $?OSTYPE == 0 ) then
   echo "OSTYPE is not defined; uname will be used."
   set OSTYPE = ( `uname -s | tr '[A-Z]' '[a-z]' | sed -e s/-//` )
else if ( "$OSTYPE" == "unknown" ) then
   echo "OSTYPE=$OSTYPE; uname will be used."
   set OSTYPE = ( `uname -s | tr '[A-Z]' '[a-z]' | sed -e s/-//` )
else
   echo '$OSTYPE=' "$OSTYPE"
endif

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

set LNXRELEASE =
if ( "$OSTYPE" == "linux" ) then
    if ( "`uname -r | grep FC4`" != "" ) then
        set LNXRELEASE = FC4
    else
        set LNXRELEASE = PRE
    endif
endif
  
##--------------------------------------------------

echo ""

if ( "$OSTYPE" == "solaris" ) then
   set optE =
else if ( "$OSTYPE" == "sunos" || "$OSTYPE" == "sunos4" ) then
   set optE =
else
   set optE = '-e'
endif

set CC  = 'gcc'
set CPP = 'g++'
set F77 = 'g77'
set F90 = 'f95'

#if ( "$OSTYPE" == "solaris" ) then
#   set CC   = 'cc'
#   set CPP  = 'CC'
#endif

#----default optimization flags----
set OPTC   = '-O'
set OPTCPP = '-O'
set OPTF   = '-O'
set OPTF90 = '-O'
set LNK_LIB = '-lcl -lm'

#=========================================
#  Analyzing the files
#=========================================

set cppfiles = ( '*.cpp' '*.c++' '*.cc' '*.C' )
set f90files = ( '*.f90' '*.f95' '*.F' )
set ccfiles  = ( '*.c' )
set f77files = ( '*.f *.for' )
set hfile =    ( '*.h' )

glob "C++ files... "; @ ncpp = `ls $cppfiles | wc -w`
   if ( $ncpp != 0 ) echo ''
glob "F90 files... "; @ nf90 = `ls $f90files | wc -w`
   if ( $nf90 != 0 ) echo ''
glob "C   files... "; @ ncc  = `ls $ccfiles  | wc -w`
   if ( $ncc != 0 ) echo ''
glob "F77 files... "; @ nf77 = `ls $f77files | wc -w`
   if ( $nf77 != 0 ) echo ''
glob "H   files... "; @ nhead = `ls $hfile | wc -w`
   if ( $nhead != 0 ) echo ''

set srcfiles = ( $cppfiles $ccfiles $f90files $f77files )
@ nsrc = `ls $srcfiles | wc -w`

if ( $nsrc == 0 ) then
   echo '======= No FORTRAN or C files. ======='
   exit
endif
@ ncccc = `expr $ncpp + $ncc`
@ nffff = `expr $nf90 + $nf77`
echo "\
   $ncccc  C file(s)\
   $nffff  FORTRAN file(s)\
   $nhead  HEADER file(s) found"

@ idcomp = 1
if ( $ncc  != 0 ) then
   if ( "`grep $optE 'main()' $ccfiles`" != "" ) @ idcomp = 2
endif
if ( $nf90 != 0 ) @ idcomp = 3
if ( $ncpp != 0 ) @ idcomp = 4

#=========================================
# Parameter specification
#=========================================

set INC_C =
set INC_CPP =
set INC_F =
set INC_F90 =

if ( "$OSTYPE" == "linux" ) then
   set OPTC   = '-O2'
   set OPTCPP = '-O2'
   set OPTF   = '-O2'
   set OPTF90 = '-O2'
   if ( "$LNXRELEASE" == "FC4" ) then
       set LNK_LIB = '-lm -lgcc -lc -lgfortran -L/usr/lib/gcc/i386-redhat-linux/4.0.0'
   else
       set LNK_LIB = '-lm -lgcc -lc -lgfortran -L/usr/lib/gcc/i386-redhat-linux/4.0.0'
#       set LNK_LIB = '-lg2c -lm -lgcc -lc'
   endif
else if ( "$OSTYPE" == "hpux" ) then
   set OPTC   = '-O3'
   set OPTCPP = '-O3'
   set OPTF   = '+O4 +U77'
   set OPTF90 = '+O3 +U77'
   set LNK_LIB = '-lcl -lm'
else if ( "$OSTYPE" == "bsdi" || "$OSTYPE" == "bsd/os" ) then
   set OPTC   = '-O3'
   set OPTCPP = '-O3'
   set OPTF   = '-O'
   set OPTF90 = '-O'
   set LNK_LIB = '-lm'
else if ( "$OSTYPE" == "aix" ) then
   set OPTC   = '-O3'
   set OPTCPP = '-O3'
   set OPTF   = '-O4'
   set OPTF90 = '-O4'
   set LNK_LIB = '-L/lib -lxlf90 -lxlf -lm -lc'
else if ( "$OSTYPE" == "solaris" ) then
   set OPTC   = '-O3'
   set OPTCPP = '-O3'
   set OPTF   = '-O3'
   set OPTF90 = '-O3'
   set LNK_LIB = '-lm -L/opt/SUNWspro/SC4.2/lib -L/usr/local/SUNWspro/WS6/lib -lg2c -lsunmath'
else if ( "$OSTYPE" == "sunos" || "$OSTYPE" == "sunos4" ) then
   set LNK_LIB = '-lm -L/opt/SUNWspro/SC4.0/lib -L/usr/local/SUNWspro/WS6/lib -lg2c -lsunmath'
   set INC_CPP = '-I/opt/SUNWspro/SC4.0/include/CC'
else
   echo "Set the optimization parameters in mkmk."
endif

if ( "$iopt" == "0" ) then
   set OPTC =; set OPTCPP =; set OPTF =; set OPTF90 =
   if ( "$OSTYPE" == "hpux" ) then
      set OPTF = '+U77'; set OPTF90 = '+U77'
   endif
endif

if ( "$link" == "0" ) then
   set LNK_LIB =
endif

# ===== check if "f77" is installed.
set NOF77 = "`which f77 | grep not`"
if ( "$NOF77" != "" ) then
   if ( "$LNXRELEASE" == "FC4" ) then
      set F77  = 'f95'
   else
       set F77 = 'f95'
   endif
   set OPTF    = "`echo $OPTF | sed 's/\+/\-/g'`"
   set OPTF90  = "`echo $OPTF90 | sed 's/\+/\-/g'`"
endif


# ===== object file =====
set SOURCES = ''
set OBJECTS = ''

foreach src ( $srcfiles )
   set SOURCES = ( $SOURCES $src )
   set OBJECTS = ( $OBJECTS $src:r.o )
end

# ===== header files =======
#doing
if ( $nhead > 0 ) then
   set HEADERS = $hfile
   if ( "$HDRINC" == "" ) then
      foreach h ( $HEADERS )
         set tmp = ( `grep $h $SOURCES | grep 'include' | sed -e 's/:.*//'` )
         if ( "$tmp" != "" ) then
            foreach i ( $tmp )
               @ again = 0
               foreach j ( $HDRINC )
                  if ( "$i" == "$j" ) @ again = 1
               end
               if ( $again == 0 && -e $i ) set HDRINC = ( $HDRINC $i )
            end
         endif
      end
      if ( "$HDRINC" != "" ) then
         echo ""
         echo "HEADER file(s): used in <$HDRINC>"
      endif
      # @ message = 1
   endif
else
   set HEADERS =
   set HDRINC =
endif

#=========================================
#=========================================
# Making makefile
#=========================================
#=========================================

if ( -e $MAKEFILE ) then
     mv -f $MAKEFILE $MAKEFILE.bak
     echo ""
     echo "Old ${MAKEFILE}: moved to $MAKEFILE.bak."
endif

# ===== heading for Makefile =====

echo "# $MAKEFILE - generated by mkmk, $Version\
# Author = $Author\
# `date '+%a %h %d, 20%y  %r'`" >! $MAKEFILE
echo "#----------------------------------------------\
# Define macros used for compiling and linking \
#----------------------------------------------" >> $MAKEFILE

echo "\
CC  = $CC\
CPP = $CPP\
F77 = $F77\
F90 = $F90" >> $MAKEFILE

echo "\
#OSTYPE=$OSTYPE\
#---------------\
OPTC  = $OPTC\
OPTCPP= $OPTCPP\
OPTF  = $OPTF\
OPTF90= $OPTF90" >> $MAKEFILE

echo "\
BLASDEF =\
#BLASDEF = -DUSE_VENDOR_BLAS" >> $MAKEFILE

echo "\
INC_CPP = $INC_CPP\
INC_C   = $INC_C\
INC_F90 = $INC_F90\
INC_F   = $INC_F\
LNK_LIB = $LNK_LIB" >> $MAKEFILE

echo "\
#C preprocessor defs (-DNoChange, -DAdd_, or -DUpCase)\
CDEFS =\
#CDEFS = -DNoChange" >> $MAKEFILE

echo '\
PREFLAGS= $(CDEFS) $(BLASDEF)\
CFLAGS  = $(OPTC) $(PREFLAGS)\
CPPFLAGS= $(OPTCPP) $(PREFLAGS)\
FFLAGS  = $(OPTF) $(PREFLAGS)\
F90FLAGS= $(OPTF90) $(PREFLAGS)\
' >> $MAKEFILE

if ( $idcomp == 1 ) then
    echo '#Main=FORTRAN' >> $MAKEFILE
    echo '#---------------' >> $MAKEFILE
    echo 'COMP = $(F77)' >> $MAKEFILE
    echo 'FLAG = $(FFLAGS)' >> $MAKEFILE
else if ( $idcomp == 2 ) then
    echo '#Main=C' >> $MAKEFILE
    echo '#---------------' >> $MAKEFILE
    echo 'COMP = $(CC)' >> $MAKEFILE
    echo 'FLAG = $(CFLAGS)' >> $MAKEFILE
else if ( $idcomp == 3 ) then
    echo '#Main=F90' >> $MAKEFILE
    echo '#---------------' >> $MAKEFILE
    echo 'COMP = $(F90)' >> $MAKEFILE
    echo 'FLAG = $(F90FLAGS)' >> $MAKEFILE
else if ( $idcomp == 4 ) then
    echo '#Main=C++' >> $MAKEFILE
    echo '#---------------' >> $MAKEFILE
    echo 'COMP = $(CPP)' >> $MAKEFILE
    echo 'FLAG = $(CPPFLAGS)' >> $MAKEFILE
endif

echo '\
MYINC =\
MYLIB =\
#MYINC = -I$(HOME)/c++/include\
#MYLIB = -L$(HOME)/c++/lib' >> $MAKEFILE

echo "\
#----------------------------------------------\
\
SRCS = $SOURCES\
\
OBJS = $OBJECTS\
\
HDRS = $HEADERS" >> $MAKEFILE

# ===== the last part of MAKEFILE =============
echo '\
#----------------------------------------------\
# Things to make                               \
#----------------------------------------------' >> $MAKEFILE

echo '\
xx yy zz: $(OBJS) $(SRCS) Makefile\
	$(COMP) -o $@ $(FLAG) $(OBJS) $(MYLIB) $(LNK_LIB)' >> $MAKEFILE

echo '\
debug:\
	$(COMP) -g -c $(SRCS)\
	$(COMP) -g -o xx $(OBJS) $(MYLIB) $(LNK_LIB)' >> $MAKEFILE

echo '\
clean clear:\
	/bin/rm -f core *.trace *.bak *.o a.out xx yy zz\
sep ps numerical out:\
	/bin/rm -f core *.trace *.bak *.sep* *.ps fort.* pic.made\
bak rmbak:\
	/bin/rm -f *.bak' >> $MAKEFILE

echo '\
#-------------------------------------------------\
\
.SUFFIXES : .o .a .c .C .cc .cpp .cxx .f .for .F .f90 .f95 \
\
.C.o .cc.o .cpp.o .cxx.o: \
	$(CPP) -c $(INC_CPP) $(CPPFLAGS) $(MYINC) $< \
.c.o: \
	$(CC) -c $(INC_C) $(CFLAGS) $(MYINC) $< \
.F.o .f90.o .f95.o: \
	$(F90) -c $(INC_F90) $(F90FLAGS) $< \
.f.o .for.o: \
	$(F77) -c $(INC_F) $(FFLAGS) $< \
' >> $MAKEFILE

#---------------------------------------
# Header File Dependence
#---------------------------------------

if ( "$HDRINC" != "" ) then
   foreach src ( $HDRINC )
      set HDR =
      if ( $nhead > 0 ) then
         foreach h ( $HEADERS )
            set tmp = ( `grep $h $src | grep $optE include` )
            if ( "$tmp" != "" ) then
               set HDR = ( $HDR $h )
            endif
         end
      endif

      if ( "$HDR" != "" ) then
         set obj = $src:r.o
         set ext = $src:e
         echo "" >> $MAKEFILE
         echo "${obj}: $src $HDR" >> $MAKEFILE

         if ( "$ext" == "C" || "$ext" == "cc" ||\
               "$ext" == "cpp" || "$ext" == "c++" ) then
            echo '	$(CPP) -c $(INC_CPP) $(CPPFLAGS) $(MYINC)' $src >> $MAKEFILE
         else if ( "$ext" == "c" ) then
            echo '	$(CC)  -c $(INC_C) $(CFLAGS) $(MYINC)' $src >> $MAKEFILE
         else if ( "$ext" == "F" || "$ext" == "f90" || "$ext" == "f95" ) then
            echo '	$(F90) -c $(INC_F90) $(F90FLAGS)' $src >> $MAKEFILE
         else if ( "$ext" == "f" ) then
            echo '	$(F77) -c $(INC_F) $(FFLAGS)' $src >> $MAKEFILE
         endif
      endif
   end
endif

#---------------------------------------
# Print out
#---------------------------------------

echo "\
[1;7mOUTPUT[m = $cwd/$MAKEFILE\
**** you may have to customize MYINC, MYLIB, & LNK_LIB ****"

if( $message == 0 ) then
   exit
endif

PRINTMESSAGE:
echo "\
 MKMK - Automatic Makefile Maker\
 $Version; $Author; $Date\
\
 Usage: mkmk [Options]\
\
 Options:\
    -o[pt]              to set the optimization parameter empty\
    -l[ink]             to set the link parameter empty\
    -h[elp]             to get this message printed out\
    h|header=a.cpp,b.c  to specify the routines including header files\
                        mkmk will try to find them when not set\
"
