#
###########################
#                         #
#  The Razorback Library  #
#         ,     ,         #
# (C) Andras Aszodi 2000. #
#                         #
###########################
#
# Razorback C++ library Makefile
# ==============================
# 
# Supported architectures:-
# 	SGI:-
#		"irix32": N32 ABI, MIPS-III ISA (R4k,R5k,R8k,R10k,R12k)
#		"irix64": N64 ABI, MIPS-IV ISA (R8k,R10k,R12k)
#	PC:-
#		"linux": ELF Linux/GCC
#	Alpha:-
#		"alpha": Tru64 UNIX with native compilers
# 
# Directory layout
# ================
#
# razorback/cc: root of the C++ hierarchy  <--YOU ARE HERE
#  |
#  +-- obj: compilation is performed in its $(ARCH) subdirectories!
#  |   |
#  |   +-- irix32: N32/MIPS-III
#  |   |
#  |   +-- irix64: N64/MIPS-IV
#  |   |
#  |   +-- linux: GCC/Linux ELF
#  |   |
#  |   +-- alpha: Tru64 UNIX
#  |
#  +-- include: contains symlinks to all C++ utility headers and templates
#  |
#  +-- linalg: linear algebra library source
#  |   |
#  |   +-- templ: template header and implementation files (*.hh, *.cc)
#  |   |
#  |   +-- inccl: header files (*.hh)
#  |   |
#  |   +-- srcc: function definition files (*.cc)
#  |
#  +-- stat: statistics library source
#  |   |
#  |   +-- templ: template header and implementation files (*.hh, *.cc)
#  |   |
#  |   +-- inccl: header files (*.hh)
#  |   |
#  |   +-- srcc: function definition files (*.cc)
#  |
#  +-- bio: bioinformatics library source
#  |   |
#  |   +-- inccl: header files (*.hh)
#  |   |
#  |   +-- srcc: function definition files (*.cc)
#  |
#  +-- MThread: POSIX multithread wrapper library source
#  |   |
#  |   +-- inccl: header files (*.hh)
#  |   |
#  |   +-- srcc: function definition files (*.cc)
#  |
#  +-- except: utility exception library source
#  |   |
#  |   +-- inccl: header files (*.hh)
#  |   |
#  |   +-- srcc: function definition files (*.cc)
#  |
#  +-- misc: other modules which are not part of a library
#      |
#      +-- templ: template header and implementation files (*.hh, *.cc)
#      |
#      +-- inccl: header files (*.hh)
#      |
#      +-- srcc: function definition files (*.c)

# Usage:
# Invoked from the Razorback library Top Makefile in $RAZORBACK_ROOT.

# The shell
SHELL = /bin/sh

# The platform-dependent macro definitions, made by the configure script
# The ../ things are relative to the cc/obj/<ARCH> subdirectory
# where the compilation is done.
include ../../../Makefile.defs

# ---- MAIN RULES ----

# Make the library. (default).
# The static library is provided only as a courtesy.
# Note that the C part of the library is called "razorback",
# while the C++ library is spelled as "RazorBack".
all: libRazorBack.so.$(MAJOR).$(MINOR) libRazorBack.a

# cleanup
clean:
	rm -f *.a *.so *.so.$(MAJOR) *.so.$(MAJOR).$(MINOR) *.o

# ---- C++ LIBRARIES ----

# TEMPLATE notes:
# Some template modules are in two files, *.hh (interface) and *.cc (methods).
# Since logically the full template definition is still a header file,
# and the *.cc definition files must be #include-d (either automatically by the
# compiler or by the user by defining INCLUDE_TMPL_DEFS) anyway,
# both template declaration and definition files live in "templ"
# subdirectories. When specifying dependencies in Make rules,
# both the *.hh and *.cc files must be mentioned.
#
# On SGI systems, the template prelinker must be invoked
# on archive library components. The command is in the macro $(TMPLINK).
# A harmless command ('echo') is defined for systems without prelinkers.
# This is taken care of by the configure script.
# 
# Template instantiation+DSO (SGI-specific hack):
# the .ii files generated while making the static libraries
# confuse the DSO-making process: therefore the 'ii_files' directory
# is hidden as 'ii_xxx' while the DSO-s are made.
# G++ under Linux performs instantiation automagically.

# ---- Exceptions for the utility modules ----

# Source directory
UTILSEXC_SRC = ../../except/srcc

# Object files
UTILSEXC_OBJS = Utilsexc.o Rangedimexc.o

# Exception base class
Utilsexc.o: $(UTILSEXC_SRC)/Utilsexc.cc $(CC_INCLUDE)/Utilsexc.hh
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) -c $(UTILSEXC_SRC)/Utilsexc.cc -o $@

# Dimension and index range exceptions
Rangedimexc.o: $(CC_INCLUDE)/Utilsexc.hh \
		$(UTILSEXC_SRC)/Rangedimexc.cc $(CC_INCLUDE)/Rangedimexc.hh 
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) -c $(UTILSEXC_SRC)/Rangedimexc.cc -o $@

# ---- Linear algebra ----

# Source directory
LINALG_SRC = ../../linalg/srcc

# Object files
LINALG_OBJS = Lu.o Rsymdiag.o Safety.o Squarexc.o Svd.o

# Lu-decomposition
Lu.o: $(LINALG_SRC)/Lu.cc $(CC_INCLUDE)/Lu.hh \
		$(CC_INCLUDE)/Refstorage.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Squarexc.hh \
		$(CC_INCLUDE)/Basemat.hh $(CC_INCLUDE)/Basemat.cc \
		$(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Rectmat.cc \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Vector.cc
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(LINALG_SRC)/Lu.cc -o $@
	$(TMPLINK) $@

# Symmetric real matrix diagonalisation routines
Rsymdiag.o: $(LINALG_SRC)/Rsymdiag.cc $(CC_INCLUDE)/Rsymdiag.hh \
		$(CC_INCLUDE)/Refstorage.hh $(CC_INCLUDE)/Fparch.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Basemat.hh $(CC_INCLUDE)/Basemat.cc \
		$(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Rectmat.cc \
		$(CC_INCLUDE)/Symmat.hh $(CC_INCLUDE)/Symmat.cc \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Vector.cc
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(LINALG_SRC)/Rsymdiag.cc -o $@
	$(TMPLINK) $@

# Auxiliary class for safe division
Safety.o: $(LINALG_SRC)/Safety.cc $(CC_INCLUDE)/Safety.hh $(CC_INCLUDE)/Fparch.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(LINALG_SRC)/Safety.cc -o $@
	$(TMPLINK) $@

# Square matrix exception
Squarexc.o: $(CC_INCLUDE)/Rangedimexc.hh \
		$(LINALG_SRC)/Squarexc.cc $(CC_INCLUDE)/Squarexc.hh 
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) -c $(LINALG_SRC)/Squarexc.cc -o $@

# Singular value decomposition (real matrices)
Svd.o: $(LINALG_SRC)/Svd.cc $(CC_INCLUDE)/Svd.hh \
		$(CC_INCLUDE)/Refstorage.hh $(CC_INCLUDE)/Safety.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Basemat.hh $(CC_INCLUDE)/Basemat.cc \
		$(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Rectmat.cc \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Vector.cc
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(LINALG_SRC)/Svd.cc -o $@
	$(TMPLINK) $@

# ---- Statistics ----

# Source directory
STAT_SRC = ../../stat/srcc

# Object files
STAT_OBJS = Anova1.o Distrapprox.o Distrfunc.o Factanal.o Mvn.o Paramest.o \
    	    Linreg.o Linls.o Nonlinreg.o Orthpoly.o Random.o Spl.o \
	    Stat2.o Statprob.o Statexc.o

# One-way ANOVA
Anova1.o: $(CC_INCLUDE)/Anova1.hh $(STAT_SRC)/Anova1.cc \
		$(CC_INCLUDE)/Statprob.hh $(CC_INCLUDE)/Statexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
		-c $(STAT_SRC)/Anova1.cc -o $@
	$(TMPLINK) $@

# Univariate distributions approximated by histograms
Distrapprox.o: $(CC_INCLUDE)/Distrapprox.hh $(STAT_SRC)/Distrapprox.cc \
		$(CC_INCLUDE)/Distrbase.hh $(CC_INCLUDE)/Random.hh \
		$(CC_INCLUDE)/Stat2.hh $(CC_INCLUDE)/Iovar.hh $(CC_INCLUDE)/Rangedimexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
		-c $(STAT_SRC)/Distrapprox.cc -o $@
	$(TMPLINK) $@

# Analytically known univariate distributions
Distrfunc.o: $(CC_INCLUDE)/Distrfunc.hh $(STAT_SRC)/Distrfunc.cc \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Statexc.hh \
		$(CC_INCLUDE)/Distrbase.hh $(CC_INCLUDE)/Random.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
		-c $(STAT_SRC)/Distrfunc.cc -o $@
	$(TMPLINK) $@

# Factor analysis
Factanal.o: $(CC_INCLUDE)/Factanal.hh $(STAT_SRC)/Factanal.cc \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Stat2.hh $(CC_INCLUDE)/Rsymdiag.hh \
		$(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Rectmat.cc \
		$(CC_INCLUDE)/Symmat.hh $(CC_INCLUDE)/Symmat.cc \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Vector.cc
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
			-c $(STAT_SRC)/Factanal.cc -o $@
	$(TMPLINK) $@

# Linear regression (traditional, with normal equations)
Linreg.o: $(CC_INCLUDE)/Linreg.hh $(STAT_SRC)/Linreg.cc $(CC_INCLUDE)/Paramest.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Statexc.hh \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Symmat.hh
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) $(TMPLOPTS) \
		-c $(STAT_SRC)/Linreg.cc -o $@
	$(TMPLINK) $@

# Linear regression (based on SVD, more robust)
Linls.o: $(CC_INCLUDE)/Linls.hh $(STAT_SRC)/Linls.cc \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
    	    	$(CC_INCLUDE)/Svd.hh $(CC_INCLUDE)/Vector.hh \
		$(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Symmat.hh
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) $(TMPLOPTS) \
		-c $(STAT_SRC)/Linls.cc -o $@
	$(TMPLINK) $@

# Multivariate normal distribution
Mvn.o: $(CC_INCLUDE)/Mvn.hh $(STAT_SRC)/Mvn.cc \
		$(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Symmat.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Rsymdiag.hh $(CC_INCLUDE)/Bits.hh \
		$(CC_INCLUDE)/Distrfunc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
		-c $(STAT_SRC)/Mvn.cc -o $@
	$(TMPLINK) $@

# Nonlinear regression (traditional Levenberg/Marquardt)
Nonlinreg.o: $(CC_INCLUDE)/Nonlinreg.hh $(STAT_SRC)/Nonlinreg.cc $(CC_INCLUDE)/Paramest.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Statexc.hh \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Symmat.hh
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) $(TMPLOPTS) \
		-c $(STAT_SRC)/Nonlinreg.cc -o $@
	$(TMPLINK) $@

# Regression with orthogonal polynomials
Orthpoly.o: $(CC_INCLUDE)/Orthpoly.hh $(STAT_SRC)/Orthpoly.cc \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Statexc.hh \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Symmat.hh
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) $(TMPLOPTS) \
		-c $(STAT_SRC)/Orthpoly.cc -o $@
	$(TMPLINK) $@

# Traditional least-squares regressions (linear, nonlinear) base class
Paramest.o: $(CC_INCLUDE)/Paramest.hh $(STAT_SRC)/Paramest.cc \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh \
		$(CC_INCLUDE)/Vector.hh $(CC_INCLUDE)/Rectmat.hh $(CC_INCLUDE)/Symmat.hh
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) $(TMPLOPTS) \
		-c $(STAT_SRC)/Paramest.cc -o $@
	$(TMPLINK) $@

# Random number generators
Random.o: $(CC_INCLUDE)/Random.hh $(STAT_SRC)/Random.cc
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) -c $(STAT_SRC)/Random.cc -o $@

# Cubic splines
Spl.o: $(STAT_SRC)/Spl.cc $(CC_INCLUDE)/Spl.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
                -c $(STAT_SRC)/Spl.cc -o $@
	$(TMPLINK) $@
		
# Simple avg, SD, corr for 1 and 2 variables
Stat2.o: $(CC_INCLUDE)/Stat2.hh $(STAT_SRC)/Stat2.cc \
    	    $(CC_INCLUDE)/Statexc.hh $(CC_INCLUDE)/Iovar.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) \
	-I$(CC_INCLUDE) -c $(STAT_SRC)/Stat2.cc -o $@
	$(TMPLINK) $@

# Stat test probability distributions
Statprob.o: $(CC_INCLUDE)/Statprob.hh $(STAT_SRC)/Statprob.cc \
    	    $(CC_INCLUDE)/Rangedimexc.hh
	$(CXX) $(CCFLAGS) $(PIC) \
	-I$(CC_INCLUDE) -c $(STAT_SRC)/Statprob.cc -o $@

# Statistics exceptions
Statexc.o: $(CC_INCLUDE)/Utilsexc.hh \
		$(STAT_SRC)/Statexc.cc $(CC_INCLUDE)/Statexc.hh 
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) -c $(STAT_SRC)/Statexc.cc -o $@

# ---- Biological sequences ----

# Source directory
BIOSEQ_SRC = ../../bio/srcc

# Object files
BIOSEQ_OBJS = Alignment.o Bioseq.o Bioseqio.o Gapseq.o Monomer.o

# Aligned sequences
Alignment.o: $(BIOSEQ_SRC)/Alignment.cc $(CC_INCLUDE)/Alignment.hh $(CC_INCLUDE)/Gapseq.hh \
		$(CC_INCLUDE)/Bioseq.hh $(CC_INCLUDE)/Monomer.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(BIOSEQ_SRC)/Alignment.cc -o $@
	$(TMPLINK) $@
	
# Biological sequences
Bioseq.o: $(BIOSEQ_SRC)/Bioseq.cc $(CC_INCLUDE)/Bioseq.hh $(CC_INCLUDE)/Bioseqio.hh \
		$(CC_INCLUDE)/Monomer.hh $(CC_INCLUDE)/Utilsexc.hh  $(CC_INCLUDE)/Rangedimexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(BIOSEQ_SRC)/Bioseq.cc -o $@
	$(TMPLINK) $@
	
# I/O operations for biological sequences
Bioseqio.o: $(BIOSEQ_SRC)/Bioseqio.cc $(CC_INCLUDE)/Bioseqio.hh \
		$(CC_INCLUDE)/Monomer.hh $(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(BIOSEQ_SRC)/Bioseqio.cc -o $@
	$(TMPLINK) $@
	
# Gapped biological sequences
Gapseq.o: $(BIOSEQ_SRC)/Gapseq.cc $(CC_INCLUDE)/Gapseq.hh \
		$(CC_INCLUDE)/Bioseq.hh $(CC_INCLUDE)/Monomer.hh \
		$(CC_INCLUDE)/Utilsexc.hh $(CC_INCLUDE)/Rangedimexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(BIOSEQ_SRC)/Gapseq.cc -o $@
	$(TMPLINK) $@
	
# Monomer alphabets
Monomer.o: $(BIOSEQ_SRC)/Monomer.cc $(CC_INCLUDE)/Monomer.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(BIOSEQ_SRC)/Monomer.cc -o $@
	$(TMPLINK) $@

# ---- POSIX multithread wrappers ----

# Source directory
MTHREAD_SRC = ../../mthread/srcc

# Object files
MTHREAD_OBJS = MTmgr.o MTqueue.o MTsync.o

# Thread management (launch, reap)
MTmgr.o: $(MTHREAD_SRC)/MTmgr.cc $(CC_INCLUDE)/MTmgr.hh $(CC_INCLUDE)/Utilsexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
                -c $(MTHREAD_SRC)/MTmgr.cc -o $@
	$(TMPLINK) $@

# Job priority queue
MTqueue.o: $(MTHREAD_SRC)/MTqueue.cc $(CC_INCLUDE)/MTqueue.hh $(CC_INCLUDE)/MTsync.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
                -c $(MTHREAD_SRC)/MTqueue.cc -o $@
	$(TMPLINK) $@

# Thread synchronisation
MTsync.o: $(MTHREAD_SRC)/MTsync.cc $(CC_INCLUDE)/MTsync.hh 
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) \
                -c $(MTHREAD_SRC)/MTsync.cc -o $@
	$(TMPLINK) $@

# ---- Miscellaneous modules ----

# Source directory
MISC_SRC = ../../misc/srcc

# Object files
MISC_OBJS = Bits.o Symvar.o

# Bit vectors
Bits.o: $(CC_INCLUDE)/Bits.hh $(MISC_SRC)/Bits.cc $(CC_INCLUDE)/Rangedimexc.hh
	$(CXX) $(CCFLAGS) $(PIC) -I$(CC_INCLUDE) -c $(MISC_SRC)/Bits.cc -o $@

# Symbolic variables (allowed value is a string out of a predefined set)
Symvar.o: $(CC_INCLUDE)/Symvar.hh $(MISC_SRC)/Symvar.cc $(CC_INCLUDE)/Utilsexc.hh
	$(CXX) $(CCFLAGS) $(PIC) $(TMPLOPTS) -I$(CC_INCLUDE) -c $(MISC_SRC)/Symvar.cc -o $@
	$(TMPLINK) $@

# =====================================================

# All C++ object files together (both library members and the "misc")
RAZORBACK_CCOBJS = $(UTILSEXC_OBJS) $(LINALG_OBJS) $(STAT_OBJS) \
    	$(BIOSEQ_OBJS) $(MTHREAD_OBJS) $(MISC_OBJS)

# The DSO depends on the external POSIX thread library, add to compilation line
EXTLIBS = -lpthread

# Razorback C++ library
# Symlinks will be built by the installation script
# as recommended in the Linux ELF Howto:-
# libRazorBack.so -> libRazorBack.so.MAJOR -> libRazorBack.so.MAJOR.MINOR
libRazorBack.so.$(MAJOR).$(MINOR): $(RAZORBACK_CCOBJS)
	if ( [ -d ii_files ] ) then mv ii_files ii_xxx; fi
	$(CCDSO_CMD) $(SONAME)libRazorBack.so.$(MAJOR) \
	    -o $@ $(RAZORBACK_CCOBJS) $(EXTLIBS)
	if ( [ -d ii_xxx ] ) then mv ii_xxx ii_files; fi

# Static archive
libRazorBack.a: $(RAZORBACK_CCOBJS)
	$(AR) $(ARFLAGS) $@ $(RAZORBACK_CCOBJS)
