#!/usr/bin/make -f

export DH_VERBOSE=1

# Get version from changelog as well as lsb_release
# to compute unique build version (useful for repo mirroring systems doing file pooling)
PKG_VERSION  := $(shell dpkg-parsechangelog | grep -E '^Version:' | cut -d' ' -f2)
DIST_NAME    := $(shell lsb_release -si)
DIST_RELEASE := $(shell lsb_release -sc)
DIST_VERSION := $(shell lsb_release -sr)
PKG_VERSION_TAG := $(PKG_VERSION)+$(DIST_NAME).$(DIST_RELEASE).$(DIST_VERSION)
SUBSTVARS_BINARY_VERSION := -Vbinary:Version="$(PKG_VERSION_TAG)"
SUBSTVARS_SOURCE_VERSION := -Vsource:Version="$(PKG_VERSION_TAG)"
DEB_TARGET_GNU_TYPE := $(shell dpkg-architecture -qDEB_TARGET_GNU_TYPE)

# Compute very strict dependency on libcudnn as it seems to be tighten
# To a specific CUDA version
ifeq (,$(filter nocuda,$(DEB_BUILD_PROFILES)))
  CUDNN_PACKAGE := $(shell dpkg-query -W -f='$${Package}' libcudnn?)
  CUDNN_VERSION := $(shell dpkg-query -W -f='$${Version}' libcudnn?)
  SUBSTVARS_CUDNN := -Vcudnn:Depends="$(CUDNN_PACKAGE) (= $(CUDNN_VERSION))"
  SUBSTVARS_CUDNNDEV := -Vcudnndev:Depends="$(CUDNN_PACKAGE)-dev (= $(CUDNN_VERSION))"
endif

# Default build options
DEFAULT_OPTIONS := -DUSE_OPENCV=1
DEFAULT_OPTIONS += -DUSE_OPENMP=1
DEFAULT_OPTIONS += -DUSE_LAPACK=1
# https://github.com/apache/incubator-mxnet/issues/8569
# gperftools breaks compatibily with OpenCV
DEFAULT_OPTIONS += -DUSE_GPERFTOOLS=0
DEFAULT_OPTIONS += -DUSE_JEMALLOC=1
DEFAULT_OPTIONS += -DUSE_PROFILER=1
# Because it triggers protobuf requirement
# And linking fails on recent distros because C++ ABI being different
# between protobuf built with GCC 5+ and MXNet with GCC 4.) (CUDA builds)
DEFAULT_OPTIONS += -DUSE_DIST_KVSTORE=0
DEFAULT_OPTIONS += -DUSE_PLUGINS_WARPCTC=0
DEFAULT_OPTIONS += -DUSE_PLUGIN_CAFFE=0
DEFAULT_OPTIONS += -DUSE_CPP_PACKAGE=0
DEFAULT_OPTIONS += -DGTEST_ROOT=/usr/src/googletest/

# CUDA specific build options
WITH_CUDA_OPTIONS := -DUSE_CUDA=1 -DUSE_CUDNN=1 -DCUDA_ARCH_NAME=All -D_GLIBCXX_USE_CXX11_ABI=1
WITHOUT_CUDA_OPTIONS := -DUSE_CUDA=0 -DUSE_CUDNN=0

# Intel MKL DNN build options
WITH_MKL_DNN_OPTIONS := -DUSE_MKL_IF_AVAILABLE=1 -DUSE_MKLML_MKL=1
WITHOUT_MKL_DNN_OPTIONS := -DUSE_MKL_IF_AVAILABLE=0

# CUDA library requires old GCC versions
CPU_CC  := /usr/bin/gcc
CPU_CXX := /usr/bin/g++
CUDA_CC  := /usr/bin/gcc-4.9
CUDA_CXX := /usr/bin/g++-4.9

# Python dependencies, by hand
# Otherwise it picks trac-graphviz as a dependency lol
SUBSTVARS_PYTHON := -Vpython:ManualDepends="python-requests,python-numpy"
SUBSTVARS_PYTHON += -Vpython3:ManualDepends="python3-requests,python3-numpy"
SUBSTVARS_PYTHON += -Vpython:ManualRecommends="python-opencv,python-graphviz"
SUBSTVARS_PYTHON += -Vpython3:ManualRecommends="python3-opencv,python3-graphviz"

# dh-r is broken :(
# https://github.com/chronitis/dh-r/issues/1
# Information extracted from /usr/share/perl5/Debian/Debhelper/Buildsystem/R.pm
# RBASE_VERSION := $(shell dpkg-query -W -f='$${Version}' r-base-dev)
# RAPI_VERSION  := $(shell dpkg-query -W -f='$${Provides}' r-base-core | grep -o 'r-api[^, ]*')
# R_BUILD_DEPS  := $(shell grep -A 1 @@@@R_DEPS_TOKEN@@@@ debian/control | tail -n 1)
# SUBSTVARS_R_DEPENDS := -VR:Depends="r-base-core (>= $(RBASE_VERSION)), $(RAPI_VERSION), $(R_BUILD_DEPS)"


%:
	dh $@ --with python2,python3 --parallel --buildsystem=cmake


override_dh_auto_clean:
	dh_auto_clean
	rm -rf "$(CURDIR)/debian/build"
	rm -rf "$(CURDIR)/debian/install"
	# Generate CPP headers depending on CUDA being enabled or not
	rm -f "$(CURDIR)/cpp-package/include/mxnet-cpp/op.h"
	# Python stuff
	find "$(CURDIR)" -name '*.pyc' -delete
	rm -rf "$(CURDIR)/.pybuild"
	rm -rf "$(CURDIR)/python/mxnet.egg-info"
	rm -f "$(CURDIR)/python/mxnet/ndarray/"gen_*.py
	rm -f "$(CURDIR)/python/mxnet/symbol/"gen_*.py


override_dh_auto_configure:
	# Standard build
	export CC=$(CPU_CC); \
	export CXX=$(CPU_CXX); \
	dh_auto_configure --builddirectory="$(CURDIR)/debian/build/generic/" -- \
	                  $(DEFAULT_OPTIONS) \
	                  $(WITHOUT_CUDA_OPTIONS) \
	                  $(WITHOUT_MKL_DNN_OPTIONS)
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With MKL DNN
	export CC=$(CPU_CC); \
	export CXX=$(CPU_CXX); \
	dh_auto_configure --builddirectory="$(CURDIR)/debian/build/mkl-dnn/" -- \
	                  $(DEFAULT_OPTIONS) \
	                  $(WITHOUT_CUDA_OPTIONS) \
	                  $(WITH_MKL_DNN_OPTIONS)
endif
ifeq (,$(filter nocuda,$(DEB_BUILD_PROFILES)))
	# With CUDA
	export CC=$(CUDA_CC); \
	export CXX=$(CUDA_CXX); \
	dh_auto_configure --builddirectory="$(CURDIR)/debian/build/cuda/" -- \
	                  $(DEFAULT_OPTIONS) \
	                  $(WITH_CUDA_OPTIONS) \
	                  $(WITHOUT_MKL_DNN_OPTIONS)
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With CUDA and MKL DNN
	export CC=$(CUDA_CC); \
	export CXX=$(CUDA_CXX); \
	dh_auto_configure --builddirectory="$(CURDIR)/debian/build/cuda-mkl-dnn/" -- \
	                  $(DEFAULT_OPTIONS) \
	                  $(WITH_CUDA_OPTIONS) \
	                  $(WITH_MKL_DNN_OPTIONS)
endif
endif


override_dh_auto_build:
	# Standard build
	dh_auto_build --builddirectory="$(CURDIR)/debian/build/generic/"
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With MKL DNN
	dh_auto_build --builddirectory="$(CURDIR)/debian/build/mkl-dnn/"
endif
ifeq (,$(filter nocuda,$(DEB_BUILD_PROFILES)))
	# With CUDA
	dh_auto_build --builddirectory="$(CURDIR)/debian/build/cuda/"
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With CUDA and MKL DNN
	dh_auto_build --builddirectory="$(CURDIR)/debian/build/cuda-mkl-dnn/"
endif
endif


override_dh_auto_test:
	# Standard build
	dh_auto_test --builddirectory="$(CURDIR)/debian/build/generic/"
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With MKL DNN
	dh_auto_test --builddirectory="$(CURDIR)/debian/build/mkl-dnn/"
endif
ifeq (,$(filter nocuda,$(DEB_BUILD_PROFILES)))
	# With CUDA
	dh_auto_test --builddirectory="$(CURDIR)/debian/build/cuda/"
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With CUDA and MKL DNN
	dh_auto_test --builddirectory="$(CURDIR)/debian/build/cuda-mkl-dnn/"
endif
endif


override_dh_auto_install:
	# Standard build
	dh_auto_install --builddirectory="$(CURDIR)/debian/build/generic/" \
	                --destdir="$(CURDIR)/debian/install/generic/"
	# Copy cpp headers too (contains op.h being depending at least on CUDA)
	cp -av $(CURDIR)/cpp-package/include/mxnet-cpp "$(CURDIR)/debian/install/generic/usr/include/"
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With MKL DNN
	dh_auto_install --builddirectory="$(CURDIR)/debian/build/mkl-dnn/" \
	                --destdir="$(CURDIR)/debian/install/mkl-dnn/"
	cp -av $(CURDIR)/cpp-package/include/mxnet-cpp "$(CURDIR)/debian/install/generic/usr/include/"
endif
ifeq (,$(filter nocuda,$(DEB_BUILD_PROFILES)))
	# With CUDA
	dh_auto_install --builddirectory="$(CURDIR)/debian/build/cuda/" \
	                --destdir="$(CURDIR)/debian/install/cuda/"
	cp -av $(CURDIR)/cpp-package/include/mxnet-cpp "$(CURDIR)/debian/install/generic/usr/include/"
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With CUDA and MKL DNN
	dh_auto_install --builddirectory="$(CURDIR)/debian/build/cuda-mkl-dnn/" \
	                --destdir="$(CURDIR)/debian/install/cuda-mkl-dnn/"
	cp -av $(CURDIR)/cpp-package/include/mxnet-cpp "$(CURDIR)/debian/install/generic/usr/include/"
endif
endif


override_dh_install:
	# Standard build
	dh_install --sourcedir="$(CURDIR)/debian/install/generic/" \
	           --package=libmxnet-generic --package=mxnet-generic-dev
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With MKL DNN
	dh_install --sourcedir="$(CURDIR)/debian/install/mkl-dnn/" \
	           --package=libmxnet-mkl-dnn --package=mxnet-mkl-dnn-dev
endif
ifeq (,$(filter nocuda,$(DEB_BUILD_PROFILES)))
	# With CUDA
	dh_install --sourcedir="$(CURDIR)/debian/install/cuda/" \
	            --package=libmxnet-cuda --package=mxnet-cuda-dev
ifeq (,$(filter nomkldnn,$(DEB_BUILD_PROFILES)))
	# With CUDA and MKL DNN
	dh_install --sourcedir="$(CURDIR)/debian/install/cuda-mkl-dnn/" \
	           --package=libmxnet-cuda-mkl-dnn --package=mxnet-cuda-mkl-dnn-dev
endif
endif
	# Python bindings
	# Need libmxnet.so importable to run setup.py
	ln -s "$(CURDIR)/debian/install/generic/usr/lib/$(DEB_TARGET_GNU_TYPE)/libmxnet.so" \
	      "$(CURDIR)/python/mxnet/libmxnet.so"
	export PYBUILD_NAME=mxnet; \
	dh_auto_install --buildsystem=pybuild --sourcedirectory="$(CURDIR)/python"
	rm -f "$(CURDIR)/python/mxnet/libmxnet.so"
	# Remove libmxnet.so, it will depends on libmxnet package instead
	rm -rf "$(CURDIR)/debian/python-mxnet/usr/mxnet/"
	rm -rf "$(CURDIR)/debian/python3-mxnet/usr/mxnet/"
	
	# GNU R bindings
	# mkdir -p debian/tmp/usr/lib/R/site-library
	#R CMD INSTALL -l debian/r-mxnet/usr/lib/R/site-library --clean R-package/

override_dh_strip:
	# Don't strip anything


override_dh_python2:
	# Dependencies are handled by hand
	# See SUBSTVARS_PYTHON definition on top
	dh_python2 --no-guessing-deps --package=python-mxnet
	ln -sf "/usr/lib/libmxnet.so" "$(CURDIR)/debian/python-mxnet/usr/lib/python2.7/dist-packages/mxnet/libmxnet.so"
override_dh_python3:
	dh_python3 --no-guessing-deps --package=python3-mxnet
	ln -sf "/usr/lib/libmxnet.so" "$(CURDIR)/debian/python3-mxnet/usr/lib/python3/dist-packages/mxnet/libmxnet.so"


override_dh_gencontrol:
	dh_gencontrol -- -v"$(PKG_VERSION_TAG)" $(SUBSTVARS_BINARY_VERSION) $(SUBSTVARS_SOURCE_VERSION) $(SUBSTVARS_CUDNN) $(SUBSTVARS_CUDNNDEV) $(SUBSTVARS_PYTHON) $(SUBSTVARS_R_DEPENDS)
