####### Makefile for "BioSig for C/C++" #####################
###
###  Copyright (C) 2006-2020 Alois Schloegl <alois.schloegl@ist.ac.at>
###  This file is part of the "BioSig for C/C++" repository
###  (biosig4c++) at http://biosig.sf.net/
###
##############################################################

##### Target: GNU/Linux
#
## make && make install    build and install libbiosig, but no other tools.
#             libbiosig is a prerequisite for building all the other tools below.
#
## make save2gdf   - makes converter
## make install_save2gdf   - installs converter
#
## make mex4o      - makes mexSLOAD, mexSOPEN for Octave (requires Octave-headers)
## make mex4m      - makes mexSLOAD, mexSOPEN for Matlab (requires Matlab, mex -setup must be configured)
## make mexw32     - makes mexSLOAD.mexw32, mexSOPEN.mexw32 (requires that mingw32, gnumex libraries from Matlab/Win32)
## make mexw64     - makes mexSLOAD.mexw64, mexSOPEN.mexw64 (requires that mce-w32, gnumex libraries from Matlab/Win64)
## make mex        - mex4o, mex4m, mexw32, mexw64 combined
## make biosig4python - makes python interface (requires Python)
## make biosig4java - makes Java interface (experimental)
## make biosig4php - makes PHP interface (experimental)
## make biosig4perl - makes perl interface (experimental)
## make biosig4ruby - makes ruby interface (experimental)
## make biosig4tcl - makes tcl/tk interface (experimental)
##
## make win32 and make win64 are obsolete. save2gdf.exe, and libbiosig.{a,dll} for windows can now be built
## with the mingw-cross-compiler environment (mxe.cc).
##    git clone https://github.com/schloegl/mxe.git
##    make biosig
## should do what you want. Please note, that win32mma does now also rely that libbiosig is built with MXE.
## Make sure that CROSS or CROSS64 is properly defined when running `make`
##
## ???
## make sigviewer  - makes sigviewer

##### Target: Win32
## make win32      - makes save2gdf.exe,libbiosig.lib,libbiosig.dll, for MSWindows, requires MinGW
## make mexw32 mex/mexSLOAD.mexw32   - requires MinGW32 and GNUMEX libraries from Matlab/Win32
## make win32/sigviewer.exe 	- requires sources of SigViewer, and MinGW32 (mex: make suitesparse zlib qt )

##### Target: Win64
## make win64      - makes save2gdf.exe,libbiosig.lib,libbiosig.dll, for MSWindows, requires MinGW
## make mexw64 mex/mexSLOAD.mexw64   - requires MCE-W64 and GNUMEX libraries from Matlab/Win64
## make win64/sigviewer.exe 	- requires sources of SigViewer and MCE-W64, make suitesparse zlib qt 

##### Target: MacOSX w/ homebrew
## make install_homebrew	installs libbiosig and save2gdf
	# requires: brew tap homebrew/dupes
	#	    brew install libiconv

###############################
# whether dynamic or static linking is used, can be controlled with
# LIBEXT. Setting it to 'a' links statically, 'so' links dynamically
#
LIBEXT        = a
#LIBEXT	      = so
###############################


## TARGET dependencies
ifeq (,$(TARGET))
	CC      ?= gcc
	CXX     ?= g++
	AR      := ar rcs
	PKGCONF := pkg-config
ifneq (Darwin,$(shell uname))
	LFLAGS  += -Wl,-z,relro,-z,now
endif
else ifeq (intel,$(TARGET))
	CC      := /opt/intel/bin/icc
	CXX     := /opt/intel/bin/icc
	LD      := /opt/intel/bin/xild
	AR      := /opt/intel/bin/xiar crs
else 
	prefix  := $(dir $(shell which $(TARGET)-gcc))
	CC      := $(TARGET)-gcc
	CXX     := $(TARGET)-g++
	LD      := $(TARGET)-ld
	AR      := $(TARGET)-ar rcs
	PKGCONF := $(TARGET)-pkg-config
	ifeq (mingw, $(findstring mingw, $(TARGET)))
		## add gnulib's getlogin
		SOURCES += win32/getlogin.c win32/getline.c win32/getdelim.c
		OBJECTS += getlogin.o getline.o getdelim.o
		## exclude conflicting definition of sopen from mingw's io.h
		CFLAGS  += -I.
		IO_H_FILE2 = io.h
		CFLAGS  += -I$(prefix)/include
		LIBS    += -lssp
		LDLIBS  += -liconv -lws2_32
	endif
endif

ifeq (Darwin,$(shell uname))
	## Homebrew:
	##	brew tap homebrew/dupes
	##	brew install libiconv
	##
	LD	       = ld
	CFLAGS        += -I/usr/local/opt/libiconv/include
	LDLIBS        += -L/usr/local/opt/libiconv/lib/ -liconv -lstdc++
	LDFLAGS        += -dylib -arch x86_64 -macosx_version_min 10.9
	DLEXT          = dylib
	FULLDLEXT      = ${BIOSIG_VERSION}.dylib
	SONAME_PREFIX  = -install_name # the last space character is crucial
	SONAME_POSTFIX = .${MAJOR_VERSION}.${MINOR_VERSION}.$(DLEXT)
else
	LD	       = $(CXX)
	LDFLAGS       += -shared
	DLEXT          = so
	FULLDLEXT      = so.${BIOSIG_VERSION}
	SONAME_PREFIX  = -Wl,-soname=
	SONAME_POSTFIX = .$(DLEXT).${MAJOR_VERSION}.${MINOR_VERSION}
endif

exec_prefix ?= @prefix@

DEFINES_ALL   = #-D=NDEBUG

LIBS         += $(LDLIBS)

DELETE        = rm -f
COPY          = cp -f
DATA_DIR      = data/
DATA_DIR_CFS  = $(HOME)/L/data/test/CFS/
TEMP_DIR      = test/
VERBOSE	     := -V0

##########################################################
## set Matlab and Octave variables
MATLABDIR ?= $(shell dirname @MATLAB@)

ifeq (.,$(MATLABDIR))
  #$(warning MATLABDIR is not defined)
else
  MEX         = $(MATLABDIR)/mex
  MEX_EXT    := $(shell $(MATLABDIR)/mexext)
endif
##########################################################

first: mex4o 

### Install mexbiosig for Matlab and Octave
install:
	mkdir -p $(DESTDIR)$(exec_prefix)/libexec/biosig/matlab
	install *.mex*   $(DESTDIR)$(exec_prefix)/libexec/biosig/matlab
	@echo "  mexBiosig for Matlab is installed in $(exec_prefix)/libexec/biosig/matlab";
	@echo "  Usage: Start Matlab and addpath ";
	@echo " addpath('$(exec_prefix)/libexec/biosig/matlab')";
	@echo " mexSLOAD";

uninstall:
	# from older source installations
	-${RM} $(DESTDIR)@datadir@/biosig/mex/*
	-cd $(DESTDIR)@datadir@ && rmdir -p biosig
	# from later than 2.0.6 installations
	-${RM} $(DESTDIR)$(exec_prefix)/libexec/biosig/matlab/{mexSLOAD,mexSOPEN,mexSSAVE,physicalunits,*_mex}.mex*
	-cd $(DESTDIR)$(exec_prefix)/libexec && rmdir -p biosig/matlab

#############################################################
#	Compilation: Implicit, default rules
#############################################################


#############################################################
#	MEX-files for Octave and Matlab
#############################################################

# include directory for Win32-Matlab include
W32MAT_INC = $(HOME)/bin/win32/Matlab/R2010b/extern/include/ -I../win32
W64MAT_INC = $(HOME)/bin/win64/Matlab/R2010b/extern/include/ -I../win64
# path to GNUMEX libraries, available from here http://sourceforge.net/projects/gnumex/
GNUMEX   = $(HOME)/bin/win32/gnumex
GNUMEX64 = $(HOME)/bin/win64/gnumex

mexSOPEN.cpp : mexSLOAD.cpp
	echo "#define mexSOPEN" > mexSOPEN.cpp
	cat mexSLOAD.cpp >> mexSOPEN.cpp

MEX_OBJECTS = mexSLOAD.cpp mexSOPEN.cpp mexSSAVE.cpp physicalunits.cpp accovf_mex.cpp sumskipnan_mex.cpp covm_mex.cpp

mex4o:  $(patsubst %.cpp, %.mex, $(MEX_OBJECTS))
oct:    $(patsubst %.cpp, %.oct, $(MEX_OBJECTS))
mexw32: $(patsubst %.cpp, %.mexw32, $(MEX_OBJECTS))
mexw64: $(patsubst %.cpp, %.mexw64, $(MEX_OBJECTS))

ifdef MEX_EXT
mex: mex4o mex4m mexw32 mexw64
mex4m: $(patsubst %.cpp, %.$(MEX_EXT), $(MEX_OBJECTS))

%.$(MEX_EXT): %.cpp
	$(MEX) $(MEX_OPTION) $(DEFINES) -I.. "$<" -L.. -lbiosig -output "$@"

else
mex: mex4o mexw32 mexw64
endif

ifneq (:,@OCTAVE@)
%.mex: %.cpp
	$(MKOCTFILE) $(DEFINES) -I.. -v -g --mex "$<" -L.. -lbiosig -o "$@"

%.oct: %.cpp
	$(MKOCTFILE) $(DEFINES) -I.. "$<" -L.. -lbiosig -o "$@"
endif

%.mexw32: %.cpp
	## $(CROSS)-g++ is used instead of $(CXX), so it can be called from biosig as well as mxe. 
	$(CROSS)-g++ -shared $(GNUMEX)/mex.def -DMATLAB_MEX_FILE $(DEFINES) -x c++ \
		-I$(prefix)/include $(shell $(CROSS)-pkg-config --cflags libbiosig) \
		-I$(W32MAT_INC) -O2 -o "$@" -L$(GNUMEX) -s "$<" -llibmx -llibmex $(shell $(CROSS)-pkg-config --libs libbiosig)

%.mexw64: %.cpp
	$(CROSS64)-g++ -shared $(GNUMEX64)/mex.def -DMATLAB_MEX_FILE $(DEFINES) -x c++ \
		-I$(prefix)/include $(shell $(CROSS64)-pkg-config --cflags libbiosig) \
		-I$(W64MAT_INC) -O2 -o "$@" -L$(GNUMEX64) -s "$<" -llibmx -llibmex $(shell $(CROSS64)-pkg-config --libs libbiosig)

clean:
	-$(DELETE) *.o *.obj *.o64 core octave-core *.oct *.mex* mexSOPEN.cpp

