#! /usr/bin/make -f

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

# version number of the defaults package
include /usr/share/dpkg/pkg-info.mk

VMAJOR	:= $(shell echo $(DEB_VERSION) | awk -F. '{print $$1}')
VMINOR	:= $(shell echo $(DEB_VERSION) | awk -F. '{print $$2}' | sed -e 's/\([0-9]*\).*/\1/')
REL_EXT	:= $(shell echo $(DEB_VERSION) | sed -e 's/^$(VMAJOR)\.$(VMINOR)//')

# llvm-defaults 0.1 is the first version for 2.7.
REL_NO_27	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.2 is the first version for 2.8.
REL_NO_28	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.7 is the first version for 2.9.
REL_NO_29	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.9 is the first version for 3.0.
REL_NO_30	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.10 is the first version for 3.1.
REL_NO_31	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.16 is the first version for 3.2.
REL_NO_32	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.21 is the first version for 3.3.
REL_NO_33	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.22 is the first version for 3.4.
REL_NO_34	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.24 is the first version for 3.5.
REL_NO_35	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.27 is the first version for 3.6.
REL_NO_36	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults (not in debian) is the first version for 3.7.
REL_NO_37	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.34 is the first version for 3.8.
REL_NO_38	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults (not in debian) is the first version for 3.9.
REL_NO_39	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.37 is the first version for 4.0.
REL_NO_40	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.41 is the first version for 5.0.
REL_NO_50	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.41 is the first version for 6.0.
REL_NO_60	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.44 is the first version for 7.0.
REL_NO_70	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.48 is the first version for 8.0.
REL_NO_80	:= $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.49 is the first version for 9.0.
REL_NO_90   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.50 is the first version for 10.
REL_NO_100   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.51 is the first version for 11.
REL_NO_110   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.52 is the first version for 12.
REL_NO_120   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.53 is the first version for 13.
REL_NO_130   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.53 is the first version for 14.
REL_NO_140   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.56 is the first version for 15.
REL_NO_150   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.57 is the first version for 16.
REL_NO_160   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.58 is the first version for 17.
REL_NO_170   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.59 is the first version for 18.
REL_NO_180   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.60 is the first version for 19.
REL_NO_190   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.60ubuntu1~ppa1 is the first version for 20.
REL_NO_200   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# llvm-defaults 0.63 is the first version for 21.
REL_NO_210   := $(shell expr $(VMINOR) - 0)$(REL_EXT)

# minimum required version

LV		= 21
REQV            = (>= 1:$(LV).1.6-1)
CURRENT_VERSION = $(LV).1.6

# complete version number, including the release
CV_LLVM		:= 1:$(CURRENT_VERSION)-$(REL_NO_210)

# architecture dependent variables
include /usr/share/dpkg/architecture.mk

# get some build information from llvm-toolchain-$(LV)
ifeq (,$(wildcard /usr/lib/llvm-$(LV)/share/debian_config.mk))
  $(error file /usr/lib/llvm-$(LV)/share/debian_config.mk not found, install llvm-$(LV)-dev)
else
include /usr/lib/llvm-$(LV)/share/debian_config.mk
endif

distribution := $(shell lsb_release -is)
all_packages   := llvm llvm-runtime llvm-dev \
	clang clang-tools libclang-cpp-dev libclang-dev clang-format clang-tidy clangd \
	python3-clang libomp-dev libc++-dev libc++abi-dev libllvm-ocaml-dev libclang-rt-dev \
	libc++-dev-wasm32 libclang-rt-dev-wasm32 libclang-rt-dev-wasm64 libclang-rt-dev-win \
	flang
no_packages    :=

LLVM_BUILD_DEPS = llvm-$(LV) $(REQV), llvm-$(LV)-runtime, llvm-$(LV)-dev, \
	clang-$(LV), clang-tools-$(LV), clangd-$(LV), \
	clang-tidy-$(LV), clang-format-$(LV), lld-$(LV), \
	lldb-$(LV) [$(LLDB_ARCHS)], \
	flang-$(LV) [$(FLANG_ARCHS)], \
	bolt-$(LV) [$(BOLT_ARCHS)], \


ifneq (,$(filter $(DEB_HOST_ARCH),$(LLDB_ARCHS)))
    all_packages += lldb liblldb-dev python3-lldb
else
    no_packages += lldb liblldb-dev python3-lldb
endif

ifneq (,$(filter $(DEB_HOST_ARCH),$(LLD_ARCHS)))
    all_packages += lld liblld-dev
else
    no_packages += lld liblld-dev
endif

ifneq (,$(filter $(DEB_HOST_ARCH),$(FLANG_ARCHS)))
    all_packages += flang libflang-dev
else
    no_packages += flang libflang-dev
endif

ifneq (,$(filter $(DEB_HOST_ARCH),$(BOLT_ARCHS)))
    all_packages += llvm-bolt libbolt-dev
else
    no_packages += llvm-bolt libbolt-dev
endif

ifneq (,$(filter $(DEB_HOST_ARCH),$(POLLY_ARCHS)))
    all_packages += libpolly-dev
else
    no_packages += libpolly-dev
endif

# 64bit and i386
ifneq (,$(filter $(DEB_HOST_ARCH),$(CLANG_RT_ARCHS)))
    #all_packages += libclang-rt-dev
else
    no_packages += libclang-rt-dev
endif


packages := $(filter-out $(no_packages), $(all_packages))

# derived version number (without release)
V_LLVM  := $(shell echo $(CV_LLVM) | sed 's/^[0-9]*://' | sed 's/-[^-]*$$//')

# number for the package name
PV_LLVM := $(shell echo $(V_LLVM) | awk -F. '{printf "%d", $$1}')

OS_NAME := Linux

ifeq ($(DEB_HOST_ARCH),hurd-i386)
    OS_NAME	:= Hurd
endif

ifneq (,$(filter $(DEB_HOST_ARCH),kfreebsd-i386 kfreebsd-amd64))
    OS_NAME	:= kFreeBSD
endif

README:
	m4 -DPACKAGES="$(packages)" \
	   -DOS_NAME=$(OS_NAME) \
	   -DDEB_ARCH=$(DEB_HOST_ARCH) \
	   -DPV_LLVM=$(PV_LLVM) \
	   debian/README.Debian.m4 > debian/README.Debian.tmp2
	uniq debian/README.Debian.tmp2 > debian/README.Debian.tmp
	rm -f debian/README.Debian.tmp2
	[ -e debian/README.Debian ] \
	  && cmp -s debian/README.Debian debian/README.Debian.tmp \
	  && rm -f debian/README.Debian.tmp && exit 0; \
	  mv debian/README.Debian.tmp debian/README.Debian
.PHONY: README

substvars:
	( \
	  echo 'version:llvm=$(CV_LLVM)'; \
	  echo 'pv:llvm=$(PV_LLVM)'; \
	  echo 'reqv:llvm=$(REQV)'; \
	) > debian/substvars.local
.PHONY: substvars
build: build-arch build-indep
build-arch: build-stamp
build-indep: build-stamp
build-stamp: control-stamp
	dh_testdir
	touch build-stamp

clean:
	dh_testdir
	rm -f *-stamp
	rm -f debian/substvars.local
	dh_clean

# link_bin_and_man(<unversioned pkg>, <versioned pkg>)
define link_bin_and_man
	@echo 'link_bin_and_man $(1) -> $(2)'
	dpkg -l $(2) 2>/dev/null | grep '^ii'
	for f in $$(dpkg -L $(2)); do \
	  case $$f in /usr/bin/*-$(LV)|/usr/share/man/man1/*-$(LV).1.gz) \
	    lnk=$$(echo $$f | sed -e 's/-$(LV)//'); \
	    mkdir -p debian/$(strip $(1))/$$(dirname $$lnk); \
	    echo ln -s $$(basename $$f) debian/$(strip $(1))$$lnk; \
	    ln -s $$(basename $$f) debian/$(strip $(1))$$lnk;; \
	  esac; \
	done
endef

install: build README substvars
	dh_testdir
	dh_prep

	for p in $(packages); do \
	  cp -l debian/substvars.local debian/$$p.substvars; \
	done

	: # llvm
	dh_installdirs -pllvm
	$(call link_bin_and_man, llvm, llvm-$(LV))

	: # clang
	$(call link_bin_and_man, clang, clang-$(LV))

	: # clang-tools
	$(call link_bin_and_man, clang-tools, clang-tools-$(LV))

	: # clang-format
	$(call link_bin_and_man, clang-format, clang-format-$(LV))
	dh_link -pclang-format \
		/usr/share/vim/addons/syntax/clang-format-$(PV_LLVM).py \
		/usr/share/vim/addons/syntax/clang-format.py
	dh_link -pclang-format \
		/usr/share/emacs/site-lisp/clang-format-$(PV_LLVM) \
		/usr/share/emacs/site-lisp/clang-format

	: # clangd
	$(call link_bin_and_man, clangd, clangd-$(LV))

	: # clang-tidy
	$(call link_bin_and_man, clang-tidy, clang-tidy-$(LV))

	: # llvm-runtime
	$(call link_bin_and_man, llvm-runtime, llvm-$(LV)-runtime)

	: # llvm-dev
	dh_installdirs -pllvm-dev \
		/usr/include \
		/usr/share/vim/addons/syntax/ \
		/usr/lib
	dh_link -pllvm-dev \
		/usr/lib/llvm-$(PV_LLVM)/include/llvm /usr/include/llvm \
		/usr/lib/llvm-$(PV_LLVM)/include/llvm-c /usr/include/llvm-c \
		/usr/share/vim/addons/syntax/llvm-$(PV_LLVM).vim /usr/share/vim/addons/syntax/llvm.vim \
		/usr/share/vim/addons/syntax/tablegen-$(PV_LLVM).vim /usr/share/vim/addons/syntax/tablegen.vim \
		/usr/share/emacs/site-lisp/llvm-$(PV_LLVM) /usr/share/emacs/site-lisp/llvm

	for lib in \
		libLTO.so LLVMgold.so; do \
		dh_link -pllvm-dev \
		/usr/lib/llvm-$(PV_LLVM)/lib/$$lib /usr/lib/$$lib; \
	done

ifneq (,$(filter $(DEB_HOST_ARCH),$(LLDB_ARCHS)))
	: # lldb
	$(call link_bin_and_man, lldb, lldb-$(LV))

	: # liblldb-dev
	dh_installdirs -pliblldb-dev \
		/usr/include \
		/usr/lib
	dh_link -pliblldb-dev \
		/usr/lib/llvm-$(PV_LLVM)/include/lldb /usr/include/lldb \

	for lib in \
		liblldb.so; do \
		dh_link -pliblldb-dev \
		/usr/lib/llvm-$(PV_LLVM)/lib/$$lib /usr/lib/$$lib; \
	done
endif

	: # lld
	$(call link_bin_and_man, lld, lld-$(LV))

	: # liblld-dev
	dh_installdirs -pliblld-dev \
		/usr/include
	dh_link -pliblld-dev \
		/usr/lib/llvm-$(PV_LLVM)/include/lld /usr/include/lld \

ifneq (,$(filter $(DEB_HOST_ARCH),$(OCAML_ARCHS)))
	: # libllvm-ocaml-dev
	dh_installdirs -plibllvm-ocaml-dev \
		/usr/lib/ocaml/METAS
	dh_link -plibllvm-ocaml-dev \
		/usr/lib/ocaml/META.llvm /usr/lib/ocaml/METAS/META.llvm
endif

ifneq (,$(filter $(DEB_HOST_ARCH),$(FLANG_ARCHS)))
	: # flang
	$(call link_bin_and_man, flang, flang-$(LV))
endif

ifneq (,$(filter $(DEB_HOST_ARCH),$(BOLT_ARCHS)))
	: # bolt
	$(call link_bin_and_man, llvm-bolt, bolt-$(LV))
endif


nopkgs := $(foreach p, $(no_packages),-N$(p))

binary-indep: build install
	# nothing to do

binary-arch: build install
	dh_testdir

	dh_lintian
	dh_installchangelogs -a $(nopkgs)
	dh_installdocs -a $(nopkgs) debian/README.Debian

	dh_compress -a $(nopkgs) -X README.Debian
	dh_fixperms -a $(nopkgs)
	dh_installdeb -a $(nopkgs)

	for p in $(packages) ; do \
	  dh_gencontrol -p$$p -- -v$(CV_LLVM) ; \
	done

	dh_md5sums -a $(nopkgs)
	dh_builddeb -a $(nopkgs)

control-stamp: debian/control
debian/control: debian/rules debian/control.in
	sed \
	    -e "s|@ANY_ARCHS@|$(sort $(ANY_ARCHS))|g" \
	    -e "s|@BOLT_ARCHS@|$(sort $(BOLT_ARCHS))|g" \
	    -e "s|@CLANG_GRPC_ARCHS@|$(CLANG_GRPC_ARCHS)|g" \
	    -e "s|@CLANG_RT_ARCHS@|$(CLANG_RT_ARCHS)|g" \
	    -e "s|@FLANG_ARCHS@|$(FLANG_ARCHS)|g" \
	    -e "s|@HWASAN_ARCHS@|$(HWASAN_ARCHS)|g" \
	    -e "s|@LIBFUZZER_ARCHS@|$(sort $(LIBFUZZER_ARCHS))|g" \
	    -e "s|@LIBUNWIND_ARCHS@|$(sort $(LIBUNWIND_ARCHS))|g" \
	    -e "s|@LLD_ARCHS@|$(sort $(LLD_ARCHS))|g" \
	    -e "s|@LLDB_ARCHS@|$(LLDB_ARCHS)|g" \
	    -e "s|@LLVM_LIBC_ARCHS@|$(LLVM_LIBC_ARCHS)|g" \
	    -e "s|@LLVM_SPIRV_ARCHS@|$(LLVM_SPIRV_ARCHS)|g" \
	    -e "s|@MULTILIB_ARCHS@|$(MULTILIB_ARCHS)|g" \
	    -e "s|@OCAML_ARCHS@|$(OCAML_ARCHS)|g" \
	    -e "s|@OFFLOAD_ARCHS@|$(OFFLOAD_ARCHS)|g" \
	    -e "s|@OMP_ARCHS@|$(OMP_ARCHS)|g" \
	    -e "s|@OMPD_ARCHS@|$(OMPD_ARCHS)|g" \
	    -e "s|@POLLY_ARCHS@|$(sort $(POLLY_ARCHS))|g" \
	    -e "s|@LLVM_BUILD_DEPS@|$(strip $(LLVM_BUILD_DEPS))|g" \
		debian/control.in > debian/control


binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install
