#
# LDIR (defined from $BS_DIR) determines the libraries that are linked.
# PDIR (defined from $BS_DIR) determines where the libraries are built.
# LDIR and PDIR will usually be identical.
# LIBNAME - library name
# SOURCE - source files
# OBJS - object files
# PETSC_INCLUDE - locations of include files
#
LDIR	      = $(BS_DIR)/lib/lib$(BOPT)/$(PETSC_ARCH)
PDIR	      = $(BS_DIR)/lib/lib$(BOPT)/$(PETSC_ARCH)
LIBNAME	      = $(PDIR)/$(LIBBASE).a
SOURCE	      = $(SOURCEC) $(SOURCEF)
OBJS	      = $(OBJSC) $(OBJSF)
PETSC_INCLUDE = -I$(BS_DIR) -I$(BS_DIR)/include $(MPI_INCLUDE) \
	       -I$(BS_DIR)/src
#
# Defines all libraries needed for using linear and nonlinear solvers, 
# stencils, grids, and all lower level PETSc components (such as vectors 
# and matrices).  The order of listing these libraries is important!
#
ALL_PETSC_LIB	= -L$(LDIR) -lpetscstencil -lpetscgrid \
		-lpetscsnes  -lpetscsles -lpetscksp \
		-lpetscmat  -lpetscvec -lpetscdraw \
		-lpetscsys \
		$(SUPERLU_LIB) $(BS_LIB) $(LAPACK_LIB) $(BLAS_LIB) $(X11_LIB) \
		$(MPI_LIB) $(FC_LIB) $(SYS_LIB) -lm
#
PETSC_LIB   = -L$(LDIR) -lpetscsnes  -lpetscsles -lpetscksp \
		-lpetscmat  -lpetscvec -lpetscdraw \
		-lpetscsys \
		$(SUPERLU_LIB) $(BS_LIB) $(LAPACK_LIB) $(BLAS_LIB) $(X11_LIB) \
		$(MPI_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 -lpetscksp \
		-lpetscmat  -lpetscvec -lpetscdraw \
		-lpetscsys \
		$(SUPERLU_LIB) $(BS_LIB) $(LAPACK_LIB) $(BLAS_LIB) $(X11_LIB) \
		$(MPI_LIB) $(FC_LIB) $(SYS_LIB) -lm

#
#  Link if you are programming in Fortran 
#
PETSC_FORTRAN_LIB = -L$(LDIR) -lpetscfortran
#
# These include files set customized site, optimization, and version options.
# Do NOT remove any of these include files.  You should have to edit only
# $(BS_DIR)/bmake/$(PETSC_ARCH)/$(PETSC_ARCH).site for your particular
# machine configuration.  See the users manual for details.
#
include $(BS_DIR)/bmake/$(PETSC_ARCH)/$(PETSC_ARCH).site
# (This line MUST be present for certain machines (e.g., Cray T3D))
include $(BS_DIR)/bmake/$(PETSC_ARCH)/$(PETSC_ARCH).$(BOPT)

# Checks that BS_DIR variable is set and creates library directory
# if it does not exist
chkpetsc_dir:
	@if [ Holder = Holder$(BOPT) ] ; then \
	  echo "You must set the variable BOPT=[g,O, or Opg]" ; false; fi
	-@if [ ! -d $(PDIR) ]; then \
	  echo Making directory $(PDIR) for library; mkdir -p $(PDIR) ; fi

# checks that user has set BOPT variable
chkopts: 
	@if [ Holder = Holder$(BOPT) ] ; then \
	  echo "You must set the variable BOPT=[g,O, or Opg]" ; false; fi
	@if [ ! -d $(LDIR) ]; then \
	  echo Libraries not built for this BOPT: $(BOPT); false ; fi

# Compiles examples_1: primary group for installation testing
examples_1: chkopts
	@-if [ "$(EXAMPLES_1)" != "" ] ; then \
          (for ex in $(EXAMPLES_1) foo ; do \
          $(OMAKE) -f makefile PETSC_ARCH=$(PETSC_ARCH) BOPT=$(BOPT) $$ex;\
          done;) fi

# Runs examples that have already been compiled
runexamples_1:
	@-if [ "$(RUNEXAMPLES_1)" != "" ] ; then \
	  (for ex in $(RUNEXAMPLES_1) foo ; do \
	  $(OMAKE) -f makefile $$ex; \
	  done;) fi

# Compiles examples_2: secondary examples, many have x-displays
examples_2: chkopts
	@-if [ "$(EXAMPLES_2)" != "" ] ; then \
	  (for ex in $(EXAMPLES_2) foo ; do \
	  $(OMAKE) -f makefile PETSC_ARCH=$(PETSC_ARCH) BOPT=$(BOPT) $$ex\
	  > trashz 2>&1; \
	  grep -v clog trashz | grep -v "information sections" | \
	  egrep -i '(Error|warning|Can)'  >> /dev/null ; \
	  if [ "$$?" != 1 ]; then \
	  cat trashz ; fi; $(RM) trashz;\
	  done;) fi

# Runs examples that have already been compiled
runexamples_2:
	@-if [ "$(RUNEXAMPLES_2)" != "" ] ; then \
	  (for ex in $(RUNEXAMPLES_2) foo ; do \
	  $(OMAKE) -f makefile $$ex; \
	  done;) fi

# Compiles examples_3: Fortran examples
examples_3: chkopts
	@-if [ "$(EXAMPLES_3)" != "" ] ; then \
	  (for ex in $(EXAMPLES_3) foo ; do \
	  $(OMAKE) -f makefile PETSC_ARCH=$(PETSC_ARCH) BOPT=$(BOPT) $$ex\
	  > trashz 2>&1; \
	  grep -v EXTERNAL trashz | \
	  egrep -i '(Error|warning|Can)'  >> /dev/null ; \
	  if [ "$$?" != 1 ]; then \
	  cat trashz ; fi; $(RM) trashz;\
	  done;) fi

# Runs examples that have already been compiled
runexamples_3:
	@-if [ "$(RUNEXAMPLES_3)" != "" ] ; then \
	  (for ex in $(RUNEXAMPLES_3) foo ; do \
	  $(OMAKE) -f makefile $$ex; \
	  done;) fi

# Compiles examples_4: mpiuni examples
examples_4: chkopts
	@-if [ "$(EXAMPLES_4)" != "" ] ; then \
	  (for ex in $(EXAMPLES_4) foo ; do \
	  $(OMAKE) -f makefile PETSC_ARCH=$(PETSC_ARCH) BOPT=$(BOPT) $$ex\
	  > trashz 2>&1; \
	  grep -v clog trashz | grep -v "information sections" | \
	  egrep -i '(Error|warning|Can)'  >> /dev/null ; \
	  if [ "$$?" != 1 ]; then \
	  cat trashz ; fi; $(RM) trashz;\
	  done;) fi

# Runs examples that have already been compiled
runexamples_4:
	@-if [ "$(RUNEXAMPLES_4)" != "" ] ; then \
	  (for ex in $(RUNEXAMPLES_4) foo ; do \
	  $(OMAKE) -f makefile $$ex; \
	  done;) fi

# Does nothing, obviously, 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) $(BASEOPT) $(SOURCEC) ;\
	fi
	@-if [ "$(SOURCEF)" != "" ] ; then \
	     $(FC) -c $(FFLAGS) $(BASEOPTF) $(SOURCEF) ;\
	fi
	@-if [ "$(OBJS)" != " " ] ; then \
	  $(AR) cr $(LIBNAME) $(OBJS); \
	  $(RM) -f $(OBJS); \
	fi

# Removes garbage files
clean:
	@-$(RM) -f *.o *~ $(CLEANFILES) $(EXAMPLES_1) $(EXAMPLES_2) \
	       $(EXAMPLES_3) $(TESTS) \
	       PI* *.ln l.outa* mputil.mp_* core *.tmp *.map *.log gmon.out \
	       trashz \#*\# *.mex* *.stolen *.trace Log.* joe jeff *.stolen \
	       output/*~ .mpirtmp mon.out

# Builds and runs examples; then cleans directory.
examples: examples_1 examples_2
testexamples_1: examples_1 runexamples_1 clean
testexamples_2: examples_2 runexamples_2 clean
testexamples_3: examples_3 runexamples_3 clean
testexamples_4: examples_4 runexamples_4 clean
buildexamples_1: examples_1 clean
buildexamples_2: examples_2 clean
buildexamples_3: examples_3 clean
buildexamples_4: examples_4 clean

# Performs the specified action throughout the directory tree
tree: $(ACTION)
	@-if [ "$(DIRS)" != "" ]; then \
	for dir in $(DIRS) foo ; do if [ -s $$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.
#

# RCS file check-in
ci: 
	@-ci -u -q -mAutoCheckin $(SOURCEH) $(SOURCE) makefile \
	  $(EXAMPLESC) $(EXAMPLESF) $(TESTSC) $(TESTSF) 

# RCS file check-out
co:
	@-co -l -q $(SOURCEH) $(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/bsmith/bin/sun4/bfort -dir /home/bsmith/petsc/src/fortran/auto \
	  -mnative -ansi -nomsgs -anyname -mapptr -mpi -ferr -ptrprefix MPIR_\
	  -ptr64 HAVE_64BITS $(SOURCEC)
	chmod g+w /home/bsmith/petsc/src/fortran/auto/*.c


# Builds man pages (xman version)
manpages:
	@-if [ "$(MANSEC)" != "" ] ; then \
	doctext -mpath $(BS_DIR)/docs/man/man$(MANSEC) -ext $(MANSEC) -locdir $(LOCDIR) \
		readme $(SOURCEC) $(SOURCEH);	\
		chmod g+w $(BS_DIR)/docs/man/man$(MANSEC)/*; fi 

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

# Builds man pages (HTML version)
wwwpages:
	@-if [ "$(MANSEC)" != "" ] ; then \
	doctext -html -index $(BS_DIR)/docs/www/www.cit \
		-mpath $(BS_DIR)/docs/www/man$(MANSEC) -ext $(MANSEC)\
		-indexdir www/man$(MANSEC) -locdir $(LOCDIR) \
		 $(SOURCEC) $(SOURCEH); \
		chmod g+w $(BS_DIR)/docs/www/man$(MANSEC)/*; fi 





