#!/usr/bin/make -f

include /usr/share/dpkg/default.mk
export DEB_BUILD_MAINT_OPTIONS=hardening=+all
export DEB_CXXFLAGS_MAINT_APPEND=-DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=0

# Disable unaligned access on armhf
ifneq (,$(filter $(DEB_HOST_ARCH),armhf))
	export DEB_CFLAGS_MAINT_APPEND += -mno-unaligned-access
endif

# Ensure pcre_h.jl and errno_h.jl are sorted reproducibly
export LC_ALL=C.UTF-8
# HOME is needed to avoid "mkdir(): Permission denied" while building docs.
# Some tests also need a HOME directory.
export HOME=/tmp
# If you want to do a custom build of Julia against MKL, set it to 1.
export CUSTOM_MKL ?= 0
# If you want to do a custom build for native machine architecture
export CUSTOM_NATIVE ?= 0
# Disable networking relates tests. (test-add-envvar-for-skipping-network-tests.patch)
export DEBIAN_FORCE_NONET="true"

LLVM_VER = $(shell grep -e 'llvm-.*-dev' debian/control | cut -d- -f2)

# NOTES:
# 1. Some of these flags come from upstream's Make.inc .
# 2. To enable USE_BLAS64=0 (ILP64), we need to set INTERFACE64=1 for OpenBLAS.
# 3. Julia is tightly coupled with a specific libuv1 version. we cannot use the one provided in archive.
# 4. ∴ is unicode "therefore", ⛬  is unicode "historic site" https://unicode-table.com/en/26EC/
COMMON_FLAGS = \
	prefix=/usr \
	sysconfdir=/etc \
	DESTDIR=debian/tmp/ \
	LLVM_CONFIG=/usr/bin/llvm-config-$(LLVM_VER) \
	LLVM_VER=$(LLVM_VER) \
	MULTIARCH=$(DEB_HOST_MULTIARCH) \
	MULTIARCH_INSTALL=1 \
	NO_GIT=1 \
	TAGGED_RELEASE_BANNER='$(DEB_VENDOR) ⛬  julia/$(DEB_VERSION)' \
	USE_BLAS64=0  \
	USE_LLVM_SHLIB=1 \
	USE_SYSTEM_BLAS=1 \
	USE_SYSTEM_CURL=1 \
	USE_SYSTEM_DSFMT=1 \
	USE_SYSTEM_GMP=1 \
	USE_SYSTEM_LAPACK=1 \
	USE_SYSTEM_LIBGIT2=1 \
	USE_SYSTEM_LIBSSH2=1 \
	USE_SYSTEM_LIBUNWIND=1 \
	USE_SYSTEM_LIBUV=0 \
	USE_SYSTEM_LLVM=1 \
	USE_SYSTEM_MBEDTLS=1 \
	USE_SYSTEM_MPFR=1 \
	USE_SYSTEM_OPENSPECFUN=1 \
	USE_SYSTEM_PATCHELF=1 \
	USE_SYSTEM_PCRE=1 \
	USE_SYSTEM_SUITESPARSE=1 \
	USE_SYSTEM_UTF8PROC=1 \
	LIBBLAS=-lblas \
	LIBBLASNAME=libblas \
	LIBLAPACK=-llapack \
	LIBLAPACKNAME=liblapack \
	VERBOSE=1

# Set architecture specific CPU targets. See: #910784
ifneq (,$(filter $(DEB_HOST_ARCH),amd64 kfreebsd-amd64 x32))
COMMON_FLAGS += MARCH=x86-64 \
	JULIA_CPU_TARGET="generic;sandybridge,-xsaveopt,clone_all;haswell,-rdrnd,base(1)"
else ifneq (,$(filter $(DEB_HOST_ARCH),i386 hurd-i386 kfreebsd-i386))
COMMON_FLAGS += MARCH=pentium4 \
	JULIA_CPU_TARGET="pentium4;sandybridge,-xsaveopt,clone_all"
else ifneq (,$(filter $(DEB_HOST_ARCH),armhf))
COMMON_FLAGS += JULIA_CPU_TARGET="armv7-a;armv7-a,neon;armv7-a,neon,vfp4"
else
COMMON_FLAGS += JULIA_CPU_TARGET="generic"
endif

# Use libopenlibm on architectures that have it
ifneq (,$(filter $(DEB_HOST_ARCH),amd64 kfreebsd-amd64 x32))
COMMON_FLAGS += USE_SYSTEM_OPENLIBM=1 USE_SYSTEM_LIBM=0
else ifneq (,$(filter $(DEB_HOST_ARCH),i386 hurd-i386 kfreebsd-i386))
COMMON_FLAGS += USE_SYSTEM_OPENLIBM=1 USE_SYSTEM_LIBM=0
else ifneq (,$(filter $(DEB_HOST_ARCH),arm64 armhf mips mips64el mipsel powerpc ppc64 ppc64el))
COMMON_FLAGS += USE_SYSTEM_OPENLIBM=1 USE_SYSTEM_LIBM=0
else
# Use libm elsewhere
COMMON_FLAGS += USE_SYSTEM_OPENLIBM=0 USE_SYSTEM_LIBM=1
endif

# [s390x] Disable libunwind
ifneq (,$(filter $(DEB_HOST_ARCH),s390x))
COMMON_FLAGS += DISABLE_LIBUNWIND=1
endif

# [armhf] Fallback to GCC-7
ifneq (,$(filter $(DEB_HOST_ARCH),armhf))
COMMON_FLAGS += CC=gcc-7 CXX=g++-7
endif

# Set number of parallel workers for tests
ifneq (,$(filter parallel=1,$(DEB_BUILD_OPTIONS)))
TESTS_ENV += JULIA_CPU_THREADS=2
else ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
TESTS_ENV += JULIA_CPU_THREADS=$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
else
TESTS_ENV += JULIA_CPU_THREADS=2
endif
# Restart workers exceeding maximum resident memory size (requires JULIA_CPU_THREADS >= 2)
TESTS_ENV += JULIA_TEST_MAXRSS_MB=500

ifeq (1,$(CUSTOM_MKL))
COMMON_FLAGS += USE_INTEL_MKL=1 USE_BLAS64=1 \
                LIBBLAS=-lmkl_rt LIBBLASNAME=libmkl_rt \
                LIBLAPACK=-lmkl_rt LIBLAPACKNAME=libmkl_rt \
				MKLROOT=/usr MKLLIB=/usr/lib/$(DEB_HOST_MULTIARCH)
endif
ifeq (1,$(CUSTOM_NATIVE))
COMMON_FLAGS += MARCH=native JULIA_CPU_TARGET=native
endif


%:
	dh $@

override_dh_auto_build-arch:
	dh_auto_build -- $(COMMON_FLAGS)

override_dh_auto_build-indep:
	dh_auto_build -- $(COMMON_FLAGS)
	-$(MAKE) -C doc pdf

override_dh_auto_test-arch:
ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
ifeq (,$(filter $(DEB_HOST_ARCH),amd64 i386))
	-env $(TESTS_ENV) make -C test $(COMMON_FLAGS)
else
	env $(TESTS_ENV) make -C test $(COMMON_FLAGS)
endif
endif

override_dh_auto_test-indep:

override_dh_auto_clean:
	make $(COMMON_FLAGS) distcleanall
	make -f debian/shlibdeps.mk $(COMMON_FLAGS) clean

override_dh_auto_install:
	make $(COMMON_FLAGS) install
	rm -rf usr # Otherwise dh_install does not see debian/tmp/usr
	find debian -type f -name '*.so.debug' -delete
	find debian -type f -name .gitignore -delete
	find debian -type f -name 'LICENSE.md' -delete

override_dh_missing:
	dh_missing --list-missing

override_dh_link-arch:
	# Create *.so symlinks for dlopen'd libraries in private libdir.
	make -f debian/shlibdeps.mk $(COMMON_FLAGS)
	dh_link

override_dh_shlibdeps:
	# Generate dependencies for dlopen'd libraries using dummy executable.
	# Suppress useless dependency warnings caused by unused library symbols.
	dh_shlibdeps -- --warnings=1 debian/shlibdeps

override_dh_compress:
	dh_compress --exclude=examples/

override_dh_install-indep:
	dh_install --exclude=build_h.jl --exclude=build.h

override_dh_fixperms:
	dh_fixperms
	# Fix shebang and mode bits
	find debian \( -type f -name '*.jl' \
		-exec grep -q '..usr/bin/env julia' '{}' \; \
		-a -exec sed -i -e 's@#!/usr/bin/env julia@#!/usr/bin/julia@g' '{}' \; \
		-a -exec chmod +x '{}' \; -print \)

# Don't strip sys.so and libjulia.so.* to keep the sanity of this program.
# https://github.com/JuliaLang/julia/issues/23115#issuecomment-320715030
#
# 0. What is sys.so, i.e. Julia sysimage?
#
#    sys.so is NOT compiled from any compiling language such as C/C++, but
#    from Julia scripts instead. Julia precompiles .jl scripts under the base
#    and stdlib directories into this ELF-formated shared object sys.so to
#    speedup program startup time. To some extent this is just like generating
#    ELF-formated cache for Julia base and stdlib. A glance at the symbol
#    table (readelf -sW sys.so) would suggest that sys.so is not an ordinary
#    ELF shared object as you thought.
#
# 1. What is the consequence of stripping sys.so?
#
#    Stripping sys.so will make julia behave differently from what the official
#    document says. stacktrace() won't trace into .jl files in base/stdlib.
#    That's because sys.so is compiled from .jl files instead of C/C++
#    sources and stripping sys.so results in the loss of debugging information
#    on .jl files. Julia interpreter itself is more likely a machine code
#    generator built upon LLVM. It is a bad idea to delete debugging
#    information about Julia's base/stdlib .jl files and confuse our users.
#
#    The consequence can be figured out after stripping sys.so by your self.
#    Just run julia following the official documentation:
#
#        https://docs.julialang.org/en/v1.0.0/manual/stacktraces/
#
#    And you will immediately find out that Julia is no longer able to give
#    you backtrace into the .jl files, which are precompiled into the sys.so.
#    If julia were python, this means python will nolonger able to trace
#    into e.g. python standard libraries (written in python) after stripping.
#
#    Stripping sys.so would also cause "backtrace" test failure, which is used
#    as sanity check.
#
#SYSIMG= debian/libjulia1/usr/lib/$(DEB_HOST_MULTIARCH)/julia/sys.so
override_dh_strip:
	dh_strip  -X"sys.so" -X"libjulia.so.1.0"
	#objcopy --only-keep-debug $(SYSIMG) $(SYSIMG).debug
	#strip $(SYSIMG)
	#objcopy --add-gnu-debuglink=$(SYSIMG).debug $(SYSIMG)

override_dh_makeshlibs:
	dh_makeshlibs --no-scripts
