#####################
# CONFIGURATION DATA
###################
legalhosts = [alpha] [i386] [i486] [i586] [i686] [sun4m] [IP35]
x86list    = [i386] [i486] [i586] [i686]

legal_compilers = [gcc] [ccc] [cc]
legal_compilerscc = [ccc] [g++] [cxx] [CC]
legal_compilersf77 = [g77] [fort] [f77]

legal_compile_types = [debug] [fast] [fastdebug] [btdebug] [olddebug]
legal_compile_types += [matlab] [profile] [purify] [debugnoamma] [whine]


###################################
# CMDLINE CHOICES AND MACHINE INFO
#################################
# get compiler choice, default is "gcc"
# NOTE: compc might be a c++ compiler, if "c=..." is specified
compc = gcc
compcc = g++
compf77 = g77
ifneq (,$(findstring [$(c)], $(legal_compilers)))
  compc = $(c)
endif
ifneq (,$(findstring [$(cc)], $(legal_compilerscc)))
  compcc = $(cc)
endif
ifneq (,$(findstring [$(f77)], $(legal_compilersf77)))
  compf77 = $(f77)
endif

# get compile type, default is "debug"
ifeq (,$(findstring [$(t)], $(legal_compile_types)))
  override t := debug
endif


# Paul Komarek 2002 12 18 -- added code to remove spaces.
# Get machine information, removing spaces (*cough*OSX*cough*).
# We could replace spaces with underscores, but that is the character
# sed to join these variables together for the archdir.
hosttype=$(shell uname -m | sed -e 's/ //g')
ostype=$(shell uname -s | sed -e 's/ //g')
osver=$(shell uname -r | sed -e 's/ //g')

# get gcc version
gccver1 = 0
gccver2 = 0
gccver3 = 0
compcisgcc = $(shell $(compc) 2>&1 | head -n1 | sed -ne 's:.*\(gcc\).*:\1:p')
ifneq (,$(compcisgcc))
  gccver1 = $(shell $(compc) --version | head -n1 \
                    | sed -ne 's:^gcc (GCC) \([0-9]\).*$$:\1:p')
  gccver2 = $(shell $(compc) --version | head -n1 \
                    | sed -ne 's:^gcc (GCC) [0-9]\.\([0-9]\).*$$:\1:p')
  gccver3 = $(shell $(compc) --version | head -n1 \
                    | sed -ne 's:^gcc (GCC) [0-9]\.[0-9]\.\([0-9]\).*$$:\1:p')
endif



####################
# Get C lib version
##################
cver =

# Try getting glibc version on Linux-based systems.
ifeq ($(ostype),Linux)
  # Linux-based systems typically use glibc.
  glibcver=$(shell sed -n 's/^VERSION="\([0-9]*.[0-9]*.[0-9]*\)"/\1/p' \
                                                          `which glibcbug`)
  cver = glibc-$(glibcver)
endif
# Use generic method of finding libc for other systems.
ifeq (,$(cver))
    cver=$(shell \
           if [ -x "/usr/bin/ldd" ]; then \
             base="/tmp/clibver.${here}"; \
             echo "int main(void){return 0;}" > "$$base.c"; \
             $(compc) -o "$$base" "$$base.c"; \
             ldd "$$base" | sed -ne "s/.*\(libc\.so\..*\) =>.*/\1/p"; \
             rm -f "$$base" "$$base.c"; \
           fi \
          )
endif

# Paul Komarek 2002 12 18: removed "libc_unknown" to allow shorter
# directory names in some cases:
#   Darwin_PowerMacintosh_libc-unknown_gcc.fast versus
#   Darwin_PowerMacintosh__gcc.fast
# If the generic method failed, set cver to ""
ifeq (,$(cver))
  # This causes no change to cver.  I left this here to make it easy to
  # see code flow and branching options.  Don't put cver = "", because
  # the quotes are taken literally.
  cver = 
endif

# Must be :=, or else there is a recursive definition of cver.
cver := $(shell echo $(cver) | sed -e "s/ //")

#############################################################
# MISCELLANEOUS DEFINITIONS (some are changed further below)
###########################################################
# set CC and CXX for error checking -- use compc or compcc instead
CC		:= FOO
CXX             := BAR
F77             := BAZ
warn_flags      := -Wall -D__USE_FIXED_PROTOTYPES__
cxx_warn_flags  := -Wall -D__USE_FIXED_PROTOTYPES__
f77_warn_flags  := -Wall -D__USE_FIXED_PROTOTYPES__
ar_command      := ar rv
group_root := /afs/cs.cmu.edu/project/learn/group

##########
# ARCHDIR
########
# check that we can handle hosttype
ifeq (,$(findstring [$(hosttype)], $(legalhosts)))
	echo "We need to update our Make.common for \"uname -m\"==$(hosttype)"
endif
# combine all x86 hosts into one
ifneq (,$(findstring [$(hosttype)], $(x86list)))
	hosttype=x86
endif

# Check that cpu is Athlon MP, which we assume only happens on Linux and
# FreeBSD.  With more exploration, we might open this up to other cpus.
cpustr = "bogus"
ifeq ($(ostype),FreeBSD)
  cpustr = $(shell sysctl hw.model)
endif
ifeq ($(ostype),Linux)
  cpustr = $(shell \
             grep -i "model name" /proc/cpuinfo | head -n1; \
             echo "$$?" \
            )
endif
athcpu = $(shell \
           echo "$(cpustr)" | grep -i athlon | grep -iq mp; \
           echo $$? \
          )
ifeq ($(athcpu),0)
  hosttype = athlonmp
endif


# create name for target directory
archdir=$(ostype)_$(hosttype)_$(cver)_$(compc)


################
# GENERAL COMPILER FLAGS
##############

# Options are now cumulative, because I've switched := to +=

ifeq ($(t),debug)
  type_c_compile_flags += -g -O0 $(debug_flags)
  type_f77_compile_flags += -g -O0 $(debug_flags)
  type_cxx_compile_flags += -g -O0 $(debug_flags)
endif

ifeq ($(t),olddebug)
  type_c_compile_flags += -g -O0
  type_f77_compile_flags += -g -O0
  type_cxx_compile_flags += -g -O0
endif

ifeq ($(t),profile)
  type_c_compile_flags += -DAMFAST -O2 -pg
  type_f77_compile_flags += -DAMFAST -O2 -pg
  type_cxx_compile_flags += -DAMFAST -O2 -pg
  type_link_flags += -pg
endif

ifeq ($(t),fast)
  type_c_compile_flags += -DAMFAST -O2 $(fast_flags)
  type_f77_compile_flags += -DAMFAST -O2 $(fast_flags)
  type_cxx_compile_flags += -DAMFAST -O2 $(fast_flags)
endif

ifeq ($(t), debugnoamma)
  type_c_compile_flags += -g -DUSE_OS_MEMORY_MANAGEMENT
  type_f77_compile_flags += -g -DUSE_OS_MEMORY_MANAGEMENT
  type_cxx_compile_flags += -g -DUSE_OS_MEMORY_MANAGEMENT
endif

ifeq ($(t),fastdebug)
  type_c_compile_flags += -DAMFAST -g
  type_f77_compile_flags += -DAMFAST -g
  type_cxx_compile_flags += -DAMFAST -g
endif

ifeq ($(t),matlab)
  type_c_compile_flags += -DMATLAB_COMPILE -O2
  type_f77_compile_flags += -DMATLAB_COMPILE -O2
  type_cxx_compile_flags += -DMATLAB_COMPILE -O2
  build_executable = cmex -o $(group_root)/bin/$(here) CC=$(compc) LD_CCLIBS=$(LIBS) MEXLIBS='-lm /afs/cs.cmu.edu/misc/matlab/sun4c_411/omega/extern/lib/sun4/libmex.a' $(mainobjs) $(libraries)
endif

ifeq ($(t),purify)
# use debugging object directories, just write the binary using purify.
  override t += debug
  type_c_compile_flags += -g
  type_f77_compile_flags += -g
  type_cxx_compile_flags += -g
  build_executable = purify -cache-dir=.g/PURIFY -chain-length=12  $(standard_build_executable)
endif

ifeq ($(t),whine)
  pedflag = -pedantic-errors
  ifeq ($(gccver1),3)
    ifeq ($(shell if [ $(gccver2) -ge 3 ]; then echo "high"; fi), high)
      pedflag = -pedantic
    endif
  endif

  type_c_compile_flags += -O1 -Wall -D__USE_FIXED_PROTOTYPES__ $(pedflag) \
    -W -Wpointer-arith -Wbad-function-cast -Wsign-compare -Wstrict-prototypes \
    -Wmissing-format-attribute -Wpadded -Winline -Wdisabled-optimization 
  type_f77_compile_flags += -O1 -Wall
  type_cxx_compile_flags += -O1 -Wall -D__USE_FIXED_PROTOTYPES__ $(pedflag) \
    -W -Wpointer-arith -Wbad-function-cast -Wsign-compare -Wstrict-prototypes \
    -Wmissing-prototypes -Wmissing-declarations -Wmissing-format-attribute \
    -Wpadded -Wredundant-decls -Winline -Wdisabled-optimization
endif

################
# COMPILER- AND PLATFORM-SPECIFIC FLAGS
##############

# NOTES:
#
# * This is the section that is meant to maintained on a case-by-case basis
#   and correctness is soley determined by whether we DTRT.
# * The following sections do not need to be exclusive, though it will be
#   very difficult to understand if they overlap in arbitrary ways.

# Prevent C compilation mishaps.
# compc=gcc, or cc on FreeBSD and GNU/Linux (uname -s == Linux).

pedflag=""
ifneq (,$(compcisgcc))
  pedflag = -pedantic-errors
  ifeq ($(gccver1),3)
    ifeq ($(shell if [ $(gccver2) -ge 3 ]; then echo "high"; fi), high)
      pedflag = -pedantic
    endif
  endif
endif
type_c_compile_flags += $(pedflag)


ifeq ($(ostype),CYGWIN_NT-5.1)
  extra_link_flags += -L/usr/X11R6/lib
  type_c_compile_flags += -L/usr/X11R6/lib
endif


ifeq ($(ostype),FreeBSD)
  # FreeBSD's stdlib.h uses the long long type, and we can't really
  # ignore FreeBSD entirely ;-).  Therefore we ignore long long problems.
  type_c_compile_flags += -Wno-long-long
endif

# NEEDS MORE WORK: 2002 12 18
ifeq ($(ostype),Darwin)
  # Apple has chosen to copy FreeBSD's trouble-making long long mess.
  type_c_compile_flags += -Wno-long-long
endif

# Check whether to set the athlon-mp flags.
ifeq ($(hosttype),athlonmp)
  ifeq ($(t),fast)
    athflags = -march=athlon-mp -fprefetch-loop-arrays

    # Check that compiler supports athflags.
    athpre = $(shell \
              fname="/tmp/athpre.$(here)"; \
              echo "int main(void) { return 0; }" > "$$fname.c"; \
              $(compc) $(athflags) -o "$$fname" "$$fname.c" > /dev/null 2>&1; \
              rc=$$?; \
              if [ "$$rc" -eq 0 ]; then "$$fname"; rc=$$?; fi; \
              rm -f "$$fname" "$$fname.c"; \
              echo $$rc \
             )

    # If everything went well, adjust the compile flags and archdir.
    ifeq ($(athpre),0)
      type_c_compile_flags += $(athflags)
    endif
  endif
  ifeq ($(t),profile)
    athflags = -march=athlon-mp -fprefetch-loop-arrays

    # Check that compiler supports athflags.
    athpre = $(shell \
              fname="/tmp/athpre.$(here)"; \
              echo "int main(void) { return 0; }" > "$$fname.c"; \
              $(compc) $(athflags) -o "$$fname" "$$fname.c" > /dev/null 2>&1; \
              rc=$$?; \
              if [ "$$rc" -eq 0 ]; then "$$fname"; rc=$$?; fi; \
              rm -f "$$fname" "$$fname.c"; \
              echo $$rc \
             )

    # If everything went well, adjust the compile flags and archdir.
    ifeq ($(athpre),0)
      type_c_compile_flags += $(athflags)
    endif
  endif
endif

# compc=gcc, hosttype=, ostype=Linux, osver=
# I'd like to check linkcc, but it is set further below.
ifeq ($(compc),gcc)
  ifeq ($(ostype),Linux)
    # Whether we're running fast or slow, BTDEBUG is recommended.  It
    # has no performance impact.
    type_c_compile_flags += -DBTDEBUG
    type_f77_compile_flags += -DBTDEBUG
    type_cxx_compile_flags += -DBTDEBUG
    extra_link_flags += -rdynamic
  endif
endif

# compc=gcc, hosttype=, ostype=Linux, osver=
# I'd like to check linkcc, but it is set further below.
ifeq ($(compcc),g++)
  ifeq ($(ostype),Linux)
    # Whether we're running fast or slow, BTDEBUG is recommended.  It
    # has no performance impact.
    type_c_compile_flags += -DBTDEBUG
    type_f77_compile_flags += -DBTDEBUG
    type_cxx_compile_flags += -DBTDEBUG
    extra_link_flags += -rdynamic
  endif
endif

# c=, hosttype=, ostype=Linux, osver=
ifeq ($(ostype), Linux)
  arch_include_dirs += -I/usr/X11R6/include
  arch_link_flags += -L/usr/X11R6/lib -L/usr/X11R6/lib64
endif

# ostype=IRIX64 => no -Wall
ifeq ($(compcc), CC)
  ifeq ($(ostype), IRIX64)
    warn_flags      := -D__USE_FIXED_PROTOTYPES__
    f77_warn_flags  := -D__USE_FIXED_PROTOTYPES__
    cxx_warn_flags  := -D__USE_FIXED_PROTOTYPES__
  endif
endif

# c=ccc or c=cxx or c=cc(and using Tru64), hosttype=alpha, ostype=, osver=
# or f77=fort or f77=f77(and using Tru64), hosttype=alpha, ostype=, osver=
ifeq ($(hosttype),alpha)
  ifeq ($(ostype),Linux)
    compaq_compilers = [ccc] [cxx] [fort]
  else
    compaq_compilers = [cc] [cxx] [fort] [f77]
  endif

  ifneq (,$(findstring [$(compc)],$(compaq_compilers)))
    arch_compile_flags += -ieee -D__HAS_ISINF__=0 -D__USE_FIXED_PROTOTYPES_
    warn_flags      += -msg_enable level4 -D__USE_FIXED_PROTOTYPES__ -msg_disable unusedtop,nomainieee
  else
    arch_compile_flags += -mieee
  endif

  ifneq (,$(findstring [$(compcc)],$(compaq_compilers)))
     cxx_warn_flags  += -msg_enable level4 -D__USE_FIXED_PROTOTYPES__ -msg_disable unusedtop,nomainieee
  endif

  ifneq (,$(findstring [$(compf77)],$(compaq_compilers)))
     f77_warn_flags  += -msg_enable level4 -D__USE_FIXED_PROTOTYPES__ -msg_disable unusedtop,nomainieee
     extra_link_flags += -nofor_main
  endif

endif

# c=, hosttype=, ostype=SunOS, osver=[4.1.4] would be old SunOS, 5.7 is Solaris
# c=, hosttype=, ostype=SunOS, osver=[5.7]
ifeq ($(ostype), SunOS)
  ifeq ($(osver), 5.7)
    ar_command += /usr/xpg4/bin/ar -rv
  endif
endif

# c=, hosttype in pmax_list, ostype=, osver=  (though ostype is more relevant)
pmax_list += [pmax_mach] [pmax_ul43a]
ifneq (,$(findstring [$(hosttype)], $(pmax_list)))
  arch_include_dirs += -I/usr/misc/.X11/include
  arch_link_flags += -L/usr/misc/.X11/lib
endif

# c=, hosttype in sgi_list, ostype=, osver= (though ostype is more relevant)
sgi_list = [iris4d] [sgi_53] [sgi_62]
ifneq (,$(findstring [$(hosttype)], $(sgi_list)))
  arch_compile_flags += -DSGI_COMPILE
endif

# c=, hosttype=, ostype=FreeBSD, osver= (though ostype is more relevant)
freebsd_list = [FreeBSD]
ifneq (,$(findstring [$(ostype)], $(freebsd_list)))
  arch_include_dirs += -I/usr/X11R6/include
  arch_link_flags += -L/usr/X11R6/lib
endif

# c=, hosttype=, ostype=Darwin, osver= (though ostype is more relevant)
darwin_list = [Darwin]
ifneq (,$(findstring [$(ostype)], $(darwin_list)))
  arch_include_dirs += -I/usr/X11R6/include
  arch_link_flags += -L/usr/X11R6/lib
endif

############## END OF PAUL KOMAREK'S CHANGES #####################
############## END OF PAUL KOMAREK'S CHANGES #####################
############## END OF PAUL KOMAREK'S CHANGES #####################

### SECTION 3.  FINAL VARIABLE ASSIGNMENTS FOR RULES

ifeq ($(t),oldstyle)
  OBJDIR	:= obj
else
  OBJDIR	:= $(archdir).$(t)
  make_objdir   := $(shell test -d $(OBJDIR) || .g/fancy-mkdir $(OBJDIR) 1>&2 )
endif

include_dirs	:= -I. -I.g $(foreach sib,$(siblings),-I.g/$(sib))
CFLAGS		:= $(type_c_compile_flags) $(arch_compile_flags) $(warn_flags) $(user_flags) $(include_dirs) $(arch_include_dirs)

F77FLAGS	:= $(type_f77_compile_flags) $(arch_compile_flags) $(f77_warn_flags) $(user_flags) $(include_dirs) $(arch_include_dirs)

CXXFLAGS	:= $(type_cxx_compile_flags) $(arch_compile_flags) $(cxx_warn_flags) $(user_flags) $(include_dirs) $(arch_include_dirs)

LIBS		+= -lX11 -lm
LFLAGS		:= $(arch_link_flags) $(type_link_flags) $(extra_link_flags)

#mains		:= main.c $(private_sources)
#mainobjs	:= $(patsubst %.c,$(OBJDIR)/%.o,$(mains))
#libobjs		:= $(patsubst %.c,$(OBJDIR)/%.o,$(sources))

mains		:= $(filter %.c %.f %.cc %.cpp,$(wildcard main.*))
maincsources	:= $(filter %.c,$(mains))
mainf77sources	:= $(filter %.f,$(mains))
mainccsources	:= $(filter %.cc,$(mains))
maincppsources	:= $(filter %.cpp,$(mains))
maincobjs	:= $(patsubst %.c,$(OBJDIR)/%.o,$(maincsources))
mainf77objs	:= $(patsubst %.f, $(OBJDIR)/%.o,$(mainf77sources))
mainccobjs	:= $(patsubst %.cc, $(OBJDIR)/%.o,$(mainccsources))
maincppobjs	:= $(patsubst %.cpp, $(OBJDIR)/%.o,$(maincppsources))
libcsources	:= $(filter %.c,$(sources))
libf77sources	:= $(filter %.f,$(sources))  # support other extentions later
libccsources	:= $(filter %.cc,$(sources))
libcppsources	:= $(filter %.cpp,$(sources))
libcobjs	:= $(patsubst %.c, $(OBJDIR)/%.o,$(libcsources))
libf77objs	:= $(patsubst %.f, $(OBJDIR)/%.o,$(libccsources))
libccobjs	:= $(patsubst %.cc, $(OBJDIR)/%.o,$(libccsources))
libcppobjs	:= $(patsubst %.cpp, $(OBJDIR)/%.o,$(libcppsources))

numsources	:= $(words $(sources))
cplibs		:= $(filter lib%.a,$(sources))
numcplibs	:= $(words $(cplibs))

siblibs		:= $(foreach sib,$(siblings),.g/$(sib)/$(OBJDIR)/lib$(sib).a)

sibf77sources	:= $(foreach sib,$(siblings),$(wildcard .g/$(sib)/*.f))
allf77sources	:= $(mainf77sources) $(libf77sources) $(sibf77sources)

sibccsources	:= $(foreach sib,$(siblings),$(wildcard .g/$(sib)/*.cc))
sibcppsources	:= $(foreach sib,$(siblings),$(wildcard .g/$(sib)/*.cpp))
allccsources	:= $(mainccsources) $(libccsources) $(sibccsources)
allcppsources	:= $(maincppsources) $(libcppsources) $(sibcppsources)

library		:= $(OBJDIR)/lib$(here).a
libraries	:= $(library) $(siblibs) $(user_libs)

execute         := $(OBJDIR)/$(here)


# Paul Komarek 2001-12-16: attempt to automagically choose proper linker and
# compiler.
ifeq ($(linkcc),)
  linkcc = $(compc)

  # I don't know what we should do if C++ and Fortran sources are mixed.
  # The makefile code below will end up using the C++ linker.  We should
  # at least print a warning.  I have no examples to test right now.
  ifneq (,$(word 1, $(allf77sources)))
    ifneq (,$(word 1, $(allccsources)))
	echo "WARNING: we have never tested mixed FORTRAN and C++ code." 1>&2
    endif
    ifneq (,$(word 1, $(allcppsources)))
	echo "WARNING: we have never tested mixed FORTRAN and C++ code." 1>&2
    endif
  endif


  # If we have .f sources in ourself or siblings, use Fortran linker.
  ifneq (,$(word 1, $(allf77sources)))
    linkcc = $(compf77)
  endif

  # If we have .cc or .cpp sources in ourself or siblings, use C++ linker.
  ifneq (,$(word 1, $(allccsources)))
    linkcc = $(compcc)
  endif
  ifneq (,$(word 1, $(allcppsources)))
    linkcc = $(compcc)
  endif

endif


standard_build_executable := $(linkcc) $(LFLAGS)   -o $(execute)   $(maincobjs) $(mainf77objs) $(mainccobjs) $(maincppobjs) $(libraries) $(LIBS)  &&  (ln -sf $(execute) $(here) ; ln -sf $(execute) $(here)-$(OBJDIR)) && (ln -sf $(library) .)

ifeq ($(build_executable),)
  build_executable := $(standard_build_executable)
endif


### SECTION 4.  RULES FOR LIBRARY FILES

.PHONY:	main library

main: $(siblings) library $(maincobjs) $(mainccobjs) $(maincppobjs)
	$(build_executable)
	@echo Compilation finished at `date`

params:
	@echo "here                      = $(here)"
	@echo "c                         = $(c)"
	@echo "compc                     = $(compc)"
	@echo "compcisgcc                = $(compcisgcc)"
	@echo "gccver1                   = $(gccver1)"
	@echo "gccver2                   = $(gccver2)"
	@echo "gccver3                   = $(gccver3)"
	@echo "compf77                   = $(compf77)"
	@echo "compcc                    = $(compcc)"
	@echo "linkcc                    = $(linkcc)"
	@echo "type_c_compile_flags      = $(type_c_compile_flags)"
	@echo "warn_flags                = $(warn_flags)"
	@echo "type_f77_compile_flags    = $(type_f77_compile_flags)"
	@echo "f77warn_flags             = $(f77_warn_flags)"
	@echo "type_cxx_compile_flags    = $(type_cxx_compile_flags)"
	@echo "cxxwarn_flags             = $(cxx_warn_flags)"
	@echo "arch_compile_flags        = $(arch_compile_flags)"
	@echo "user_flags                = $(user_flags)"
	@echo "hosttype                  = $(hosttype)"
	@echo "ostype                    = $(ostype)"
	@echo "cver                      = $(cver)"
	@echo "archdir                   = $(archdir)"
	@echo "numsources                = $(numsources)"
	@echo "cplibs                    = $(cplibs)"
	@echo "library                   = $(library)"

showsources:
	@echo "mains                     = $(mains)"
	@echo "maincsources              = $(maincsources)"
	@echo "mainf77sources            = $(mainf77sources)"
	@echo "mainccsources             = $(mainccsources)"
	@echo "maincppsources            = $(maincppsources)"
	@echo "sources                   = $(sources)"
	@echo "libcsources               = $(libcsources)"
	@echo "libf77sources             = $(libf77sources)"
	@echo "libccsources              = $(libccsources)"
	@echo "libcppsources             = $(libcppsources)"
	@echo "cplibs                    = $(cplibs)"
	@echo "siblibs                   = $(siblibs)"
	@echo "sibf77sources             = $(sibf77sources)"
	@echo "sibccsources              = $(sibccsources)"
	@echo "sibcppsources             = $(sibcppsources)"
	@echo "allf77sources             = $(allf77sources)"
	@echo "allccsources              = $(allccsources)"
	@echo "allcppsources             = $(allcppsources)"


library.recursive: $(siblings) library

library: $(library)
	(ln -sf $(library) .)


# Modifed by Paul Komarek, 2003-07-01, to accomodate copying a single
# static lib from the sources list into the OBJDIR.  No other sources
# can be present in the project, and there may be only one lib.
# Library name must start with "lib".
$(library): $(libcobjs) $(libccobjs) $(libcppobjs) $(cplibs)
# numsources must be positive.
	@if [ "$(numsources)" -eq 0 ]; then \
		echo "There are no sources to compile or libs be made."; \
		exit 1; \
	fi
# Check that sources (incl. main) do not include both libs and c files,
# or multiple libs.
	@if [ "$(numcplibs)" -gt 0 -a "$(numsources)" -gt 1 ]; then \
		echo "Error: cannot have source files (not incl. main) and"; \
		echo "libs {$(cplibs)}, or multiple libs, in same project"; \
		exit 1; \
	fi
# At this point, numcplibs is 1 and numsources > 0.
# Make library from object files, or symlink library.
#
# In the latter case, there might be several versions of the
# library.  The library name
# is $(cplibs) (though plural, we know by now that there is only one
# library).  First we look for $(cplibs).$(OBJDIR), then $(cplibs).$(t).
# If neither of those is present, we use $(cplibs).  If that isn't
# present, we give up.
#
# Also, we check that readme.license is present for a library project.
# I wish we could check every time we link, but I'm not sure how.
# Instead, we check for readme.license only when we "build" the
# library-project.  If it is not present, we
# through an error.  If it is present, we print a notice that
# we should respect the terms of the license.
#
# The symlink we make points to the parent directory, because
# $(library) includes $OBJDIR.
#
# It appears that a minimal sh (as exemplified by FreeBSD's sh)
# allows 1>&2 redirection.
#
	@if [ "$(numcplibs)" -eq 0 ]; then \
		cd $(OBJDIR) ; 	$(ar_command) $(notdir $(library)) \
			$(notdir $(libcobjs)) $(notdir $(libccobjs)) \
			$(notdir $(libcppobjs)); \
	else \
		d=`basename $$PWD`; \
		if [ -f "$(cplibs).$(OBJDIR)" ]; then \
			echo; echo "$$d: Using $(cplibs).$(OBJDIR)"; echo; \
			ln -sf ../$(cplibs).$(OBJDIR) $(library); \
		elif [ -f "$(cplibs).$(t)" ]; then \
			echo; echo "$$d: Using $(cplibs).$(t)"; echo; \
			ln -sf ../$(cplibs).$(t) $(library); \
		elif [ -f "$(cplibs)" ]; then \
			echo; echo "$$d: Using $(cplibs)"; echo; \
			ln -sf ../$(cplibs) $(library); \
		else \
			echo; \
			echo -n "ERROR: NO LIBRARY $(cplibs) OR " 1>&2; \
			echo "DERIVATIVES FOUND IN PROJECT $$d" 1>&2; \
			echo; \
			exit 1; \
		fi; \
		if [ -f "readme.license" ]; then \
			echo; \
			echo -n "PLEASE RESPECT THE TERMS OF " 1>&2; \
			echo "$$d/readme.license" 1>&2 ; \
			echo; \
		else \
			echo; \
			echo -n "ERROR: THERE IS NO readme.license " 1>&2; \
			echo "FILE FOR LIBRARY PROJECT $$d" 1>&2; \
			echo; \
			exit 1; \
		fi; \
	fi



preprocess:
	$(compc) -E -O0 -I.g $(foreach sib,$(siblings),-I.g/$(sib)) \
                      $(arch_include_dirs) $(sources)
	@echo Compilation finished at `date`

asm:
	$(compc) -S -O0 -I.g $(foreach sib,$(siblings),-I.g/$(sib)) \
                      $(arch_include_dirs) $(sources)
	@echo Compilation finished at `date`

# Replace default rule with one that puts object files in special dir.
# The complicated line below with two colons in it says that
# each object file depends on the like-named source file
# and *every* include file.

.c.o: ;

$(libcobjs) $(maincobjs) : $(OBJDIR)/%.o : %.c $(includes)
	$(compc) $(CFLAGS) -o $@ -c $<

$(libf77objs) $(mainf77objs): $(OBJDIR)/%.o : %.f $(includes)
	$(compf77) $(F77FLAGS) -o $@ -c $<

$(libccobjs) $(mainccobjs): $(OBJDIR)/%.o : %.cc $(includes)
	$(compcc) $(CXXFLAGS) -o $@ -c $<

$(libcppobjs) $(maincppobjs): $(OBJDIR)/%.o : %.cpp $(includes)
	$(compcc) $(CXXFLAGS) -o $@ -c $<

# we use _dummy_sib_ to avoid an error when a dirlib uses no siblings
1.PHONY:	_dummy_sib_

# first, remove any symlinks to g/ unless we're under $group_root
# this is a little tricky since SunOS 4.1.3 doesn't have "test -ef"
# next, create and checkout library working directories (recursively) if they don't exist
# now make sure library exists (only thing that takes effect in "normal" case)
$(siblings) _dummy_sib_ :
	test 1 -eq $(shell ls -idL .g $(group_root) 2>/dev/null | sort -nu | wc -l ) ||\
			(test -h .g/$@ -a -d $(cvsroot)/$@ && /bin/rm .g/$@); \
	test -d .g/$@ || ( $(MAKE) $@.localize ; $(MAKE) -C .g/$@ library.recursive ); \
	$(MAKE) -C .g/$@ library


### SECTION 5.  extra goodies

########################################################################
# "gmake backup" -- backs up relevant files from the current libdir into
#                   a compressed archive named  backup/95-09-28.tar.gz

.PHONY:	backup

backup :
	test -d backup || mkdir backup
	tar cvf backup/`date +%y-%m-%d`.tar Makefile README NOTES $(sources) $(includes) $(mains) ; gzip -f backup/*.tar


########################################################################
# gmake grep string="find_me" -- searches for the string "find_me" among
#		this program's source files, including those in sibling dirs

sibs.grep := $(addsuffix .grep,$(siblings))

.PHONY: grep_here $(sibs.grep) grep

grep_here :
	@echo '*****' Searching for '"'$(string)'"' in $(here) '*****'
	@echo '  '  # print blank line
	@fgrep -i -e '$(string)' Makefile $(includes) $(sources) $(mains) || echo
	@echo '  '  # print blank line

grep : grep_here $(sibs.grep)

$(sibs.grep) _dummy_grep_sib_ :
	@cd .g/$(basename $@) ; $(MAKE) grep_here


########################################################################
# "gmake zap"	-- removes *.o files and executable for current lib,
#                  current arch only
# "gmake zapsibs"-- removes *.o and executables for lib & sibling libs,
#                   current arch only

sibs.zap  = $(addsuffix .zap,$(siblings))

.PHONY:	$(sibs.zap) zap zapsibs _dummy_zap_sib_

zap :
	rm -f $(OBJDIR)/*.[oa]
	rm -f $(execute)
	rm -f ./$(here)
	rm -f ./$(here)-$(OBJDIR)

zapsibs : zap $(sibs.zap)

$(sibs.zap) _dummy_zap_sib_ :
	cd .g/$(basename $@) ; $(MAKE) zap

# Runs zap on every AUTON-looking directory
zapall :
	for dir in .g/*; \
	do \
		if [ -d "$${dir}" -a -r "$${dir}/Makefile" ]; \
		then \
			cd $${dir};  \
			$(MAKE) zap; \
		fi; \
	done

########################################################################
# "gmake clean"	-- removes *.o files afor current lib, ALL architectures
# "gmake cleansibs"-- removes *.o for lib & sibling libs, ALL architectures

sibs.clean  = $(addsuffix .clean,$(siblings))

.PHONY:	$(sibs.clean) clean cleansibs _dummy_clean_sib_

clean :
	rm -f */*.o

cleansibs : clean $(sibs.clean)

$(sibs.clean) _dummy_clean_sib_ :
	cd .g/$(basename $@) ; $(MAKE) clean

# Runs clean on every AUTON-looking directory
cleanall :
	for dir in .g/*; \
	do \
		if [ -d "$${dir}" -a -r "$${dir}/Makefile" ]; \
		then \
			cd $${dir};  \
			$(MAKE) clean; \
		fi; \
	done

########################################################################
# "gmake TAGS"	-- generate TAGS file for multi-file searches, replaces
# 					from emacs
#  We're adding a special regex attempting to cover function prototypes
#  in .h files

include_dirs := $(foreach sib,$(siblings),.g/$(sib))
include_files := $(includes) $(foreach dir,$(include_dirs),$(wildcard $(dir)/*.h))

TAGS: $(include_files) $(sources) $(private_sources)
	etags --regex '/[ \t]*[A-Za-z_0-9]+[ \t]+\([A-Za-z_0-9]+\)(/\1/' $(include_files)
	etags -a $(sources) $(private_sources)

########################################################################
# "gmake localize"	-- makes local (CVS checked-out) copies of all
# 				       sibling libs

sibs.localize  = $(addsuffix .localize,$(siblings))

.PHONY:	$(sibs.localize) localize _dummy_localize_sib_

localize : $(sibs.localize)

$(sibs.localize) _dummy_localize_sib_ :
	cd .g/ ; ./localize-dirlib $(basename $@)

########################################################################
# "gmake status"	-- checks CVS status
# 				       
status :
	-cvs status 2>&1 | grep '\(Examining\)\|\(Status\)' | fgrep -v Up-to-date

status-all:
	-cd .g/ ; cvs status 2>&1 | grep '\(Examining\)\|\(Status\)' | fgrep -v Up-to-date
