#makefile for c++ programs
#some tweaks by Brian Pratt for TPP usage, esp. multiplatform builds
#even more tweaks for MapReduce and MPI (X!!Tandem) implementations

# make it possible to build mingw and cygwin on same machine
ifeq ($(BUILD_DIR),)
# no build dir specified, generic usage
BUILD_DIR=../bin
else
# for TPP install we want these files as well
SUPPORTFILES= $(BUILD_DIR)/tandem_params.xml $(BUILD_DIR)/isb_default_input_kscore.xml $(BUILD_DIR)/isb_default_input_native.xml $(BUILD_DIR)/taxonomy.xml
include $(SRC_ROOT)Makefile.incl
endif

EXECUTABLE = $(BUILD_DIR)/tandem

ESCAPED_TANDEM_PARAMETERS_INSTALL_DIR=$(subst \,\\,$(TANDEM_PARAMETERS_INSTALL_DIR))


#EXECUTABLE = $(BUILD_DIR)/p3.exe


#CXXFLAGS denotes flags for the C++ compiler

CXX = g++
CXXFLAGS = $(if $(DEBUG),$(DEBUG),-O2) -DGCC4 -DPLUGGABLE_SCORING $(OSFLAGS) $(ZLIB_INCL) -I $(EXPAT_INCL) -I $(HDF5_INCL) -I $(MZPARSER_INCL)
ifeq (${OS},Windows_NT)
   LDFLAGS = -static -static-libstdc++ 
   # MinGW - Xtandem uses the define "MSVC" to differentiate which thread 
   # library to use so we can't easily choose to use mthreads without using all
   # of MSVC, therefore just use pthreads under Windows+MinGW.  Oh, and don't be
   # fooled by the static link options as pthreads is dynamically linked 
   # regardless.
   LDFLAGS += -lpthread
   # Actually as of pthreads-w32-2.9.1 you can statically link but you need to
   # compile with PTW32_STATIC_LIB defined. If you don't use this option the
   # gcc linker will also complain unless you link against the import library,
   # pthreads.dll
   CXXFLAGS += -DPTW32_STATIC_LIB
else
   LDFLAGS = -lpthread
endif
LDFLAGS += -L/usr/lib -L/sw/lib -lm $(EXPAT_LIB) $(ZLIB_LIB) $(HDF5_LIB) $(MZPARSER_LIB)

# building for MPI?
ifneq ("$(XBANGBANG)","")
XVARIANT = _xbangbang_
LINKCC = mpicxx
CXXFLAGS += -DXBANGBANG
# is it mpich2?
ifneq "$(wildcard /usr/lib64/mpich2/lib/libmpichcxx.a )" ""
CXXFLAGS += -I /usr/include/mpich2-x86_64
LDFLAGS += /usr/lib64/mpich2/lib/libmpichcxx.a /usr/lib64/mpich2/lib/libmpich.a
else
ifneq "$(wildcard /usr/local/mpich2/include )" ""
CXXFLAGS += -I /usr/local/mpich2/include -I /usr/local/mpich2
LDFLAGS += /usr/local/mpich2/lib/libmpichcxx.a /usr/local/mpich2/lib/libmpich.a
else
# is it open mpi?
# as in StarCluster ubuntu
ifneq "$(wildcard /usr/lib/openmpi/include/mpi.h )" ""
CXXFLAGS += -I /usr/lib/openmpi/include
CXX = mpicxx
endif
# as in StarCluster centos
ifneq "$(wildcard /usr/lib64/openmpi/1.4-gcc/include/mpi.h )" ""
CXXFLAGS += -I /usr/lib64/openmpi/1.4-gcc/include
CXX = mpicxx
endif
# as in StarCluster centos
ifneq "$(wildcard /usr/lib/openmpi/1.4-gcc/include/mpi.h )" ""
CXXFLAGS += -I /usr/lib/openmpi/1.4-gcc/include
CXX = mpicxx
endif
endif
endif
EXECUTABLE = $(BUILD_DIR)/bbtandem

else
LINKCC = $(CXX)
endif



.SUFFIXES:	.o .cpp

OBJCLASS = $(ARCH)/$(XVARIANT)

SRCS := $(wildcard *.cpp)
OBJS := $(patsubst %.cpp,$(OBJCLASS)%.o,$(wildcard *.cpp))
DEPS := $(patsubst %.o,%.d,$(OBJS))

all: $(EXECUTABLE) $(SUPPORTFILES)

$(ARCH) :
	mkdir -p $(ARCH)

# define some support files for the win32 TPP installer
$(BUILD_DIR)/tandem_params.xml: ../bin/tandem_params.xml
	cp $< $@
	echo escaped: ${ESCAPED_TANDEM_PARAMETERS_INSTALL_DIR}
	sed 's?_DEFAULT_INPUT_LOCATION_/?${ESCAPED_TANDEM_PARAMETERS_INSTALL_DIR}?g' $@ > ${@}.updated
	mv ${@}.updated $@

$(BUILD_DIR)/isb_default_input_kscore.xml: ../bin/isb_default_input_kscore.xml
	cp $< $@

$(BUILD_DIR)/isb_default_input_native.xml: ../bin/isb_default_input_native.xml
	cp $< $@

$(BUILD_DIR)/taxonomy.xml: ../bin/taxonomy.xml
	cp $< $@

#define the components of the program, and how to link them
#these components are defined as dependencies; that is they must be up-to-date before the code is linked

ifneq (${ARCH},darwin)
XTANDEM_ZLIB_LIB=$(ZLIB_LIB)
else
# on os x 10.7, make will balk at "-lz" as a build dependency
XTANDEM_ZLIB_LIB=
endif

$(EXECUTABLE): $(DEPS) $(OBJS) $(XTANDEM_ZLIB_LIB) $(EXPAT_LIB) $(MZPARSER_LIB) $(HDF5_LIB) $(USER_OBJS)
	$(LINKCC) $(CXXFLAGS) -o $(EXECUTABLE) $(OBJS) $(MZPARSER_LIB) $(HDF5_LIB) $(LDFLAGS) $(ZLIB_LIB) $(USER_OBJS)

#specify the dep files depend on the cpp files

$(OBJCLASS)%.d: %.cpp | $(ARCH)
	$(CXX) -M $(CXXFLAGS) $< > $@
	$(CXX) -M $(CXXFLAGS) $< | sed s/\\.o/.d/ > $@

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

clean:
	rm -f $(OBJS) $(EXECUTABLE) $(DEPS) $(SUPPORTFILES)

explain:
	@echo "The following info represents the program:"
	@echo "Final exec name: $(EXECUTABLE)"
	@echo "Source files:       $(SRCS)"
	@echo "Object files:       $(OBJS)"
	@echo "Dep files:          $(DEPS)"

depend: $(DEPS)
	@echo "Deps are now up-to-date."
 
-include $(DEPS)
