#################################################################
# Generic makefile for Unix and company                         #
#################################################################
#

#################################################################
# Programs used
######

# The most important stuff.

# Gnu CC.
CC         =  gcc

# Vendor-supplied compilers are often named 'cc'.
#CC        =  cc

# Gnu C++.
CXX        =  g++
LD         =  ld
MAKEDEPEND =  makedepend

# Various utilities.
AR         =  ar
GZIP       =  gzip
MAKE       =  gmake
RANLIB     =  ranlib
RM         =  rm
TAR        =  tar
TOUCH      =  touch

#################################################################
# Flags
######
DBGFLAGS = -g 
OPTFLAGS = -O3

LDFLAGS  = -lc -lm 

# GCC.
# db3 doesn't coexist well with -ansi, curiously enough.
SPECIAL  = -pedantic -Wall

# e.g. Sun's supplied compiler for Solaris.
# SPECIAL  = -v -Xc -xtransition


# Defining PARANOID forces the box-counting routines to
# reject radius power series where the multiplier is not
# an integer.  Non-integer multipliers break various
# monotonicity guarantees, and aren't particularly 
# supported.
PARANOID    = -DPARANOID


# This package uses the C++ API of the Berkeley database 
# library.  If you use this, edit the path later in this
# file (BERKELEY_INC, et al); otherwise, set to 0.
USE_BERKELEY = 1

# Enable the provided extensible-hashing code.  Note 
# that this is a rather limited implementation and does
# not in any way support on-disk counters, meaning that
# large data may lead to thrashing followed by out-of-memory
# errors.
USE_EXTHASH  = 1

# Comment out this line to set certain options to default
# to OFF instead of ON.  These options are:
# 
#  -- storing the entire data set in memory
#  -- storing the entire count database in memory 
#  -- two-tables counting algorithm
SPEEDER    = -DSPEEDER


# Set DEBUG = 1 to turn off compiler optimizations.
DEBUG       = 0
COMMONFLAGS = $(INCFLAGS)    $(SPECIAL)  $(PARANOID)  $(SPEEDER)

ifeq ($(DEBUG), 1)
CFLAGS      = $(COMMONFLAGS) $(DBGFLAGS)
CXXFLAGS    = $(COMMONFLAGS) $(DBGFLAGS)
else
CFLAGS      = $(COMMONFLAGS) $(OPTFLAGS)
CXXFLAGS    = $(COMMONFLAGS) $(OPTFLAGS)
endif


GZIPFLAGS   = -9

#################################################################
# Default rules
#####

# Static libraries.
%.a: 
	$(AR) r $@ $?
	$(RANLIB) $@

# Shared libraries.
#
# N.B. -- you'll probably have to add an option for compiling
#         position-independent code when building each object
#         file.  With gcc, it's -fpic.
%.so:
	$(LD) -shared -o $@ $(LDFLAGS) $^

# C objects.
%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

# The next few cover common C++ extensions.
%.o: %.cc
	$(CXX) $(CXXFLAGS) -c -o $@ $<

%.o: %.cpp
	$(CXX) $(CXXFLAGS) -c -o $@ $<

%.o: %.cxx
	$(CXX) $(CXXFLAGS) -c -o $@ $<

%.o: %.C
	$(CXX) $(CXXFLAGS) -c -o $@ $<

#################################################################
# Files
######

DEPEND  = depend.mk
LIBSRC  = DataWrapper.cc DiskWrapper.cc MemoryWrapper.cc \
          BoxCount.cc CrossCount.cc QuadCount.cc


# Enable using the Berkeley database library for storing the
# occupancy tables?  If you do, you should edit the first
# section to specify correct paths and library name.
ifeq ($(USE_BERKELEY), 1) 
BERKELEY     = /usr
BERKELEY_INC = -I$(BERKELEY)/include
BERKELEY_LIB = -L$(BERKELEY)/lib
BERKELEY_LD  = --static -ldb_cxx-3.1
LIBSRC   += BerkeleyLayer.cc
CFLAGS   += -DUSE_BERKELEY=1
CXXFLAGS += -DUSE_BERKELEY=1
INCFLAGS += $(BERKELEY_INC)
LDFLAGS  += $(BERKELEY_LIB) $(BERKELEY_LD)
else
CFLAGS   += -DUSE_BERKELEY=0
CXXFLAGS += -DUSE_BERKELEY=0
endif


# Enable using the extensible-hashing in-memory-only code
# for storing counters?
ifeq ($(USE_EXTHASH), 1) 
LIBSRC   += ExtHash.cc
CFLAGS   += -DUSE_EXTHASH=1
CXXFLAGS += -DUSE_EXTHASH=1
else
CFLAGS   += -DUSE_EXTHASH=0
CXXFLAGS += -DUSE_EXTHASH=0
endif


LIBHDR  = $(LIBSRC:.cc=.h)
LIBOBJ  = $(LIBSRC:.cc=.o)

ALLSRC  = $(LIBSRC) driver.cc
ALLHDR  = $(LIBHDR)
ALLOBJ  = $(ALLSRC:.cc=.o)

#################################################################
# Standard Targets
#####

all:    depend libbox.a driver

depend:  .depend

archive:
	$(RM) -f archive.tar.gz
	$(TAR) -cvf archive.tar $(ALLSRC) $(ALLHDR) RCS *akefile* 
	$(GZIP) $(GZIPFLAGS) archive.tar

clean:
	$(RM) -f $(DEPEND)
	$(RM) -f *.o
	$(RM) -f *.a
	$(RM) -f *.so
	$(RM) -f .depend
	$(RM) -f driver

.depend: $(ALLSRC) $(ALLHDR)
	$(RM) -f $(DEPEND)
	$(TOUCH) $(DEPEND)
	$(MAKEDEPEND) -f $(DEPEND) -- $(CFLAGS) -- *.c
	$(MAKEDEPEND) -f $(DEPEND) -a -- $(CXXFLAGS) -- \
                         *.cc 
	touch .depend

libbox.a:  $(LIBOBJ)


driver:  driver.o libbox.a
	$(CXX) -o driver driver.o -L. -lbox $(LDFLAGS) $(CXXFLAGS)

#################################################################
# Other targets
#####


#################################################################
# For automatic dependency generation
#####

# This is why we use .depend; 'gmake clean' will not auto-regen
# depend.mk...
sinclude depend.mk

