# $Id: common,v 1.203.1.29 1998/04/30 01:10:54 balay Exp $ 
#
# LDIR (defined from $PETSC_DIR) determines the libraries that are linked.
# PDIR (defined from $PETSC_DIR) determines where the libraries are built.
# LDIR and PDIR will usually be identical.
# LIBNAME       - library name
# SOURCE        - source files
# SSOURCE       - single precision versions of some source code
# OBJS          - object files
# SOBJS         - single precision versions of some object files
# PETSC_INCLUDE - locations of include files
# CPPFLAGS      - preprocessor flags for *.c, *.F preprocessing
# DOCS          - files that contain PETSc documentation, readmes etc.
# PETSC_PARCH   - corresponds to the PARCH_arch in the source files, set in 
#                 the file bmake/${PETSC_ARCH}/base
#
KERNEL_LIB    = 

LDIR	      = ${PETSC_DIR}/lib/lib${BOPT}/${PETSC_ARCH}
PDIR	      = ${PETSC_DIR}/lib/lib${BOPT}/${PETSC_ARCH}
LIBNAME	      = ${PDIR}/${LIBBASE}.a
SOURCE	      = ${SOURCEC} ${SOURCEF}
OBJS	      = ${OBJSC} ${OBJSF}
PETSC_INCLUDE = -I${PETSC_DIR} -I${PETSC_DIR}/include ${MPI_INCLUDE} ${MPE_INCLUDE}  \
                -I${PETSC_DIR}/bmake/${PETSC_ARCH}
CPPFLAGS      = ${PETSC_INCLUDE} ${PCONF} ${PETSCFLAGS} ${PETSC_PARCH} 

#
# Defines all libraries needed for using linear and nonlinear solvers, 
# and all lower level PETSc components (such as vectors and matrices).
# The order of listing these libraries is important!
#
PETSC_LIB   = -L${LDIR} -lpetscts -lpetscsnes  -lpetscsles \
		-lpetscmat -lpetscvec -lpetscmat -lpetscvec -lpetscsys  \
		${EXTERNAL_LIB} ${KERNEL_LIB} ${LAPACK_LIB} ${BLAS_LIB} \
		${MPE_LIB} ${MPI_LIB} ${X11_LIB} ${FC_LIB} ${SYS_LIB} -lm
#
# Defines all libraries needed for using linear solvers and all lower
# level PETSc components (such as vectors and matrices).  The order
# of listing these libraries is important!
#
SLES_LIB    =	-L${LDIR} -lpetscsles -lpetscmat -lpetscvec -lpetscmat -lpetscvec -lpetscsys \
		${EXTERNAL_LIB}  ${KERNEL_LIB} ${LAPACK_LIB} ${BLAS_LIB}\
		${MPE_LIB} ${MPI_LIB} ${X11_LIB} ${FC_LIB} ${SYS_LIB} -lm
#
#   Library if you are using the GVec component of PETSc
#
GVEC_LIB   = -L${LDIR} -lpetscgvec  -lpetscts -lpetscsnes  -lpetscsles \
		-lpetscmat  -lpetscvec -lpetscmat -lpetscsys  \
		 ${EXTERNAL_LIB} ${KERNEL_LIB} ${LAPACK_LIB} ${BLAS_LIB} \
		${MPE_LIB} ${MPI_LIB} ${X11_LIB} ${FC_LIB} ${SYS_LIB} -lm
#
#   Currently ignore this entry
#
PETSC_ADIC_LIB  = -L${LDIR} -lpetscsnes -lpetscsles \
		  -lpetscmat -lpetscvec -lpetscsys \
                  -lpetscblas -lmpiuni  ${EXTERNAL_LIB}  ${LAPACK_LIB} \
                  ${BLAS_LIB} ${X11_LIB} \
		  ${FC_LIB} ${SYS_LIB} -lm
#
# Link if you are using the PETSc Fortran interface.
#
PETSC_FORTRAN_LIB = -L${LDIR} -lpetscfortran
#
# Link if you are using code from the contributed part of PETSc
#
PETSC_CONTRIB = -L${LDIR} -lpetsccontrib
#
# These include files set customized site, optimization, and version options.
# Do NOT remove any of these include files.  You should generally have to edit
# only ${PETSC_DIR}/bmake/${PETSC_ARCH}/base.site for your particular
# machine configuration.  See the users manual for details.
#
include ${PETSC_DIR}/bmake/${PETSC_ARCH}/base.site
# (This line MUST be present for certain machines (e.g., Cray T3D))
include ${PETSC_DIR}/bmake/${PETSC_ARCH}/base.${BOPT}

# Checks that PETSC_DIR variable is set and creates library directory
# if it does not exist
chkpetsc_dir:
	@if [ ${BOPT}foo = foo ] ; then \
	  echo "You must set the variable BOPT=[g,O,Opg,O_c++,O_complex,...]" ; \
          echo "Remove all .o files and rerun make with appropriate BOPT"; false; fi
	-@if [ ! -d ${PDIR} ]; then \
	  echo Making directory ${PDIR} for library; mkdir -p ${PDIR} ; fi

# 1. Checks that user has set BOPT variable
# 2. Check if the ${LDIR} exists
chkopts_basic: 
	@if [ ${BOPT}foo = foo ] ; then \
	  echo "You must set the variable BOPT=[g,O,Opg,O_c++,O_complex,...]" ; \
          echo "Remove all .o files and rerun make with appropriate BOPT"; false; fi
	@if [ ! -d ${LDIR} ]; then \
	  echo Libraries not built for this BOPT: ${BOPT}; false ; fi

# 3. Check if the shared libs are out of date
chkopts: chkopts_basic
	@for LIBNAME in  ${SHLIBS} ; do  \
	if [ -f ${LDIR}/$$LIBNAME.a ];	then \
	if [ -f ${LDIR}/$$LIBNAME.${SLSUFFIX} ]; then \
	flag=`find ${LDIR} -type f -name $$LIBNAME.a -newer ${LDIR}/$$LIBNAME.${SLSUFFIX} -print` ;\
	if [ "$$flag" != "" ]; then \
	echo "Shared libs in ${LDIR} are out of date, attempting to rebuild." ;\
	if [ -w ${LDIR} ]; then \
	${OMAKE} BOPT=${BOPT} PETSC_ARCH=${PETSC_ARCH} shared ;\
	else \
	echo "Unable to rebuild shared libraries, you do not have write permission." ;\
	user=`ls -l ${LDIR}/$$LIBNAME.${SLSUFFIX}  | tr -s '' ' ' | cut -d ' ' -f 3` ;\
	echo "Libraries were built by user $$user, please contact him/her to have them rebuilt." ;\
	false ;\
	fi ;\
	fi ;\
	fi ;\
	fi ;\
	done


# Does nothing; need for some rules that require actions.
foo:

# Builds library
lib: chkpetsc_dir ${SOURCE}
	@-if [ "${SOURCEC}" != "" ] ; then \
	   ${OMAKE} -f makefile PETSC_ARCH=${PETSC_ARCH} BOPT=${BOPT} libc; fi
	@-if [ "${SOURCEF}" != "" ] ; then \
		${OMAKE} -f makefile PETSC_ARCH=${PETSC_ARCH} BOPT=${BOPT} libf; fi
	@-if [ "${OBJS}" != " " ] ; then \
		${RANLIB}  ${LIBNAME}; \
		${RM} -f ${OBJS}; \
	fi
#
#  Does not work for some machines with .F fortran files.
#
# Builds library - fast version
libfast: chkpetsc_dir ${SOURCEC} ${SOURCEF}
	@-if [ "${SOURCEC}" != "" ] ; then \
	     ${CC} -c ${CFLAGS} ${COPTFLAGS} ${SOURCEC} ${SSOURCE} ;\
	fi
	-@if [ "${SOURCEF}" != "" ] ; then \
	     ${FC} -c ${FFLAGS} ${FOPTFLAGS} ${CFLAGS} ${SOURCEF} ;\
	fi
	@-if [ "${OBJS}" != " " ] ; then \
	  ${AR} cr ${LIBNAME} ${OBJS} ${SOBJS}; \
	  ${RM} -f ${OBJS} ${SOBJS}; \
	fi

# Removes garbage files
clean:
	@-${RM} -f *.o *~ ex[0-9] ex[0-9][0-9] ex[0-9]f ex[0-9][0-9]f \
	       ${CLEANFILES} ${TESTS} ex[0-9]f90 ex[0-9][0-9]f90 \
	       PI* *.ln l.outa* mputil.mp_* core *.tmp *.map *.log gmon.out \
	       trashz \#*\# *.mex* *.stolen *.trace Log.* joe jeff *.stolen \
	       output/*~ .mpirtmp mon.out *.aus *.mon.* __* p4pg ins10*.c \
	       ex[0-9].exe ex[0-9][0-9].exe ex[0-9]f.exe ex[0-9][0-9]f.exe \
	       *.ad.c *.ad.h ad_deriv.h .adic* *.cp_ *.cp__ \
               .adic* *.dep *.proj ctoatmp PETScArena* *.L *.anl

cleanstolen:
	@-${RM} -f *.stolen

cleanadic:
	@-${RM} -f *.ad.*
#
#  testexamples_X - Runs various PETSc test suites
#    1 - basic C suite used in installation tests
#    2 - additional C suite including graphics
#    3 - basic Fortran .F suite
#    4 - uniprocessor version of 1 and 2
#    5 - C examples that require complex numbers
#    6 - C examples that don't work with complex numbers 
#    7 - C examples that require BlockSolve
#    8 - Fortran .F examples that don't work with complex numbers
#    9 - uniprocessor version of 3
#   10 - Fortran examples that require complex
#   11 - uniprocessor version of 5
#   12 - basic f90 examples
#
testexamples_1: ${TESTEXAMPLES_1}
testexamples_2: ${TESTEXAMPLES_2}
testexamples_3: ${TESTEXAMPLES_3}
testexamples_4: ${TESTEXAMPLES_4}
testexamples_5: ${TESTEXAMPLES_5}
testexamples_6: ${TESTEXAMPLES_6}
testexamples_7: ${TESTEXAMPLES_7}
testexamples_8: ${TESTEXAMPLES_8}
testexamples_9: ${TESTEXAMPLES_9}
testexamples_10: ${TESTEXAMPLES_10}
testexamples_11: ${TESTEXAMPLES_11}
testexamples_12: ${TESTEXAMPLES_12}
buildexamples_1: ${BUILDEXAMPLES_1}
buildexamples_2: ${BUILDEXAMPLES_2}
buildexamples_3: ${BUILDEXAMPLES_3}
buildexamples_4: ${BUILDEXAMPLES_4}
buildexamples_5: ${BUILDEXAMPLES_5}
buildexamples_6: ${BUILDEXAMPLES_6}
buildexamples_7: ${BUILDEXAMPLES_7}
buildexamples_8: ${BUILDEXAMPLES_8}
buildexamples_9: ${BUILDEXAMPLES_9}
buildexamples_10: ${BUILDEXAMPLES_10}
buildexamples_11: ${BUILDEXAMPLES_11}
buildexamples_12: ${BUILDEXAMPLES_12}

# Performs the specified action throughout the directory tree
tree: ${ACTION}
	@-if [ "${DIRS}" != "" ]; then \
	for dir in ${DIRS} foo ; do if [ -d $$dir ]; then \
	(cd $$dir ; echo ${ACTION} in: `pwd`; \
	${OMAKE} -f makefile tree ACTION=${ACTION} BOPT=${BOPT} \
	PETSC_ARCH=${PETSC_ARCH}  ) ;fi; \
	done ; fi

# --------------------------------------------------------------------
#
# All remaining actions are intended for PETSc developers only.
# PETSc users should not generally need to use these commands.
#
chkpetsc_path:
	-@petsc_path=`pwd`; \
	mod_path=`echo $$petsc_path | sed 's/bsmith\/petsc//g'`; \
	if [ $$mod_path = $$petsc_path ] ; then \
	  echo 'Error! Wrong PETSc Dir! Please use /home/bsmith/petsc'; \
	   false; \
	fi

# RCS file check-in
ci: chkpetsc_path
	@-/usr/local/bin/ci -u -q -mAutoCheckin ${SOURCEH} ${DOCS} ${SOURCE} \
	  ${EXAMPLESC} ${EXAMPLESF} ${TESTSC} ${TESTSF} makefile

# RCS file check-out
co: chkpetsc_path
	@-/usr/local/bin/co -l -q ${SOURCEH} ${DOCS} ${SOURCE} makefile ${EXAMPLESC}\
	  ${EXAMPLESF} ${TESTSC} ${TESTSF}

# Uses lint; true is to prevent make error message from empty grep
lint:
	@-if [ "${SOURCEC}" != "" ] ; then \
	   lint -cvhu -DLINT -DPETSC_ARCH_${PETSC_ARCH} ${CFLAGS} ${SOURCEC}\
		| grep -v "never defined"\
		| grep -v "pointer alignment problem" | grep -v\
		"function prototype not in scope"; true ;\
	   ${RM} -f *.ln ; fi

# Builds Fortran-77 wrappers
fortranstubs:
	@-/home/petsc/bin/sun4/bfort -dir /home/bsmith/petsc/src/fortran/auto \
	  -mnative -ansi -nomsgs -anyname -mapptr -mpi -ferr -ptrprefix Petsc\
	  -ptr64 USE_POINTER_CONVERSION  -fcaps HAVE_FORTRAN_CAPS \
          -fuscore HAVE_FORTRAN_UNDERSCORE ${SOURCEC}
fixfortran:
	@echo "Fixing pointers in src/fortran/auto"
	-@for FILENAME in ${SOURCEC} ; do \
	cat $$FILENAME | \
	sed "s/PetscToPointer(int)/PetscToPointer(void *)/" | \
	sed "s/PetscRmPointer(int)/PetscRmPointer(void *)/" | \
	sed "s/PetscToPointer(a) (a)/PetscToPointer(a) (*(long *)(a))/" | \
	sed "s/PetscFromPointer(a) (int)(a)/PetscFromPointer(a) (long)(a)/" | \
	sed "s/PetscToPointer( \*(int\*)/PetscToPointer( /" >_$$FILENAME; \
	/bin/mv _$$FILENAME $$FILENAME ;\
	done



# Builds man pages (LaTeX version)
latexpages:
	@-if [ "${MANSEC}" != "" ] ; then \
	/home/gropp/bin/sun4/doc2lt	\
	  ${SOURCEC} ${SOURCEH} >> \
		    ${PETSC_DIR}/docs/tex/rsum/rsum${MANSEC}.tex ; fi 

# Builds man pages (HTML version) in two stages
# See rule for allwwwpages in ${PETSC_DIR}/makefile 
#   1.) wwwpages_buildcite: builds the file manualpages.cit for hyperlinks
#   2.) wwwpages: builds the html pages, complete with hyperlinks
manualpages_buildcite:
	@-if [ "${MANSEC}" != "" ] ; then \
	/home/gropp/bin/sun4/doctext -html -indexdir ../man${MANSEC} \
		-index ${PETSC_DIR}/docs/manualpages/manualpages.cit \
		-mpath ${PETSC_DIR}/docs/manualpages/man${MANSEC} ${SOURCEC} ${SOURCEH}; \
#
#   You should have DOCTEXT_PATH point to /home/bsmith/petsc/docs/tex/doctext
#
manualpages:
	@-if [ "${MANSEC}" != "" ] ; then \
	/home/gropp/bin/sun4/doctext -html \
		-mpath ${PETSC_DIR}/docs/manualpages/man${MANSEC} -heading PETSc \
		-locdir ${LOCDIR} -mapref ${PETSC_DIR}/docs/manualpages/manualpages.cit \
		-defn ${PETSC_DIR}/docs/manualpages/sec/eop.${MANSEC} \
		${SOURCEC} ${SOURCEH}; \


#.PRECIOUS: ${PRECIOUS} ${LIBNAME}
.SUFFIXES: .F ${SUFFIXES} .PETSc .C .cc .cpp .r .rm .so

.c.a:
	-${CC} -c ${CFLAGS} ${COPTFLAGS}  $<
	-${AR} cr ${LIBNAME} $*.o
	-${RM} $*.o
.c.o: 
	-${CC} -c ${CFLAGS} ${COPTFLAGS}  $<
.cpp.a .cc.a .C.a: 
	-${CC} -c ${CFLAGS} ${COPTFLAGS} $<
	-${AR} cr ${LIBNAME} $*.o
	-${RM} $*.o
.cpp.o .cc.o .C.o: 
	-${CC} -c ${CFLAGS} ${COPTFLAGS} $<

.f.o: 
	-${FC} -c ${FFLAGS} ${FOPTFLAGS}  ${CPPFLAGS} $<
.f.a: 
	-${FC} -c ${FFLAGS} ${FOPTFLAGS}  ${CPPFLAGS} $<
	-${AR} cr ${LIBNAME} $*.o
	-${RM} $*.o

#
#  These rules are for compiling the test examples.
#
.cpp.rm .cc.rm .C.rm .F.rm .f.rm .c.rm:
	-@${RM} -f $* *.o $*.mon.* gmon.out mon.out
.c.PETSc:
	-@${OMAKE} -f makefile PETSC_ARCH=${PETSC_ARCH} BOPT=${BOPT} $* > trashz 2>&1
	-@grep -v clog trashz | grep -v "information sections" | \
          grep -v "WARNING: TOC" | \
          grep -v "Extra instructions" | \
          grep -v "symbol if the" | \
          grep -v "preempts that definition" | \
          grep -v EXTERNAL  |\
          grep -v volatile  |\
          grep -v -i inconsistent | \
	  egrep -i '(Error|warning|Can|Unresolved)' >> /dev/null;\
	  if [ "$$?" != 1 ]; then \
	  cat trashz ; fi; ${RM} trashz
.F.PETSc:
	-@${OMAKE} -f makefile PETSC_ARCH=${PETSC_ARCH} BOPT=${BOPT} $* > trashz 2>&1
	-@grep -v EXTERNAL trashz | grep -v Wall | \
          grep -v "Unused external reference" | \
          grep -v "WARNING: TOC overflow." | \
          grep -v "Extra instructions are being" | \
          grep -v "symbol if the symbol" | \
          grep -v -i inconsistent | \
          grep -v -i "unused dummy" | \
	  grep -v "WARNING:  -cpp is ignored" | \
	  grep -v "Unused external reference" | \
          grep -v 'continuing despite warning messages' | \
	  grep -v "Unused dummy argument" | \
	  egrep -i '(Error|warning|Can|Unresolved)'  >> /dev/null ; \
	  if [ "$$?" != 1 ]; then \
	  cat trashz ; fi; ${RM} trashz;
# -------------------------------------------------------------------------------
#
#   Rule for generating ADIC derivatives from PETSc .c and .hfiles
#
adic:
	@-if [ "${NOADIC}" != "true" ]; then if [ "${SOURCEC}" != "" ]; then \
          for i in ${SOURCEC} foo; do if [ -f $$i ]; then \
          ${ADIC_CC} -s -h -f 1 ${CFLAGS} $$i ; \
          fi; done ; \
        fi; fi
	@-if [ "${NOADIC}" != "true" ]; then if [ "${SOURCEH}" != "" ]; then \
          for i in ${SOURCEH} foo; do if [ -f $$i ]; then \
          ${ADIC_CC} -s -h -f 1 ${CFLAGS} $$i ; \
          fi; done ; \
        fi; fi

adic2:
	-if [ "${NOADIC}" != "true" ]; then if [ "${SOURCEC}" != "" ]; then \
          for i in ${SOURCEC} foo; do if [ -f $$i ]; then \
          ${ADIC_CC} -h -f 1 ${CFLAGS} $$i ; \
          fi; done ; \
        fi; fi
	-if [ "${NOADIC}" != "true" ]; then if [ "${SOURCEH}" != "" ]; then \
          for i in ${SOURCEH} foo; do if [ -f $$i ]; then \
          ${ADIC_CC} -h -f 1 ${CFLAGS} $$i ; \
          fi; done ; \
        fi; fi

adiclib:
	-@if [ "${NOADIC}" != "true" ]; then if [ "${SOURCEC}" != "" ]; then \
          ${CC} -c ${CFLAGS} ${COPTFLAGS} ${ADIC_INCLUDE} *.ad.c ; \
        fi; fi
	-@if [ "${NOADIC}" != "true" ]; then if [ "${SOURCEC}" != "" ]; then \
          ${AR} cr ${PDIR}/${LIBBASE}.a *.ad.o ; \
        fi; fi
	-@${RM} -f *.ad.o

adiclib2:
	-if [ "${NOADIC}" != "true" ]; then if [ "${SOURCEC}" != "" ]; then \
          ${CC} -c ${CFLAGS} ${COPTFLAGS} ${ADIC_INCLUDE} *.ad.c ; \
        fi; fi
	-if [ "${NOADIC}" != "true" ]; then if [ "${SOURCEC}" != "" ]; then \
          ${AR} cr ${PDIR}/${LIBBASE}.a *.ad.o ; \
        fi; fi
	-@${RM} -f *.ad.o
#
#
countfunctions: chkpetsc_dir
	-@if [ ! -f ${PDIR}/countfunctions ]; then \
	  echo "PetscDummyFunction" > ${PDIR}/countfunctions ; fi
	@-if [ "${SOURCEC}" != "" ]; then \
          for i in ${SOURCEC} foo; do if [ -f $$i ]; then \
           grep "define __FUNC__" $$i | cut -f2 -d\" >> ${PDIR}/countfunctions ; \
          fi; done ; \
        fi
checkbadPetscFunctionBegin:
	-@if [ "${SOURCEC}" != "" ] ; then \
	${OMAKE} -f makefile PETSC_ARCH=${PETSC_ARCH} BOPT=${BOPT} \
	checkbadPetscFunctionBegin_private ; fi

checkbadPetscFunctionBegin_private:
	-@for filename in ${SOURCEC} ; do \
	a=`grep '#define __FUNC__' $$filename | wc -l`; \
	b=`grep 'PetscFunctionBegin' $$filename | wc -l`; \
	if [ $$a -ne $$b ] ; then \
	echo "$$filename: __FUNC__ = $$a; PetscFunctionBegin = $$b" ; \
	fi; \
	done
# -------------------------------------------------------------------------------

SHLIBS = libpetsccontrib libpetscmat libpetscsles \
	libpetscsnes libpetscsys libpetscts libpetscvec libpetscts libpetscgvec

deleteshared: chkopts_basic
	${RM} ${LDIR}/*.${SLSUFFIX} ${LDIR}/so_locations

noshared:

#default shared library suffix
SLSUFFIX = so
