#!/usr/bin/make -f

# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1

# cuda-gdb/README mentions --enable-targets="x86_64-apple-darwin,x86_64-unknown-linux-gnu,arm-elf-linux-gnu,m68k-unknown-linux-gnu"
CUDA_GDB_FLAGS	 =
CUDA_GDB_FLAGS	+= --program-prefix=cuda-
CUDA_GDB_FLAGS	+= --with-gdb-datadir='$${prefix}/share/cuda-gdb'
CUDA_GDB_FLAGS	+= --with-jit-reader-dir='$${libdir}/cuda-gdb'
CUDA_GDB_FLAGS	+= --with-system-gdbinit='$${sysconfdir}/cuda-gdb/gdbinit'
CUDA_GDB_FLAGS	+= --enable-cuda
CUDA_GDB_FLAGS	+= --enable-targets="$(DEB_HOST_GNU_TYPE),m68k-unknown-linux-gnu"
CUDA_GDB_FLAGS	+= --disable-nls
# the following flags were taken from gdb 8.2 in buster
CUDA_GDB_FLAGS	+= --disable-gdbtk
CUDA_GDB_FLAGS	+= --disable-shared
CUDA_GDB_FLAGS	+= --disable-readline
CUDA_GDB_FLAGS	+= --with-system-readline
CUDA_GDB_FLAGS	+= --with-expat
CUDA_GDB_FLAGS	+= --with-system-zlib
CUDA_GDB_FLAGS	+= --without-guile
CUDA_GDB_FLAGS	+= --with-babeltrace
ifneq (,$(filter $(DEB_HOST_ARCH),amd64))
CUDA_GDB_FLAGS	+= --with-intel-pt
endif
CUDA_GDB_FLAGS	+= --enable-tui
CUDA_GDB_FLAGS	+= --with-lzma
CUDA_GDB_FLAGS	+= --without-python
CUDA_GDB_FLAGS	+= --enable-64-bit-bfd
CUDA_GDB_FLAGS	+= --disable-sim

DEB_BUILD_MAINT_OPTIONS		 = hardening=+all
DEB_CPPFLAGS_MAINT_APPEND	 = -I$(CURDIR)/nvidia-cuda-tree-$(DEB_HOST_ARCH)/cuda_cudart/include
DEB_CFLAGS_MAINT_APPEND		 = -fcommon
DEB_LDFLAGS_MAINT_APPEND	 = -pthread

include /usr/share/dpkg/architecture.mk
include /usr/share/dpkg/buildflags.mk
include /usr/share/dpkg/pkg-info.mk

VENDOR			?= $(call dpkg_late_eval,VENDOR,dpkg-vendor --derives-from Ubuntu && echo Ubuntu || echo Debian)


aval			 = $(or $($(strip $1).$(or $(strip $2),$(DEB_HOST_ARCH))),$($(strip $1).default),$(error Not defined: $(strip $1)($(or $(strip $2),$(DEB_HOST_ARCH)))))
-include debian/rules.version
include debian/rules.soversion
include debian/rules.version_prefix
include debian/rules.defs
CUDA_ARCH_LIST			?= amd64
CUDA_ARCH_LIST_NO_DRIVER	?=
CUDA_ARCH_LIST_NO_OPENJDK	?=
CUDA_VERSION_TOOLKIT	?= $(DEB_VERSION_UPSTREAM)
CUDA_VERSION_MAJOR	?= $(word 1,$(subst ., ,$(CUDA_VERSION_TOOLKIT)))
CUDA_VERSION_MINOR	?= $(word 2,$(subst ., ,$(CUDA_VERSION_TOOLKIT)))
version_driver		 = $(call aval,CUDA_VERSION_DRIVER_MINIMAL)
watch_url		 = $(CUDA_WATCH_URL)
PACKAGE_LIST		:= $(shell dh_listpackages)
CUDA_GDB_VERSION	?= $(CUDA_VERSION_cuda_gdb)
DEFAULT_GCC_VERSION	?= $(error Undefined DEFAULT_GCC_VERSION)
THRUST_VERSION		?= $(or $(strip $(shell perl -ne 'if (/define\s+THRUST_VERSION\s+(\d*)/) { printf "%d.%d.%d\n", $$1 / 100000, $$1 / 100 % 1000, $$1 % 100; }' nvidia-cuda/cuda_cudart/include/thrust/version.h)),$(error empty THRUST_VERSION))
CUDA_JAVA_HOME		?= /usr/lib/jvm/java-8-openjdk-$(DEB_HOST_ARCH)
libdir			 = usr/lib/$(DEB_HOST_MULTIARCH)
jre_pkg			?= $(filter nvidia-openjdk-8-jre,$(PACKAGE_LIST))
thrust_pkg		?= $(filter libthrust-dev,$(PACKAGE_LIST))
nvidia_profiler_pkg	?= $(filter nvidia-profiler,$(PACKAGE_LIST))
visual_profiler_pkg	?= $(filter nvidia-visual-profiler,$(PACKAGE_LIST))

export NSIGHT_COMPUTE_DESKTOP_DIR	 = $(NSIGHT_COMPUTE_DESKTOP_DIR.$(DEB_HOST_ARCH))
export NSIGHT_SYSTEMS_HOST_DIR		 = $(NSIGHT_SYSTEMS_HOST_DIR.$(DEB_HOST_ARCH))
export NSIGHT_SYSTEMS_TARGET_DIR	 = $(NSIGHT_SYSTEMS_TARGET_DIR.$(DEB_HOST_ARCH))

package_libcuda1	 = $(package_libcuda1.$(VENDOR))
package_libcuda1	+= libcuda.so.1 (>= $${nvidia:MinVersion}) |
package_libcuda1	+= libcuda-$(CUDA_VERSION_MAJOR).$(CUDA_VERSION_MINOR)-1 |
package_libcuda1	+= no-libcuda1 [$${cuda:arch:has-no-driver}] |

package_libnvidia-ml1	 = $(package_libnvidia-ml1.$(VENDOR))
package_libnvidia-ml1	+= libnvidia-ml.so.1 (>= $${nvidia:MinVersion}) |
package_libnvidia-ml1	+= no-libcuda1 [$${cuda:arch:has-no-driver}] |

package_driver		 = $(package_driver.$(VENDOR))

# do not build nvidia-openjdk-8-jre on Ubuntu
ifneq (,$(jre_pkg))
ifeq ($(VENDOR),Ubuntu)
export DH_OPTIONS := $(DH_OPTIONS) -N$(jre_pkg)
jre_pkg			 =
endif
endif

OPENJDK_VERSION		 = $(call aval,OPENJDK_VERSION,$(DEB_HOST_ARCH))
make_component_version	?= $(subst -deb,-d,$(subst +,-,$(subst ~,-,$1)))
get_openjdk_component		?= openjdk-8-$1-$(call make_component_version,$(call aval,OPENJDK_VERSION,$2))
get_openjdk_source_component	?= $(call get_openjdk_component,source,$1)
get_openjdk_jre_component	?= $(call get_openjdk_component,jre-$1,$1)

jre_pkg_dep		?= $(if $(jre_pkg),$(jre_pkg) (>= 9.+8u252))
jre_depends.Debian	?= $(if $(jre_pkg),$(jre_pkg_dep) |) openjdk-8-jre
jre_depends.Ubuntu	?= openjdk-8-jre | $(jre_pkg_dep)

ifneq (,$(jre_pkg))
$(jre_pkg).VERSION	 = $(subst ~,~~,$(OPENJDK_VERSION))
endif

ifneq (,$(thrust_pkg))
$(thrust_pkg).DEB_VERSION	 = $(THRUST_VERSION)
endif

TEMPLATES	:= $(wildcard debian/*.in debian/patches/*.in)
SOVERTEMPLATES	:= $(wildcard debian/*SOVER*)
AUTOGEN		+= $(patsubst %.in,%,$(TEMPLATES))
AUTOGEN		+= $(foreach t,$(sort $(patsubst %.in,%,$(SOVERTEMPLATES))),$(subst SOVER,$(or $($(firstword $(subst SOVER, ,$(notdir $t))).SOVERSION),XXX),$t))
AUTOGEN		+= debian/g++
AUTOKEEP	 = debian/watch
AUTOCLEAN	 = $(filter-out $(AUTOKEEP),$(AUTOGEN))
AUTOCLEAN	+= debian/shlibs.local


.PHONY: autogen prepare
autogen: $(AUTOGEN)
prepare: autogen unpack-stamp compare-copyright-license
prepare: update-version-prefix


# deep copy, files will get irreversibly modified via hardlinks in the build target
define nvidia-cuda-unpack-repack
	dh_testdir
	$(RM) -r $@ $@.tmp
	cp -a $1 $@
endef

nvidia-cuda-tree-%:
	$(call nvidia-cuda-unpack-$(call aval,CUDA_TAR_TYPE,$*),$*)

unpack-stamp: $(filter debian/patches%,$(AUTOGEN))
unpack-stamp: nvidia-cuda-tree-$(DEB_HOST_ARCH)
	$(RM) nvidia-cuda
	ln -sf nvidia-cuda-tree-$(DEB_HOST_ARCH) nvidia-cuda
	$(RM) -r cuda-gdb-$(CUDA_GDB_VERSION) cuda-gdb
ifneq (arm64,$(DEB_HOST_ARCH))
	tar xf nvidia-cuda/cuda_gdb/extras/cuda-gdb-$(CUDA_GDB_VERSION).src.tar.gz
else
	tar xf amd64/cuda_gdb/extras/cuda-gdb-$(CUDA_GDB_VERSION).src.tar.gz
endif
	mv cuda-gdb-$(CUDA_GDB_VERSION) cuda-gdb
ifneq (,$(jre_pkg))
	$(RM) -r openjdk-8-jre
	dpkg -x $(call get_openjdk_jre_component,$(DEB_HOST_ARCH))/openjdk-8-jre-headless_$(OPENJDK_VERSION)_$(DEB_HOST_ARCH).deb openjdk-8-jre
	dpkg -x $(call get_openjdk_jre_component,$(DEB_HOST_ARCH))/openjdk-8-jre_$(OPENJDK_VERSION)_$(DEB_HOST_ARCH).deb openjdk-8-jre
	cp openjdk-8-jre/usr/share/doc/openjdk-8-jre-headless/copyright debian/$(jre_pkg).copyright
endif
	QUILT_PATCHES=debian/patches QUILT_SERIES=series-postunpack quilt --quiltrc /dev/null push -a || test $$? = 2
	touch $@

# Reformat the EULA to the format needed for debian/copyright.
nvidia-cuda/EULA.txt: unpack-stamp
EULA.fmt: nvidia-cuda/EULA.txt
	cat $< \
		| fromdos | fromdos | expand \
		| iconv -f UTF-8 -t latin1//TRANSLIT \
		| fold -s -w 80 \
		| sed -e 's/ *$$//;s/^$$/./;s/^/ /;' \
		> $@

# Compare the license in debian/copyright with the EULA shipped in the archive.
compare-copyright-license: EULA.fmt
	sed -e '1,/^License: other-NVIDIA-CUDA-TOOLKIT/d; /^$$/,$$d; /^ .$$/d' debian/copyright > copyright.tmp
	sed -e '/^ .$$/d' EULA.fmt > EULA.tmp
	diff -w copyright.tmp EULA.tmp
	rm -f copyright.tmp EULA.tmp

dpkg-compare-versions = $(shell dpkg --compare-versions "$(1)" "$(2)" "$(3)" && echo "$(2)")

# $1 = key, $2 = value, $3 = append_to_file
define echokv
	echo '$(shell printf "%-39s" $(1)) = $(2)'	>> $(3)

endef

define update-version-prefix
	$(if $($(1).VERSION_PREFIX),$(if $(call dpkg-compare-versions,$($(1).VERSION_PREFIX),le,$(call get-upstream-version,$(1),1)),
		: DROP PREFIX $(1) $($(1).VERSION_PREFIX) $(call get-upstream-version,$(1),1)
		$(eval $(1).VERSION_PREFIX =)))
	$(if $(call dpkg-compare-versions,$($(1).PREV_VERSION),le,$(call get-current-version,$(1))),,
		$(if $(call get-upstream-version,$(1),),,$(error MISSING VERSION FOR $(1)))
		: ADD PREFIX $(1) $($(1).PREV_VERSION) $(call get-current-version,$(1))
		$(eval $(1).VERSION_PREFIX = $($(1).PREV_VERSION)+~))
	echo '' >> $(2)
	$(if $($(1).VERSION_PREFIX),$(call echokv,$(1).VERSION_PREFIX,$($(1).VERSION_PREFIX),$(2)))
	$(call echokv,$(1).PREV_VERSION,$(call get-current-version,$(1)),$(2))

endef

update-version-prefix:
	echo "# This file is generated/updated by 'debian/rules update-version-prefix'." > debian/rules.version_prefix.new
	$(foreach pkg,$(OTHER_PACKAGES) $(LIB_PACKAGES),$(call update-version-prefix,$(pkg),debian/rules.version_prefix.new))
	mv debian/rules.version_prefix.new debian/rules.version_prefix


.PHONY: binary binary-arch binary-indep build build-arch build-indep clean install
binary binary-arch binary-indep build build-arch build-indep clean install:
	dh $@

build-stamp: unpack-stamp
	$(RM) -r build
	cp -al nvidia-cuda-tree-$(DEB_HOST_ARCH)/ build
	test -d build/libcublas/src || cp -alv amd64/libcublas/src build/libcublas/
	test -d build/libcusparse/src || cp -alv amd64/libcusparse/src build/libcusparse/
	test -d build/cuda_cupti/extras/CUPTI/doc/Cupti || cp -alv amd64/cuda_cupti/extras/CUPTI/doc build/cuda_cupti/extras/CUPTI/
	# fix permissions
ifneq (,$(visual_profiler_pkg))
	chmod -x build/cuda_nvvp/libnvvp/*.xpm
endif
	chmod -x build/cuda_nvcc/nvvm/libnvvm-samples/build.bat
	# remove rpath
	chrpath -d build/cuda_sanitizer_api/compute-sanitizer/libTreeLauncherTargetInjection.so
	# remove tracking scripts
	find build \( -name google-analytics-tracker.js -o -name google-analytics-write.js -o -name tynt.js \) -exec rm -v {} +
	# remove tracking images
	@set -e -x ; for dir in \
		build/nsight_compute/docs \
		build/cuda_cupti/extras/CUPTI/doc \
		build/cuda_sanitizer_api/compute-sanitizer/docs \
	; do test ! -d $$dir || find $$dir \
	    -name '*.html' -exec sed -r -i \
		-e '\,http://omniture.nvidia.com/b/ss/nvidiacudadocs/1/H.17--NS/0, { s,(<noscript>),<!-- \1,; s,img src,img DISABLED,; s,(</noscript>),\1 -->, }' \
		-e 's,(<script type="text/javascript" )src(="http://w.sharethis.com/button/buttons.js"[^>]*></script>),<!-- \1DISABLED\2 -->,' \
		-e 's,(<script type="text/javascript" charset="utf-8" )src(="//assets.adobedtm.com/b92787824f2e0e9b68dc2e993f9bd995339fe417/satelliteLib-7ba51e58dc61bcb0e9311aadd02a0108ab24cc6c.js"[^>]*></script>),<!-- \1DISABLED\2 -->,' \
		{} + ; \
	done
	@set -e -x ; for dir in \
		build/cuda_nvvp/libnvvp \
	; do test ! -d $$dir || find $$dir \
	    -name 'license.html' -exec sed -r -i \
		-e 's,(<script type="text/javascript" )src(="http://w.sharethis.com/button/buttons.js"[^>]*></script>),<!-- \1DISABLED\2 -->,' \
		{} + ; \
	done
	# replace embedded javascript libraries
	find build -name doctools.js -exec ln -sfv /usr/share/javascript/sphinxdoc/1.0/doctools.js {} \;
	find build -name html5shiv-printshiv.min.js -exec ln -sfv /usr/share/javascript/html5shiv/html5shiv-printshiv.min.js {} \;
	find build -name jquery.js -exec ln -sfv /usr/share/javascript/jquery/jquery.js {} \;
	find build -name jquery-3.1.0.js -exec ln -sfv /usr/share/javascript/jquery/jquery.js {} \;
	find build -name jquery.min.js -exec ln -sfv /usr/share/javascript/jquery/jquery.min.js {} \;
	find build -name searchtools.js -exec ln -sfv /usr/share/javascript/sphinxdoc/1.0/searchtools.js {} \;
	find build -name underscore.js -exec ln -sfv /usr/share/javascript/underscore/underscore.js {} \;
	# reduce 'dh_missing --list-missing' noise
	@set -e -x ; for dir in build/*/include build/*/lib64 ; do if [ -h "$$dir" ] ; then target=$$(readlink -f $$dir) ; $(RM) $$dir ; mv -v $$target $$dir ; fi ; done
	$(RM) -rv build/cuda_nvcc/nvvm-prev
	$(RM) -rv build/cuda_nvrtc/lib64/nvrtc-prev
	$(RM) -v build/cuda_cudart/include/cuda/std/detail/libcxx/include/CMakeLists.txt
	# cuda-gdb is built from source
	$(RM) -rv build/cuda_gdb/share/gdb
ifeq (,$(thrust_pkg))
	# thrust is packaged separately
	$(RM) -r build/cuda_cudart/include/cub
	$(RM) -r build/cuda_cudart/include/thrust
endif
	# remove empty directories
	find build -depth -type d -exec sh -c 'd="{}"; rmdir --ignore-fail-on-non-empty "$$d" ; test -d "$$d" || echo "removed $$d"' \;
	# split arch and indep eclipse plugins
ifneq (,$(visual_profiler_pkg))
	mkdir build/cuda_nvvp/libnvvp/plugins-arch
	mv build/cuda_nvvp/libnvvp/plugins/org.eclipse.equinox.launcher.gtk.linux.* build/cuda_nvvp/libnvvp/plugins-arch/
endif
	# clean up nsight_compute
ifeq (amd64,$(DEB_HOST_ARCH))
	chrpath -d build/nsight_compute/host/$(NSIGHT_COMPUTE_DESKTOP_DIR)/libicu*.so.56
	$(RM) -rv build/nsight_compute/target/$(NSIGHT_COMPUTE_DESKTOP_DIR.i386)/
	$(RM) -rv build/nsight_compute/target/$(NSIGHT_COMPUTE_DESKTOP_DIR.ppc64el)/
	$(RM) -rv build/nsight_compute/target/$(NSIGHT_COMPUTE_DESKTOP_DIR.arm64)/
else
	chrpath -d build/nsight_compute/target/$(NSIGHT_COMPUTE_DESKTOP_DIR)/libTreeLauncherTargetInjection.so
endif
	$(RM) -v build/nsight_compute/host/$(NSIGHT_COMPUTE_DESKTOP_DIR)/libcrypto.so*
	$(RM) -v build/nsight_compute/host/$(NSIGHT_COMPUTE_DESKTOP_DIR)/libssl.so*
	# clean up nsight_systems
ifeq (amd64,$(DEB_HOST_ARCH))
	chrpath -d build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5WebEngineCore.so.5
	chrpath -d build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libicu*.so.56
	chrpath -d build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libpapi.so.5
endif
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libstdc++.so.6
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libcrypto.so*
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libssl.so*
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5Charts.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5Designer*.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5Help.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5Multimedia*.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5QuickParticles.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5QuickTest.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5ScriptTools.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5Sensors.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5Sql.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5Test.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libQt5XmlPatterns.so.5
	$(RM) -v build/nsight_systems/$(NSIGHT_SYSTEMS_HOST_DIR)/libboost_python*.so.1.*
ifeq (amd64,$(DEB_HOST_ARCH))
	$(RM) -rv build/nsight_systems/$(NSIGHT_SYSTEMS_TARGET_DIR.arm64)/
endif
	touch $@

execute_before_dh_update_autotools_config: $(AUTOGEN) unpack-stamp

override_dh_auto_configure-arch:
	dh_auto_configure --sourcedirectory=cuda-gdb -- $(CUDA_GDB_FLAGS)

execute_before_dh_auto_build: build-stamp

override_dh_auto_build-arch:
	dh_auto_build --sourcedirectory=cuda-gdb -- V=1

ifneq (,$(jre_pkg))
execute_before_dh_auto_test-arch:
	openjdk-8-jre/$(CUDA_JAVA_HOME)/bin/java -version
endif

execute_before_dh_auto_install:
	rm -rf debian/tmp
	cp -al build/ debian/tmp

override_dh_auto_install-arch:
	dh_auto_install --sourcedirectory=cuda-gdb
	chrpath -d debian/tmp/usr/bin/cuda-gdb

override_dh_installman:
	dh_installman --language=C

override_dh_makeshlibs:
	dh_makeshlibs -X/stubs/ -VNone

override_dh_shlibdeps:
	$(RM) -r libcuda
	mkdir libcuda
	ln -s ../nvidia-cuda/cuda_cudart/lib64/stubs/libcuda.so libcuda/libcuda.so.1
	echo 'libcuda 1 XXXlibcuda1XXX' > debian/shlibs.local
	dh_shlibdeps -pnsight-compute -X/libexec/QtWebEngineProcess -- \
		-l/usr/lib/nsight-compute/host/$(NSIGHT_COMPUTE_DESKTOP_DIR) \
		-l/usr/lib/nsight-compute/target/$(NSIGHT_COMPUTE_DESKTOP_DIR)
	dh_shlibdeps -pnsight-systems -- \
		-llibcuda \
		-l/usr/lib/nsight-systems/$(NSIGHT_SYSTEMS_HOST_DIR)
ifneq (,$(jre_pkg))
ifeq (ppc64el,$(DEB_HOST_ARCH))
	dh_shlibdeps -p$(jre_pkg) -- -l$(CUDA_JAVA_HOME)/jre/lib/ppc64le/server
else
	dh_shlibdeps -p$(jre_pkg) -- -l$(CUDA_JAVA_HOME)/jre/lib/$(DEB_HOST_ARCH)/server
endif
endif
	dh_shlibdeps --remaining-packages -X/stubs/ -- -llibcuda
	$(RM) -r libcuda debian/shlibs.local
	sed -r -i -e 's/XXXlibcuda1XXX/$${package:libcuda1}/g' \
		$(foreach lib,$(LIB_BASENAMES),-e 's/$(lib)$($(lib).SOVERSION)(,|$$)/$${$(lib):eq:Version}\1/g') \
		debian/*.substvars

# running dh_strip is not permitted by the NVIDIA license
override_dh_dwz:
	dh_dwz -pnvidia-cuda-gdb
override_dh_strip:
	dh_strip -pnvidia-cuda-gdb
override_dh_strip_nondeterminism-indep:
override_dh_strip_nondeterminism-arch:
	dh_strip_nondeterminism -pnvidia-cuda-gdb

execute_before_dh_installdeb-indep:
	hardlink -v -t debian/nvidia-cuda-toolkit-doc/usr/share/doc/nvidia-cuda-toolkit
	hardlink -v -t debian/libcupti-doc/usr/share/doc/libcupti-dev

execute_before_dh_installdeb-arch:
	hardlink -v -t debian/nsight-compute/usr/share/doc/nsight-compute

# $1 = <lib_basename or pkgname>
get-custom-version	 = $(or $($(1).DEB_VERSION),$($(1).VERSION_PREFIX)$($(1).VERSION))
get-upstream-version	 = $(or $($(1).DEB_VERSION),$($(1).VERSION),$(if $(2),$(DEB_VERSION_UPSTREAM)))
get-previous-version	 = $($(1).PREV_VERSION)
get-current-version	 = $(or $(call get-custom-version,$(1)),$(DEB_VERSION_UPSTREAM))

substvars	+= $(foreach pkg,$(filter-out $(PACKAGE_LIST),$(OTHER_PACKAGES)),-V'$(pkg):Version=0.not-built' -V'$(pkg):eq:Version=$(pkg) (= $${$(pkg):Version})')
substvars	+= $(foreach pkg,$(filter-out $(LIB_PACKAGES),$(PACKAGE_LIST)),$(if $(call get-custom-version,$(pkg)),-V'$(pkg):Version=$(call get-custom-version,$(pkg))~$(DEB_VERSION)' -V'$(pkg):eq:Version=$(pkg) (= $${$(pkg):Version})'))
substvars	+= $(foreach lib,$(LIB_BASENAMES),$(if $(call get-custom-version,$(lib)),-V'$(lib):Version=$(call get-custom-version,$(lib))~$(DEB_VERSION)'))
substvars	+= $(foreach lib,$(LIB_BASENAMES),-V'$(lib):eq:Version=$(lib)$($(lib).SOVERSION) (= $${$(if $(call get-custom-version,$(lib)),$(lib),binary):Version})')
substvars	+= -V'package:libcuda1=$(package_libcuda1)'
substvars	+= -V'package:libnvidia-ml1=$(package_libnvidia-ml1)'
substvars	+= -V'package:driver=$(package_driver)'
substvars	+= -V'nvidia:MinVersion=$(version_driver)'
substvars	+= -V'cuda:gcc:DefaultVersion=$(DEFAULT_GCC_VERSION)'
substvars	+= -V'thrust:Version=$(THRUST_VERSION)'
substvars	+= -V'cuda:arch:has-no-driver=$(if $(filter $(DEB_HOST_ARCH),$(CUDA_ARCH_LIST_NO_DRIVER)),,!)$(DEB_HOST_ARCH)'
substvars	+= -V'cuda:arch:has-nvidia-profiler=$(if $(nvidia_profiler_pkg),,!)$(DEB_HOST_ARCH)'
substvars	+= -V'cuda:arch:has-nvidia-visual-profiler=$(if $(visual_profiler_pkg),,!)$(DEB_HOST_ARCH)'
substvars	+= -V'jre:Depends=$(jre_depends.$(VENDOR))'

define check-monotonic-version
	: $(shell printf "%-29s" "$(1)") ; dpkg --compare-versions "$(call get-previous-version,$(1))" le "$(call get-current-version,$(1))"

endef

define gencontrol-template
	dh_gencontrol $(1) -- $(2) \
		$(substvars)

endef

override_dh_gencontrol:
	$(foreach p,$(PACKAGE_LIST),$(call check-monotonic-version,$(p)))
	$(foreach p,$(PACKAGE_LIST),$(if $(call get-custom-version,$(p)),$(call gencontrol-template,-p$(p),-v$(call get-custom-version,$(p))~$(DEB_VERSION))))
	$(call gencontrol-template,--remaining-packages,)

execute_after_dh_autoreconf_clean:
	$(RM) -r .pc
	$(RM) -r nvidia-cuda-tree-amd64*
	$(RM) -r nvidia-cuda-tree-ppc64el*
	$(RM) -r nvidia-cuda-tree-arm64*
	$(RM) nvidia-cuda*
	$(RM) -r build
	$(RM) -r libcuda
	$(RM) EULA.fmt EULA.tmp copyright.tmp
	$(RM) -r openjdk-8-jre
	$(RM) debian/$(jre_pkg).copyright

execute_after_dh_clean:
	$(RM) -r get-orig-source
	$(RM) -r cuda-gdb-$(CUDA_GDB_VERSION) cuda-gdb
	$(RM) $(AUTOCLEAN)
	$(MAKE) -f debian/rules $(AUTOKEEP)
	$(RM) debian/rules.version debian/rules.soversion


debian/rules.version: amd64/version.json
	sed -r -n '/: \{/{s/.*"(.*)".*/\1/;h};/"version" :/{s/.*: "(.*)".*/\1/;H;x;s/^/CUDA_VERSION_/;s/\n/ = /;p}' $< > $@

debian/rules.soversion: debian/control
	sed -rn 's/Package: (lib.*[^0-9.]+)([0-9.]+)$$/LIB_PACKAGES += \1\2\nLIB_BASENAMES += \1\n\1.SOVERSION = \2/p; s/Package: (.*)/OTHER_PACKAGES += \1/p' $< > $@

# Generating control files
%:: %.in debian/rules debian/rules.defs
	perl -p \
	-e 's{#VERSION_TOOLKIT#}{$(CUDA_VERSION_TOOLKIT)}g;' \
	-e 's{#CUDA_GDB_VERSION#}{$(CUDA_GDB_VERSION)}g;' \
	-e 's{#DEFAULT_GCC_VERSION#}{$(DEFAULT_GCC_VERSION)}g;' \
	-e 's{#CUDA_DOWNLOAD_URL#}{$(watch_url)}g;' \
	-e 's{#LIBDIR#}{$(libdir)}g;' \
	-e 's{#!ppc64el#}{$(if $(filter ppc64el,$(DEB_HOST_ARCH)),#)}g;' \
	-e 's{#!arm64#}{$(if $(filter arm64,$(DEB_HOST_ARCH)),#)}g;' \
	-e 's{#CUDA_JAVA_HOME#}{$(CUDA_JAVA_HOME)}g;' \
	-e 's{#NSIGHT_COMPUTE_DESKTOP_DIR#}{$(NSIGHT_COMPUTE_DESKTOP_DIR)}g;' \
	-e 's{#NSIGHT_SYSTEMS_HOST_DIR#}{$(NSIGHT_SYSTEMS_HOST_DIR)}g;' \
	-e 's{#NSIGHT_SYSTEMS_TARGET_DIR#}{$(NSIGHT_SYSTEMS_TARGET_DIR)}g;' \
	< $< > $@

# $1 = <lib_basename>, $2 = <soversion>
define sover-template
$(1).VERSION_PREFIX	?= $$($(1)$(2).VERSION_PREFIX)
$(1)$(2).VERSION	?= $$($(1).VERSION)
$(1)$(2).%:: $(1)SOVER.%
	perl -p \
	-e 's{#SOVERSION#}{$(2)}g;' \
	-e 's{#VERSION#}{$$(or $$($(1).LIBVERSION),$$($(1).VERSION),$$(error $(1).VERSION))}g;' \
	< $$< > $$@
endef
$(foreach lib,$(LIB_BASENAMES),$(eval $(call sover-template,$(lib),$($(lib).SOVERSION))))

debian/g++: debian/gcc
	sed '/prog=/s/gcc-/g++-/g' < $< > $@
	chmod 0755 $< $@

# only invoked manually
check-whitespace:
	grep -r --exclude-dir=.svn --exclude-dir=.git --exclude '*.patch*' -E '\s$$' debian || true

############################################################################

# $1 = <arch>
get_origdir		 = $(or $(ORIGDIR.$(strip $1)),$(ORIGDIR_BASE)-$(strip $1))
get_tarball		 = $(or $(TARBALL.$(strip $1)),$(TARBALL_BASE)-$(strip $1))$(TARBALL_SUFFIX)

# these must be defined in rules.defs
get_dl_url		?= $(error Undefined: get_dl_url)
get_dl_filename		?= $(error Undefined: get_dl_filename)
get_dl_type		?= $(error Undefined: get_dl_type)

UPSTREAM_NAME		 = nvidia-cuda-toolkit
UPSTREAM_VERSION	 = $(CUDA_VERSION_TOOLKIT)
CUDA_TARBALL_LIST	 = $(foreach a,$(CUDA_ARCH_LIST),$(call get_tarball,$a))
OPENJDK_ARCH_LIST	 = $(filter-out $(CUDA_ARCH_LIST_NO_OPENJDK),$(CUDA_ARCH_LIST))
OPENJDK_TARBALL_LIST	 = $(sort $(foreach a,$(OPENJDK_ARCH_LIST),$(foreach j,source jre,$(call get_tarball,$(call get_openjdk_$(j)_component,$a)))))
TARBALL_LIST		 = $(call get_tarball,empty)
TARBALL_LIST		+= $(CUDA_TARBALL_LIST)
TARBALL_LIST		+= $(OPENJDK_TARBALL_LIST)

CACHE			?= ../.cache
COMPRESS_EXT		?= gz
COMPRESS.gz		?= gzip -n9
COMPRESS.xz		?= xz -9
ORIGDIR_BASE		?= $(UPSTREAM_NAME)-$(UPSTREAM_VERSION).orig
TARBALL_BASE		?= $(UPSTREAM_NAME)_$(UPSTREAM_VERSION).orig
TARBALL_SUFFIX		?= .tar.$(COMPRESS_EXT)
ORIGDIR.empty		?= $(ORIGDIR_BASE)
TARBALL.empty		?= $(TARBALL_BASE)

# per-target variables
origdir			 = $(error Undefined: origdir)
tarball			 = $(error Undefined: tarball)
openjdk_arch		 = $(error Undefined: openjdk_arch)
openjdk_version		 = $(error Undefined: openjdk_version)

get-orig-source-prepare:
	$(RM) -r get-orig-source
	mkdir get-orig-source

get-orig-source-prepare/%: get-orig-source-prepare
	$(RM) $(tarball)
	mkdir get-orig-source/$(origdir)

get-orig-source-download/%: dl_filename = $(call get_dl_filename,$*)
get-orig-source-download/%: get-orig-source-prepare
	ln -v $(CACHE)/$(dl_filename) get-orig-source/ 2>/dev/null || \
		wget $(call get_dl_url,$*) -O get-orig-source/$(dl_filename)
	if [ -d $(CACHE) ] && [ ! -f $(CACHE)/$(dl_filename) ]; then \
		ln -v get-orig-source/$(dl_filename) $(CACHE) ; fi

get-orig-source-download-openjdk-8-source/%: get-orig-source-prepare/%
	cd get-orig-source/$(origdir) && (apt-get source -d openjdk-8=$(openjdk_version) || debsnap -v -f -d . openjdk-8 $(openjdk_version))

get-orig-source-download-openjdk-8-jre/%: get-orig-source-prepare/%
	cd get-orig-source/$(origdir) && (apt-get download openjdk-8-jre:$(openjdk_arch)=$(openjdk_version) || debsnap -v -f -a $(openjdk_arch) -d . openjdk-8-jre $(openjdk_version))
	cd get-orig-source/$(origdir) && (apt-get download openjdk-8-jre-headless:$(openjdk_arch)=$(openjdk_version) || debsnap -v -f -a $(openjdk_arch) -d . openjdk-8-jre-headless $(openjdk_version))

# unpack the all-in-one .run cuda installer containing toolkit, driver and samples
get-orig-source-run-unpack/%: get-orig-source-prepare/% get-orig-source-download/%
	@set -e -x ; \
	    cd get-orig-source ; \
	    sh $(call get_dl_filename,$*) --nox11 --noexec --keep --target tmp.$* ; \
	    find tmp.$* -ls ; \
	    if [ -d tmp.$*/builds/cuda-toolkit ]; then \
		mv tmp.$*/builds/cuda-toolkit/* $(origdir)/ ; \
	    elif [ -d tmp.$*/builds/cuda_cudart ]; then \
		$(RM) -v tmp.$*/builds/NVIDIA-Linux*.run ; \
		$(RM) -r tmp.$*/builds/cuda_demo_suite ; \
		$(RM) -r tmp.$*/builds/cuda_samples ; \
		mv tmp.$*/builds/* $(origdir)/ ; \
	    else \
	        false ; \
	    fi ; \
	    $(RM) -r tmp.$*

get-orig-source-files/%: get-orig-source-unpack/%
	@set -e -x ; \
	    cd get-orig-source ; \
	    touch $(origdir).stamp -r $$(find $(origdir) -type f | xargs -r ls -tr | tail -n 1)

get-orig-source-files/empty: origdir = $(call get_origdir,empty)
get-orig-source-files/empty: get-orig-source-prepare/empty $(CUDA_TARBALL_LIST)
	touch get-orig-source/$(origdir).stamp -r $$(ls -tr $(CUDA_TARBALL_LIST) | tail -n 1)

get-orig-source-pack/%: origdir = $(call get_origdir,$*)
get-orig-source-pack/%: tarball = $(call get_tarball,$*)
get-orig-source-pack/%: get-orig-source-files/%
	@set -e -x ; \
	    cd get-orig-source ; \
	    tar cfv - \
	        --clamp-mtime --mtime="./$(origdir).stamp" \
		--sort=name \
		--owner=root --group=src \
		$(origdir) \
		| $(COMPRESS.$(COMPRESS_EXT)) > $(tarball); \
	    touch $(tarball) -r $(origdir).stamp
	mv get-orig-source/$(tarball) .

$(call get_tarball,empty): get-orig-source-pack/empty

# $1 = <arch>
define get-orig-source-template
get-orig-source-unpack/$1: get-orig-source-$$(call get_dl_type,$1)-unpack/$1
$$(call get_tarball,$1): get-orig-source-pack/$1
endef

# $1 = <arch>, $2 = <component>, $3 = source|jre
define get-orig-source-openjdk-8-template
ORIGDIR.$2	?= $$(UPSTREAM_NAME).orig-$2
$$(call get_tarball,$2): openjdk_arch=$1
$$(call get_tarball,$2): openjdk_version=$$(call aval,OPENJDK_VERSION,$1)
get-orig-source-unpack/$2: get-orig-source-download-openjdk-8-$3/$2
$$(call get_tarball,$2): get-orig-source-pack/$2
endef

# $1 = <arch>
define get-orig-source-openjdk-8-source-template
$(call get-orig-source-openjdk-8-template,$1,$$(call get_openjdk_source_component,$1),source)
endef

# $1 = <arch>
define get-orig-source-openjdk-8-jre-template
$(call get-orig-source-openjdk-8-template,$1,$$(call get_openjdk_jre_component,$1),jre)
endef

$(foreach a,$(CUDA_ARCH_LIST),\
	$(eval $(call get-orig-source-template,$a))\
	$(eval $(call get-orig-source-openjdk-8-source-template,$a))\
	$(eval $(call get-orig-source-openjdk-8-jre-template,$a)))

get-orig-source-openjdk-8: $(OPENJDK_TARBALL_LIST)

.PHONY: get-orig-source
get-orig-source: $(TARBALL_LIST)
	$(RM) -r get-orig-source

list-tarballs:
	@for t in $(TARBALL_LIST) ; do echo "$$t" ; done

############################################################################

# The tarballs are kept in a separate git repository and use the git-lfs
# storage backend. To keep the local disk usage low, this repository is
# checked out sparsely, only tarballs for versions that have been built
# locally will be available locally.

GIT			?= git
TARBALL_REPOSITORY	 = https://salsa.debian.org/nvidia-team/tarballs-$(UPSTREAM_NAME).git
TARBALL_TREE		 = ../tarballs-$(UPSTREAM_NAME)

define sparse-checkout-current
	grep '^$(UPSTREAM_VERSION)/' $(TARBALL_TREE)/.git/info/sparse-checkout || \
		echo '$(UPSTREAM_VERSION)/*' >> $(TARBALL_TREE)/.git/info/sparse-checkout

endef

define test-file-exists
	test -f $1

endef

$(TARBALL_TREE):
	$(RM) -r $@.tmp
	$(GIT) clone --no-checkout $(TARBALL_REPOSITORY) $@.tmp
	cd $@.tmp && $(GIT) lfs install --local
	cd $@.tmp && $(GIT) config --local core.sparsecheckout true
	echo .gitattributes >> $@.tmp/.git/info/sparse-checkout
	cd $@.tmp && $(GIT) checkout
	mv $@.tmp $@

$(TARBALL_TREE)/$(UPSTREAM_VERSION): | $(TARBALL_TREE)
	$(sparse-checkout-current)
	cd $(TARBALL_TREE) && $(GIT) pull --ff-only && $(GIT) checkout

tarball-tree: $(TARBALL_TREE)

# only invoked manually
writable-tarball-tree: tarball-tree
	cd $(TARBALL_TREE) && $(GIT) remote set-url origin $(patsubst https://salsa.debian.org/%,git@salsa.debian.org:%,$(TARBALL_REPOSITORY))

# invoked from gbp buildpackage preexport hook
check-current-tarballs: $(TARBALL_TREE)/$(UPSTREAM_VERSION)
	$(foreach t,$(TARBALL_LIST),$(call test-file-exists,$(TARBALL_TREE)/$(UPSTREAM_VERSION)/$t))

# only invoked manually
commit-current-tarballs: get-orig-source
	$(sparse-checkout-current)
	mkdir -p $(TARBALL_TREE)/$(UPSTREAM_VERSION)
	mv $(TARBALL_LIST) $(TARBALL_TREE)/$(UPSTREAM_VERSION)/
	cd $(TARBALL_TREE) && $(GIT) add $(UPSTREAM_VERSION) && if $(GIT) status -s $(UPSTREAM_VERSION) | grep ^A ; then $(GIT) commit -m "add $(UPSTREAM_VERSION) tarballs" $(UPSTREAM_VERSION) ; fi