SHELL=/bin/sh

.SUFFIXES:

OBJDIR    =./obj
DOBJDIR   =./dobj
SOOBJDIR  =./soobj
SODOBJDIR =./sodobj
OUTDIR    =../../lib
FLIBDIR   =../ftn

ifdef VERBOSE
AT   =
else
AT   = @
endif

ECHO = $(AT)echo
ifdef ICC
  CC = icpc
else
  CC = g++
endif
AR = ar cr

LIBS=-lgfortran
DLIBS=-lgfortran

#ifeq ($(OSTYPE),linux)
ifdef COMSPEC
  COMMON_LFLAGS = -L$(OUTDIR) 
  LIBS += -lftn_cygwin_missing -lftn
  DLIBS+= -lftn_cygwin_missing -lftn_debug
else
  LIBS += -lpthread -lpthread_nonshared
  DLIBS+= -lpthread -lpthread_nonshared
endif

ifdef EM64T
  # for pre-installed versions like in Fedora x64
  ifdef LD_LIBRARY_PATH  
    $(LD_LIBRARY_PATH)+=/usr/lib64
  else
    LD_LIBRARY_PATH=/usr/lib64
  endif

  ifdef MKL
    FLIB  = libftn_mkl_em64t.a
    DFLIB = libftn_mkl_em64t_debug.a
  else
    FLIB  = libftn_em64t.a
    DFLIB = libftn_em64t_debug.a
  endif
  SONAME   = libcvm_em64t.so
  SODNAME  = libcvm_em64t_debug.so
  LIBNAME  = libcvm_em64t.a
  LIBDNAME = libcvm_em64t_debug.a
else
  ifdef MKL
    FLIB  = libftn_mkl.a
    DFLIB = libftn_mkl_debug.a
  else
    FLIB  = libftn.a
    DFLIB = libftn_debug.a
  endif
  SONAME   = libcvm.so
  SODNAME  = libcvm_debug.so
  LIBNAME  = libcvm.a
  LIBDNAME = libcvm_debug.a
endif


ifdef ACML
  ifndef ACML_PATH
    ifdef EM64T
      ACML_PATH=/opt/acml4.0.1/
    else
      ifdef IFORT
        ACML_PATH=/opt/acml3.6.0/
      else
        ACML_PATH=/opt/acml3.6.1/
      endif
    endif
  endif
  ifdef IFORT
    ifdef EM64T
      ACML_PATHL=$(ACML_PATH)/ifort64/lib/
    else
      ACML_PATHL=$(ACML_PATH)/ifort32/lib/
    endif
  else
    ifdef EM64T
      ACML_PATHL=$(ACML_PATH)/gfortran64/lib/
    else
      ACML_PATHL=$(ACML_PATH)/gfortran32/lib/
    endif
  endif
  ACML_FLAG=-L$(ACML_PATHL)
  LIBS  += -lacml
  DLIBS += -lacml
  ifdef EM64T
    LIBS += -lacml_mv
    DLIBS += -lacml_mv
  endif
  COMMON_FLAGS += -DCVM_ACML=1
  COMMON_LFLAGS += -Wl,-rpath,$(ACML_PATHL)
else
ifdef ACML_MP
  ifndef ACML_PATH
    ifdef EM64T
      ACML_PATH=/opt/acml4.0.1/
    else
      ifdef IFORT
        ACML_PATH=/opt/acml3.6.0/
      else
        ACML_PATH=/opt/acml3.6.1/
      endif
    endif
  endif
  ifdef IFORT
    ifdef EM64T
      ACML_PATHL=$(ACML_PATH)/ifort64_mp/lib/
    else
      ACML_PATHL=$(ACML_PATH)/ifort32_mp/lib/
    endif
  else
    ifdef EM64T
      ACML_PATHL=$(ACML_PATH)/gfortran64_mp/lib/
    else
      ACML_PATHL=$(ACML_PATH)/gfortran32_mp/lib/
    endif
  endif
  ACML_FLAG=-L$(ACML_PATHL)
  LIBS  += -lacml_mp
  DLIBS += -lacml_mp
  ifdef EM64T
    LIBS += -lacml_mv
    DLIBS += -lacml_mv
  endif
  COMMON_FLAGS += -DCVM_ACML=1
  COMMON_LFLAGS += -Wl,-rpath,$(ACML_PATHL)
else
ifdef MKL
  # Intel MKL 10.0 library:
  ifndef MKL_PATH
    MKL_PATH=/opt/intel/mkl/10.0.011/lib/
  endif
  ifdef EM64T
    MKL_PATHL=$(MKL_PATH)/em64t
#    LIBS  += -lmkl -lguide
#    DLIBS += -lmkl -lguide
     LIBS  += -lmkl_core -lmkl_lapack -lmkl_em64t -lguide
     DLIBS += -lmkl_core -lmkl_lapack -lmkl_em64t -lguide
  else
    MKL_PATHL=$(MKL_PATH)/32
#    LIBS  += -lmkl -lguide
#    DLIBS += -lmkl -lguide
     LIBS  += -lmkl_core -lmkl_lapack -lmkl_ia32 -lguide
     DLIBS += -lmkl_core -lmkl_lapack -lmkl_ia32 -lguide
  endif
  MKL_FLAG=-L$(MKL_PATHL)
  COMMON_LFLAGS += -Wl,-rpath,$(MKL_PATHL)
else
  LIBS  += -llapack -lblas
  DLIBS += -llapack -lblas
#  DLIBS += -llapack_debug -lblas_debug
endif
endif
endif


ifdef IFORT
  LIBS  += -lifcoremt -liomp5
  DLIBS += -lifcoremt -liomp5
  ifndef IFORT_PATH
    ifdef EM64T
      IFORT_PATH=/opt/intel/fce/10.1.015/
    else 
      IFORT_PATH=/opt/intel/fc/10.1.015/
    endif
  endif
  IFORT_FLAG = -L$(IFORT_PATH)/lib
endif

COMMON_FLAGS += -Wall
ifdef CVM_FLOAT
  COMMON_FLAGS += -DCVM_FLOAT
endif

ifdef CVM_STLPORT
  COMMON_FLAGS += -I/usr/include/stlport
  LIBS  += -lstlport
  DLIBS += -lstlportg
endif

CFLAGS    =$(COMMON_FLAGS) -O3
CFLAGSD   =$(COMMON_FLAGS) -g -DDEBUG
SOCFLAGS  =$(CFLAGS) -D_REENTRANT -DCVM_EXPORTS
SOCFLAGSD =$(CFLAGSD) -D_REENTRANT -DCVM_EXPORTS


ifeq ($(OSTYPE),linux)
  SOCFLAGS += -fPIC
  SOCFLAGSD += -fPIC
endif

LFLAGS  += $(COMMON_LFLAGS) -L$(OUTDIR) -shared
LFLAGSD += $(COMMON_LFLAGS) -L$(OUTDIR) -shared

ifdef PROF
  CFLAGSD += -pg
  LFLAGSD += -pg
endif

all : release debug
ifdef STATIC_ONLY
  release: $(OUTDIR)/$(LIBNAME)
  debug:   $(OUTDIR)/$(LIBDNAME)
else
  release: $(OUTDIR)/$(LIBNAME) $(OUTDIR)/$(SONAME)
  debug:   $(OUTDIR)/$(LIBDNAME) $(OUTDIR)/$(SODNAME)
endif

SOURCES=$(wildcard *.cpp)
OBJS=$(patsubst %.cpp, $(OBJDIR)/%.o, $(SOURCES))
DOBJS=$(patsubst %.cpp, $(DOBJDIR)/%.o, $(SOURCES))
SOOBJS=$(patsubst %.cpp, $(SOOBJDIR)/%.o, $(SOURCES))
SODOBJS=$(patsubst %.cpp, $(SODOBJDIR)/%.o, $(SOURCES))

#$(call make-depend,source-file,object-file,depend-file)
define make-depend
  $(AT)$(CC) -MM -MF $3 -MP -MT $2 $(COMMON_FLAGS) $1
endef

$(OUTDIR)/$(LIBNAME): $(OBJS)
	$(ECHO) Archiving: $@
	$(AT)$(AR) $@ $^

$(OUTDIR)/$(LIBDNAME): $(DOBJS)
	$(ECHO) Archiving: $@
	$(AT)$(AR) $@ $^

$(OUTDIR)/$(FLIB):
	make release -C $(FLIBDIR) $(MAKECMD)

$(OUTDIR)/$(DFLIB):
	make debug -C $(FLIBDIR) $(MAKECMD)

$(OUTDIR)/$(SONAME): $(SOOBJS) $(OUTDIR)/$(FLIB)
	$(AT)if [ ! -d $(OUTDIR) ]; then mkdir $(OUTDIR); fi
	$(ECHO) Linking: $@
	$(AT)$(CC) $(LFLAGS) -Wl,-soname,$(SONAME) -o $@ $^ $(MKL_FLAG) $(ACML_FLAG) $(IFORT_FLAG) -Wl,--start-group $(LIBS) -Wl,--end-group

$(OUTDIR)/$(SODNAME): $(SODOBJS) $(OUTDIR)/$(DFLIB)
	$(AT)if [ ! -d $(OUTDIR) ]; then mkdir $(OUTDIR); fi
	$(ECHO) Linking: $@
	$(AT)$(CC) $(LFLAGSD) -Wl,-soname,$(SODNAME) -o $@ $^ $(MKL_FLAG) $(ACML_FLAG) $(IFORT_FLAG) -Wl,--start-group $(DLIBS) -Wl,--end-group

$(OBJDIR)/%.o: %.cpp
	$(AT)if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR); fi
	$(call make-depend,$<,$@,$(subst .o,.d,$@))
	$(ECHO) Compiling release: $<
	$(AT)$(CC) $(CFLAGS) -c -o $@ $<

$(DOBJDIR)/%.o: %.cpp
	$(AT)if [ ! -d $(DOBJDIR) ]; then mkdir $(DOBJDIR); fi
	$(call make-depend,$<,$@,$(subst .o,.d,$@))
	$(ECHO) Compiling debug: $<
	$(AT)$(CC) $(CFLAGSD) -c -o $@ $<

$(SOOBJDIR)/%.o: %.cpp
	$(AT)if [ ! -d $(SOOBJDIR) ]; then mkdir $(SOOBJDIR); fi
	$(call make-depend,$<,$@,$(subst .o,.d,$@))
	$(ECHO) Compiling release: $<
	$(AT)$(CC) $(SOCFLAGS) -c -o $@ $<

$(SODOBJDIR)/%.o: %.cpp
	$(AT)if [ ! -d $(SODOBJDIR) ]; then mkdir $(SODOBJDIR); fi
	$(call make-depend,$<,$@,$(subst .o,.d,$@))
	$(ECHO) Compiling debug: $<
	$(AT)$(CC) $(SOCFLAGSD) -c -o $@ $<

clean:
	$(ECHO) Cleaning...
	$(AT)rm -rf $(OBJDIR) $(DOBJDIR) $(SOOBJDIR) $(SODOBJDIR) $(OUTDIR)/libcvm*

ifneq "$(MAKECMDGOALS)" "clean"
  -include $(OBJDIR)/*.d $(DOBJDIR)/*.d $(SOOBJDIR)/*.d $(SODOBJDIR)/*.d
endif
