#!/usr/bin/make -f

# Currently gcc can not be compiled with format-security and it is not needed
# for Ada code anyway
export DEB_BUILD_MAINT_OPTIONS = hardening=+all,-format

#export DH_VERBOSE = 1

include /usr/share/dpkg/default.mk
include /usr/share/ada/packaging.mk

# These variables are used to find and unpack the gcc source
GCC_DIR := /usr/src/gcc-$(DEB_GNAT_VERSION)

# This variable is used in Makefile.in to adjust src/version.in
export GHDL_VER_DESC := $(DEB_VENDOR) $(DEB_VERSION)

# Get parallel option to parallelize the gcc build specifically (Ada builds
# are already parallelized by code included from debian_packaging-*.mk above).
MAKEPARALLEL = $(DEB_BUILD_OPTION_PARALLEL:%=-j%)

# List of the ghdl backends to build
BACKENDS := mcode llvm gcc

# build profile control over what backends get built
ifneq ($(filter pkg.ghdl.nomcode,$(DEB_BUILD_PROFILES)),)
    BACKENDS := $(filter-out mcode,$(BACKENDS))
endif
ifneq ($(filter pkg.ghdl.nollvm,$(DEB_BUILD_PROFILES)),)
    BACKENDS := $(filter-out llvm,$(BACKENDS))
endif
ifneq ($(filter pkg.ghdl.nogcc,$(DEB_BUILD_PROFILES)),)
    BACKENDS := $(filter-out gcc,$(BACKENDS))
endif

# force disable mcode build on non-x86 architectures where it isn't supported
ifeq ($(filter amd64 i386,$(DEB_HOST_ARCH_CPU)),)
    BACKENDS := $(filter-out mcode,$(BACKENDS))
endif

BUILDDIR := $(CURDIR)/builddir
TESTRUNDIR := $(CURDIR)/testrundir
STAMPSDIR := $(BUILDDIR)/stamps

# Common arguments for all calls to ./configure.
# The order is the same than there.
export CC           := gcc-$(DEB_GNAT_VERSION)
export CXX          := g++-$(DEB_GNAT_VERSION)
export CFLAGS
export CXXFLAGS
export GNATMAKE     := gnatmake $(GNATMAKEFLAGS)
export ADA_FLAGS    := $(ADAFLAGS)
export LDFLAGS

# Used in 3 normal builds but not in the gcc part of the build section.
common_configure_arguments := \
  --prefix=/usr \
  --disable-werror \
  --incdir=lib/ghdl/include \
  --enable-gplcompat \
 # EOL


%:
ifneq (,$(findstring $(shell dpkg-architecture -qDEB_HOST_ARCH), s390x))
 $(error This package is currently broken on s390x)
endif
	dh ${@}

override_dh_clean:
	# An .orig file exists in the release, don't delete it to not create
	# spurious differences to the tarball/git.
	dh_clean -Xtestsuite/synth/synth14/top.vhdl.orig

override_dh_auto_clean:
	# dh_auto_clean complains about python-distutils and fails if it
	# doesn't see a Makefile, so override the default build system.
	dh_auto_clean --buildsystem=makefile

override_dh_installdocs:
	dh_installdocs -pghdl -pghdl-mcode -pghdl-llvm -pghdl-gcc --link-doc=ghdl-common
	dh_installdocs --remaining-packages

override_dh_auto_configure: $(foreach backend,$(BACKENDS),$(STAMPSDIR)/configure-$(backend))

override_dh_auto_build: $(foreach backend,$(BACKENDS),$(STAMPSDIR)/build-$(backend))

override_dh_auto_install: $(foreach backend,$(BACKENDS),$(STAMPSDIR)/install-$(backend))
	@echo
	@echo ------------------------------------------------------------
	@echo Common install final steps
	@echo ------------------------------------------------------------
	install -pD debian/ghdl.wrapper $(CURDIR)/debian/tmp/usr/bin/ghdl
	cd debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH) && ln -s libghdl-*.so libghdl.so
	$(RM) debian/tmp/usr/lib/ghdl/src/ieee2008/LICENSE

override_dh_dwz:
	# dwz currently has problems with some debug sections created by the
	# current LLVM compiler and would cause this step to fail.
	#dh_dwz -a -Nghdl-llvm
	# Furthermore it appears to have problems with something in
	# libghdlvpi.so and runs into assertions, so disable it altogether for
	# now.

override_dh_auto_test: $(foreach backend,$(BACKENDS),$(STAMPSDIR)/test-$(backend))

override_dh_gencontrol:
ifneq ($(filter gcc,$(BACKENDS)),)
	dh_gencontrol -- -VBuilt-Using-GCC="$(shell dpkg-query -f '$${Source} (= $${Version})' -W gcc-$(DEB_GNAT_VERSION)-source)"
else
	dh_gencontrol
endif



$(STAMPSDIR)/configure-mcode:
	dh_testdir
	mkdir -p $(BUILDDIR)/mcode $(STAMPSDIR)
	@echo
	@echo ------------------------------------------------------------
	@echo Configuring with mcode backend
	@echo ------------------------------------------------------------
	cd $(BUILDDIR)/mcode && \
	../../configure --srcdir=../.. $(common_configure_arguments) \
		--libdir=lib/ghdl/mcode
	touch $@

$(STAMPSDIR)/build-mcode: $(STAMPSDIR)/configure-mcode
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Building with mcode backend
	@echo ------------------------------------------------------------
	$(MAKE) -C $(BUILDDIR)/mcode
	touch $@

$(STAMPSDIR)/install-mcode: $(STAMPSDIR)/build-mcode
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Installing with mcode backend
	@echo ------------------------------------------------------------
	$(MAKE) -C $(BUILDDIR)/mcode install DESTDIR=../../debian/tmp
	@echo
	@echo ------------------------------------------------------------
	@echo Moving parts to required locations
	@echo ------------------------------------------------------------
	mkdir -p debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)
	$(RM) -r debian/tmp/usr/lib/ghdl/src
	mv debian/tmp/usr/lib/ghdl/mcode/vhdl/src debian/tmp/usr/lib/ghdl
	ln -s ../../src debian/tmp/usr/lib/ghdl/mcode/vhdl/src
	mv debian/tmp/usr/lib/ghdl/mcode/libghdl-*.so debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/
	mv debian/tmp/usr/lib/ghdl/mcode/libghdl.a debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/
	touch $@

$(STAMPSDIR)/test-mcode: $(STAMPSDIR)/build-mcode
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Run testsuite for mcode backend
	@echo ------------------------------------------------------------
	# With some paths patched for the Debian packaging, the tests will not
	# work right when run from the build directory. To keep it simple
	# install into a temporary location and tell the testsuite to find ghdl
	# there.
	$(MAKE) -C $(BUILDDIR)/mcode install DESTDIR=$(TESTRUNDIR)/mcode
	debian/tests/ghdl-tests buildtest mcode
	touch $@


$(STAMPSDIR)/configure-llvm:
	dh_testdir
	mkdir -p $(BUILDDIR)/llvm $(STAMPSDIR)
	@echo
	@echo ------------------------------------------------------------
	@echo Configuring with llvm backend
	@echo ------------------------------------------------------------
	cd $(BUILDDIR)/llvm && \
	../../configure --srcdir=../.. $(common_configure_arguments) \
		--libdir=lib/ghdl/llvm \
		--with-llvm-config=llvm-config-14
	touch $@

$(STAMPSDIR)/build-llvm: $(STAMPSDIR)/configure-llvm
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Building with llvm backend
	@echo ------------------------------------------------------------
	$(MAKE) -C $(BUILDDIR)/llvm
	touch $@

$(STAMPSDIR)/install-llvm: $(STAMPSDIR)/build-llvm
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Installing with llvm backend
	@echo ------------------------------------------------------------
	$(MAKE) -C $(BUILDDIR)/llvm install DESTDIR=../../debian/tmp
	@echo
	@echo ------------------------------------------------------------
	@echo Moving parts to required locations
	@echo ------------------------------------------------------------
	mkdir -p debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)
	$(RM) -r debian/tmp/usr/lib/ghdl/src
	mv debian/tmp/usr/lib/ghdl/llvm/vhdl/src debian/tmp/usr/lib/ghdl
	ln -s ../../src debian/tmp/usr/lib/ghdl/llvm/vhdl/src
	mv debian/tmp/usr/lib/ghdl/llvm/libghdl-*.so debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/
	mv debian/tmp/usr/lib/ghdl/llvm/libghdl.a debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/
	touch $@

$(STAMPSDIR)/test-llvm: $(STAMPSDIR)/build-llvm
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Run testsuite for llvm backend
	@echo ------------------------------------------------------------
	# With some paths patched for the Debian packaging, the tests will not
	# work right when run from the build directory. To keep it simple
	# install into a temporary location and tell the testsuite to find ghdl
	# there.
	$(MAKE) -C $(BUILDDIR)/llvm install DESTDIR=$(TESTRUNDIR)/llvm
	# Temporarily make LLVM backend testsuite failure non-fatal to more
	# easily collect data for investigating the PSL testsuite failures on
	# some architectures
	-debian/tests/ghdl-tests buildtest llvm
	touch $@


$(STAMPSDIR)/configure-gcc:
	dh_testdir
	mkdir -p $(BUILDDIR)/gcc $(STAMPSDIR)
	@echo
	@echo ------------------------------------------------------------
	@echo Configuring with gcc backend
	@echo ------------------------------------------------------------
	# gcc unpack sequence cribbed from gcc-7-cross debian/rules
	# We have to disable the gcc-verbose-lto-link patch since it replaces
	# the LLINKER value with one that runs the linker under /usr/bin/time
	# and the spaces are not escaped properly somewhere on the ghdl side.
	set -e && \
	cd $(BUILDDIR)/gcc && \
	ln -sf ${GCC_DIR}/gcc-*.tar.* && \
	cp -a  ${GCC_DIR}/debian/ . && \
	if [ -n "$$(grep -v '^\#' ${CURDIR}/debian/gcc-patches/gcc-${DEB_GNAT_VERSION}/series)" ]; then \
		cp -n ${CURDIR}/debian/gcc-patches/gcc-${DEB_GNAT_VERSION}/*.diff debian/patches/  && \
		cat ${CURDIR}/debian/gcc-patches/gcc-${DEB_GNAT_VERSION}/series >> debian/patches/series  && \
		sed -i "s/\(^series_stamp.*\)/debian_patches += $$(grep -v '^#' ${CURDIR}/debian/gcc-patches/gcc-$(DEB_GNAT_VERSION)/series|sed 's/\..*//'|tr '\n' ' ')\n\n\1/" debian/rules.patch ; \
	fi && \
	echo -n > $(BUILDDIR)/gcc/debian/patches/gcc-verbose-lto-link.diff && \
	debian/rules patch && \
	../../configure --srcdir=../.. $(common_configure_arguments) \
		--libdir=lib/ghdl/gcc \
		--with-gcc=src && \
	make copy-sources && \
	$(MAKE) -f debian/rules2 configure PF=usr/lib/ghdl/gcc with_bootstrap=off \
		with_cc1=no with_dev=no separate_lang=yes enabled_languages=vhdl \
		with_common_libs=no with_common_pkgs=no \
		with_check="skipped for GHDL build"
	touch $@

$(STAMPSDIR)/build-gcc: $(STAMPSDIR)/configure-gcc
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Building with gcc backend
	@echo ------------------------------------------------------------
	$(MAKE) $(MAKEPARALLEL) -C $(BUILDDIR)/gcc/build
	# For some reason, on the i386 architecture only, it decides to delete
	# one important build result. Just rerun make as a workaround.
	$(MAKE) $(MAKEPARALLEL) -C $(BUILDDIR)/gcc/build
	$(MAKE) -C $(BUILDDIR)/gcc ghdllib \
		GHDL_GCC_BIN=$(BUILDDIR)/gcc/build/gcc/ghdl \
		GHDL1_GCC_BIN="--GHDL1=$(BUILDDIR)/gcc/build/gcc/ghdl1"
	touch $@

$(STAMPSDIR)/install-gcc: $(STAMPSDIR)/build-gcc
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Installing with gcc backend
	@echo ------------------------------------------------------------
	# Place a symlink for the binary ahead of time so that the compilation
	# of the VHDL standard libraries works during the gcc install step. The
	# binary is properly moved afterwards.
	mkdir -p $(CURDIR)/debian/tmp/usr/bin
	ln -sf ../lib/ghdl/gcc/bin/ghdl-gcc $(CURDIR)/debian/tmp/usr/bin/ghdl-gcc
	$(MAKE) -C $(BUILDDIR)/gcc/build install DESTDIR=$(CURDIR)/debian/tmp
	$(MAKE) -C $(BUILDDIR)/gcc install DESTDIR=$(CURDIR)/debian/tmp
	@echo
	@echo ------------------------------------------------------------
	@echo Moving parts to required locations
	@echo ------------------------------------------------------------
	mkdir -p debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)
	$(RM) -r debian/tmp/usr/lib/ghdl/src
	mv debian/tmp/usr/lib/ghdl/gcc/vhdl/src debian/tmp/usr/lib/ghdl
	ln -s ../../src debian/tmp/usr/lib/ghdl/gcc/vhdl/src
	mv debian/tmp/usr/lib/ghdl/gcc/libghdl-*.so debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/
	mv debian/tmp/usr/lib/ghdl/gcc/libghdl.a debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/
	touch $@

$(STAMPSDIR)/test-gcc: $(STAMPSDIR)/build-gcc
	dh_testdir
	@echo
	@echo ------------------------------------------------------------
	@echo Run testsuite for gcc backend
	@echo ------------------------------------------------------------
	# With some paths patched for the Debian packaging, the tests will not
	# work right when run from the build directory. To keep it simple
	# install into a temporary location and tell the testsuite to find ghdl
	# there.
	mkdir -p $(TESTRUNDIR)/gcc/usr/bin
	# Place a symlink for the binary ahead of time so that the compilation
	# of the VHDL standard libraries works during the gcc install step. The
	# binary is properly moved afterwards (so that it can find its
	# libraries as relative paths from the executable's location).
	ln -sf ../lib/ghdl/gcc/bin/ghdl-gcc $(TESTRUNDIR)/gcc/usr/bin/ghdl-gcc
	$(MAKE) -C $(BUILDDIR)/gcc/build install DESTDIR=$(TESTRUNDIR)/gcc
	$(MAKE) -C $(BUILDDIR)/gcc install DESTDIR=$(TESTRUNDIR)/gcc
	mv $(TESTRUNDIR)/gcc/usr/lib/ghdl/gcc/bin/ghdl-gcc \
	   $(TESTRUNDIR)/gcc/usr/bin/ghdl-gcc
	mv $(TESTRUNDIR)/gcc/usr/lib/ghdl/gcc/lib/ghdl/libbacktrace.a \
	   $(TESTRUNDIR)/gcc/usr/lib/ghdl/gcc/vhdl/libbacktrace.a
	ln -sf ghdl/gcc/lib/gcc $(TESTRUNDIR)/gcc/usr/lib/gcc
	debian/tests/ghdl-tests buildtest gcc
	touch $@


# convenience targets for development
configure-mcode: $(STAMPSDIR)/configure-mcode
build-mcode: $(STAMPSDIR)/build-mcode
install-mcode: $(STAMPSDIR)/install-mcode
test-mcode: $(STAMPSDIR)/test-mcode
.PHONY: configure-mcode build-mcode install-mcode test-mcode

configure-llvm: $(STAMPSDIR)/configure-llvm
build-llvm: $(STAMPSDIR)/build-llvm
install-llvm: $(STAMPSDIR)/install-llvm
test-llvm: $(STAMPSDIR)/test-llvm
.PHONY: configure-llvm build-llvm install-llvm test-llvm

configure-gcc: $(STAMPSDIR)/configure-gcc
build-gcc: $(STAMPSDIR)/build-gcc
install-gcc: $(STAMPSDIR)/install-gcc
test-gcc: $(STAMPSDIR)/test-gcc
.PHONY: configure-gcc build-gcc install-gcc test-gcc
