#! /usr/bin/make -f

export DH_OPTIONS

# set the number of build jobs
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
	JOBS := -j$(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
endif

DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)

PKGVERSION = 1.46
SOVERSION = 1.46.1
SHLIBS_VERSION = (>= 1.46.1-1)

pyversions = $(shell pyversions -rv) $(shell py3versions -rv)

# Boost libraries for which we want separate packages
boost_libs := date-time filesystem graph-parallel graph iostreams math \
	mpi mpi-python						       \
	program-options python regex random serialization signals      \
	system test						       \
	thread wave

# these are special cases, where /usr/lib name differs from Boost library name
boost_lib_math := math_c99 math_c99f math_tr1 math_tr1f
boost_lib_math_long_double := math_c99l math_tr1l
boost_lib_serialization := serialization wserialization
boost_lib_test := prg_exec_monitor test_exec_monitor unit_test_framework

# These are special cases for suffixes.  Generally come from --python-buildid, so begin with a dash.
boost_suffixes_python := $(addprefix -py,$(subst .,,$(pyversions)))
boost_suffixes_mpi-python := $(boost_suffixes_python)

# Files that are generated by filtering a template
filtered_files = \
	debian/libboost-doc.doc-base \
	debian/libboost-python-dev.postinst \
	debian/libboost-python-dev.prerm

# Function to map Boost component name to set of shared library names
# Input: Boost component name
# Return: shared library names for the given Boost library
boost_lib = $(if $(boost_lib_$(1)), $(boost_lib_$(1)), $(1))

# Function to map Boost component name to set of suffixes for the library
# Input: Boost component name
# Return: suffixes for the given Boost component
boost_suffixes = $(if $(boost_suffixes_$(1)), $(boost_suffixes_$(1)),"")

# Helpers to make basic and decorated library names
# Input: library, variant, suffix
# Return: base library filename for short or full name
mk_base_name = usr/lib/libboost_$(subst -,_,$(1))$(2)$(3)

# Input: component, variant
# Return: package name for shared library or development
mk_pkg_lib = libboost$(if $(findstring -d,$(2)),$(PKGVERSION)-dbg,-$(1)$(SOVERSION))
mk_pkg_dev = libboost$(if $(findstring -d,$(2)),$(PKGVERSION)-dbg,-$(1)$(PKGVERSION)-dev)

# Helpers to generate debhelper input filenames.
# Input: component, variant
# Return: prefix to debhelper filenames
mk_deb_lib = debian/$(call mk_pkg_lib,$(1),$(2))
mk_deb_dev = debian/$(call mk_pkg_dev,$(1),$(2))

# Helpers that update debhelper .install or .links files
# Input: component, library, variant, suffix
# Output: none
mk_so_files = $(shell echo debian/tmp/$(call mk_base_name,$(2),$(3),$(4)).so.$(SOVERSION) >> $(call mk_deb_lib,$(1),$(3)).install)
mk_a_files = $(shell echo debian/tmp/$(call mk_base_name,$(2),$(3),$(4)).a >> $(call mk_deb_dev,$(1),$(3)).install)
mk_ln_files = $(shell echo $(call mk_base_name,$(2),$(3),$(4)).so.$(SOVERSION) $(call mk_base_name,$(2),$(3),$(4)).so >> $(call mk_deb_dev,$(1),$(3)).links)

# Make compatibility symlinks libfoo-mt --> libfoo
mk_mtso_files = $(shell echo $(call mk_base_name,$(2),$(3),$(4)).so.$(SOVERSION) $(call mk_base_name,$(2),$(3)-mt,$(4)).so >> $(call mk_deb_dev,$(1),$(3)).links)
mk_mta_files = $(shell echo $(call mk_base_name,$(2),$(3),$(4)).a $(call mk_base_name,$(2),$(3)-mt,$(4)).a >> $(call mk_deb_dev,$(1),$(3)).links)

# Specify the type of files/links to install.
# Special cases first, then general rule
boost_filetypes_test_exec_monitor = a mta
boost_filetypes = $(if $(boost_filetypes_$(1)), $(boost_filetypes_$(1)),a so ln mtso mta)

# Function that updates debhelper files for a given library variant
# Input: component, library, variant, suffix
# Output: none
mk_files = $(foreach fn,$(call boost_filetypes,$(2)),$(call mk_$(fn)_files,$(1),$(2),$(3),$(4)))

# helpers to make and install lintian override files

# Input: package, override
add_override = echo $(1): $(2) >> debian/$(1).lintian-overrides;

# Input: override
add_dbg_override = $(call add_override,libboost$(PKGVERSION)-dbg,$(1))
add_dev_override = $(call add_override,libboost$(PKGVERSION)-dev,$(1))
add_doc_override = $(call add_override,libboost$(PKGVERSION)-doc,$(1))

# Input: component, variant, lintian-warning
add_lib_override = $(call add_override,$(call mk_pkg_lib,$(1),$(2)),$(3))
add_libdev_override = $(call add_override,$(call mk_pkg_dev,$(1),$(2)),$(3))

cp_debhelper = for s in doc-base examples postinst prerm README.Debian; do \
	if test -f debian/$(1).$$s; then cp -f debian/$(1).$$s debian/$(2).$$s; fi; done

# Function that updates debhelper files for all library variants shipped.
mk_debhelper_files = \
	$(call add_dbg_override,package-name-doesnt-match-sonames) \
	$(call add_dbg_override,non-dev-pkg-with-shlib-symlink) \
	$(call add_dbg_override,dbg-package-missing-depends) \
	$(call add_dev_override,description-synopsis-starts-with-a-capital-letter) \
	$(call add_dev_override,spelling-error-in-description) \
	$(call add_dev_override,extra-license-file) \
	$(call add_doc_override,description-synopsis-starts-with-a-capital-letter) \
	$(call add_doc_override,extra-license-file) \
	$(call add_libdev_override,python,,description-synopsis-starts-with-a-capital-letter) \
	$(foreach l, $(boost_libs), \
		echo "making debhelper files for $(l)..."; \
		$(call add_lib_override,$(l),,package-name-doesnt-match-sonames) \
		$(foreach ll, $(call boost_lib,$(l)), \
			$(foreach suf, $(call boost_suffixes,$(l)), \
				$(call mk_files,$(l),$(ll),,$(suf)) \
			) \
		) \
	)

TOOLSET_CONFIG="using gcc ;"
BUILD_LONG_DOUBLE = yes

ifeq ($(DEB_BUILD_ARCH), hppa)
TOOLSET_CONFIG="using gcc : : : <compileflags>-mlong-calls <compileflags>-DBOOST_SP_USE_PTHREADS ;"
BUILD_LONG_DOUBLE = no
else ifeq ($(DEB_BUILD_ARCH), arm)
BUILD_LONG_DOUBLE = no
else ifeq ($(DEB_BUILD_ARCH), armel)
BUILD_LONG_DOUBLE = no
else ifeq ($(DEB_BUILD_ARCH), armhf)
BUILD_LONG_DOUBLE = no
else ifeq ($(DEB_BUILD_ARCH), mips)
BUILD_LONG_DOUBLE = no
else ifeq ($(DEB_BUILD_ARCH), mipsel)
BUILD_LONG_DOUBLE = no
else ifeq ($(DEB_BUILD_ARCH), sh4)
BUILD_LONG_DOUBLE = no
endif

ifeq ($(BUILD_LONG_DOUBLE), yes)
boost_lib_math += $(boost_lib_math_long_double)
else
JAM_OPT += --disable-long-double
endif

MPI_CONFIG = "using mpi ;"

exampledir = debian/libboost$(PKGVERSION)-doc/usr/share/doc/libboost$(PKGVERSION)-doc/examples
htmldir = debian/libboost$(PKGVERSION)-doc/usr/share/doc/libboost$(PKGVERSION)-doc/HTML
pyste_prefix = $(CURDIR)/debian/libboost-python$(PKGVERSION)-dev/usr
bjam = $(CURDIR)/bjam
bbv2dir = $(CURDIR)/tools/build/v2

# With --ignore-site-config, can probably drop Build-Conflicts on boost-build.
JAM = $(bjam) $(JOBS) -d2 $(JAM_OPT) --layout=system --ignore-site-config --user-config=$(CURDIR)/user-config.jam debug-symbols=on

$(bjam):
	./bootstrap.sh --with-icu --prefix=$(CURDIR)/debian/tmp/usr \
	  || cat bootstrap.log

debian/bjam.1: $(bjam)
	help2man --name 'software build tool' --no-info ./bjam > $@

user-config.jam:
	echo $(TOOLSET_CONFIG) > $@
	echo $(MPI_CONFIG)     >> $@
	for pyver in $(filter-out $(shell pyversions -dv),$(pyversions)); do \
		echo "using python : $$pyver : /usr ;" >> $@; \
	done

build: build-stamp
build-stamp: $(bjam) user-config.jam
	dh_testdir

	$(JAM) --without-python                        
	for pyver in $(pyversions); do \
	 	pyid=$$(echo $$pyver | tr -d .); \
		echo "Building Boost.Python for python version $$pyver"; \
	 	$(JAM) --with-python --with-mpi --python-buildid=py$$pyid python=$$pyver; \
	 	mv stage/lib/mpi.so stage/lib/mpi-py$$pyid.so; \
	done

	cd $(bbv2dir) && ./bootstrap.sh --with-toolset=gcc
	cd tools/bcp && $(JAM)
	cd tools/inspect/build && $(JAM)
	cd tools/quickbook && $(JAM)
	cd tools/wave/build && $(JAM)
	cd tools/regression/build && $(JAM)
	cd libs/python/pyste/install && python setup.py build

	touch build-stamp

$(filtered_files): % : %.in
	sed -e 's/@PKGVERSION@/$(PKGVERSION)/g' < $< > $@

clean-debhelper:
	rm -rf debian/*.install
	rm -rf debian/*.links
	rm -rf debian/*.lintian-overrides

clean: clean-debhelper
	dh_testdir
	dh_testroot
	rm -f build-stamp

	-cd tools && $(JAM) clean
	-$(JAM) clean
	-cd libs/python/pyste/install && python setup.py clean

	rm -rf libs/python/pyste/install/build
	rm -rf tools/jam/src/bootstrap
	rm -rf tools/jam/src/bin.*
	rm -ff tools/jam/src/bjam
	rm -rf tools/regression/build/bin
	rm -rf bin.v2 dist
	rm -rf user-config.jam
	rm -rf debian/bjam.1

	dh_clean build-stamp

# This rule is for debugging debian/rules.
make-debhelper: clean-debhelper
	@$(call mk_debhelper_files)

install: DH_OPTIONS=-X.svn
install: build clean-debhelper $(filtered_files) debian/bjam.1
	dh_testdir
	dh_testroot
	dh_prep

	@$(call cp_debhelper,libboost-dbg,libboost$(PKGVERSION)-dbg)
	@$(call cp_debhelper,libboost-dev,libboost$(PKGVERSION)-dev)
	@$(call cp_debhelper,libboost-doc,libboost$(PKGVERSION)-doc)
	@$(call cp_debhelper,libboost-python-dev,libboost-python$(PKGVERSION)-dev)
	@$(call cp_debhelper,libboost-mpi-python-dev,libboost-mpi-python$(PKGVERSION)-dev)

	$(JAM) --prefix=$(CURDIR)/debian/tmp/usr install --without-python                        
	for pyver in $(pyversions); do \
		pyid=`echo $$pyver | tr -d .`; \
		$(JAM) --prefix=$(CURDIR)/debian/tmp/usr install --with-python --with-mpi --python-buildid=py$$pyid python=$$pyver; \
	done

	# Install Boost.Build v2 & jam
	cd $(bbv2dir) && ./bjam install --prefix=$(CURDIR)/debian/tmp/usr
	mv debian/tmp/usr/share/boost-build/example debian/boost-build-examples

	install --mode=755 -D debian/rtupdate debian/tmp/usr/share/python/runtime.d/libboost-python$(PKGVERSION)-dev.rtupdate
	install --mode=755 -D debian/rtupdate debian/tmp/usr/share/python/runtime.d/libboost-mpi-python$(PKGVERSION)-dev.rtupdate

	find debian/tmp/usr/include debian/tmp/usr/share/boost-build -type f | xargs chmod 644
	find debian/tmp -name .cvsignore | xargs rm -f
	find debian -empty -type f | xargs rm -f

	# generate (some) debhelper files
	@$(call mk_debhelper_files)

	# package libboost-dbg

	# package libboost$(PKGVERSION)-dev
	dh_install -plibboost$(PKGVERSION)-dev \
	   debian/tmp/usr/include/boost \
	   usr/include
	dh_install -plibboost$(PKGVERSION)-dev \
	   debian/tmp/usr/bin/bjam \
	   dist/bin/bcp \
	   dist/bin/inspect \
	   dist/bin/quickbook \
	   usr/bin
	dh_installman -plibboost$(PKGVERSION)-dev debian/bjam.1 debian/bcp.1 debian/inspect.1 debian/quickbook.1
	dh_install -plibboost$(PKGVERSION)-dev tools/boostbook/xsl/* usr/share/boostbook/xsl
	dh_install -plibboost$(PKGVERSION)-dev tools/boostbook/dtd/* usr/share/boostbook/dtd
	dh_install -plibboost$(PKGVERSION)-dev debian/tmp/usr/share/boost-build

	# package libboost-doc
	rm -rf $(htmldir)
	mkdir -p $(htmldir) 
	cat debian/documentation-files | xargs cp --parents --target-directory=$(htmldir)
	find doc libs -name doc | xargs -n1 cp --archive --parents --target-directory=$(htmldir)
	rm -rf $(htmldir)/boost
	dh_link -plibboost$(PKGVERSION)-doc \
	   usr/include/boost \
	   usr/share/doc/libboost$(PKGVERSION)-doc/HTML/boost
	# provide a constant symlink to the latest documents
	dh_link -plibboost$(PKGVERSION)-doc \
	   usr/share/doc/libboost$(PKGVERSION)-doc/HTML \
	   usr/share/doc/libboost-doc/HTML

	dh_installexamples -plibboost$(PKGVERSION)-doc debian/boost-build-examples
	mkdir -p $(exampledir)
	cat debian/example-files | xargs cp -a --parents --target-directory=$(exampledir)
	find $(exampledir) -type f | xargs chmod 644

	# package libboost-mpi-python$(SOVERSION)
	dh_install -plibboost-mpi-python$(SOVERSION)
	for pyver in $(pyversions); do \
		pyid=`echo $$pyver | tr -d .`; \
		dh_install -plibboost-mpi-python$(SOVERSION) libs/mpi/build/__init__.py usr/lib/python$$pyver/site-packages/boost; \
		dh_installdirs -plibboost-mpi-python$(SOVERSION) usr/lib/python$$pyver/site-packages/boost; \
		cp stage/lib/mpi-py$$pyid.so debian/libboost-mpi-python$(SOVERSION)/usr/lib/python$$pyver/site-packages/boost/mpi.so; \
	done
	# package libboost-mpi-python$(PKGVERSION)-dev
	dh_install -plibboost-python$(PKGVERSION)-dev --autodest \
	   debian/tmp/usr/share/python/runtime.d/libboost-mpi-python$(PKGVERSION)-dev.rtupdate
	# package libboost-python$(PKGVERSION)-dev
	dh_install -plibboost-python$(PKGVERSION)-dev --autodest \
	   debian/tmp/usr/share/python/runtime.d/libboost-python$(PKGVERSION)-dev.rtupdate

	cd libs/python/pyste/install && python setup.py install --no-compile --prefix=$(pyste_prefix) --install-lib=$(pyste_prefix)/share/pyshared
	mv $(pyste_prefix)/bin/pyste.py $(pyste_prefix)/bin/pyste
	dh_installman -plibboost-python$(PKGVERSION)-dev debian/pyste.1


# This single target is used to build all the packages, all at once, or
# one at a time. So keep in mind: any options passed to commands here will
# affect _all_ packages. Anything you want to only affect one package
# should be put in another target, such as the install target.
binary-common:
	dh_testdir
	dh_testroot
	dh_install
	dh_installdocs --all debian/README.Debian debian/NEWS.Debian
	dh_installexamples
	dh_installinfo
	dh_installchangelogs
	dh_lintian
	dh_strip --dbg-package=libboost$(PKGVERSION)-dbg -X"-d-"
	dh_link
	dh_compress -Xlibboost$(PKGVERSION)-doc/HTML
	dh_python2
	dh_python3
	dh_fixperms

	@if [ "$(DH_OPTIONS)" = "-a" ]; then \
		echo DH_OPTIONS=-plibboost$(PKGVERSION)-dbg dh_makeshlibs -V"libboost$(PKGVERSION)-dbg $(SHLIBS_VERSION)"; \
		DH_OPTIONS=-plibboost$(PKGVERSION)-dbg dh_makeshlibs -V"libboost$(PKGVERSION)-dbg $(SHLIBS_VERSION)"; \
		for name in $(boost_libs); do \
			lib=libboost-$${name}$(SOVERSION); \
			echo DH_OPTIONS=-p$${lib} dh_makeshlibs -V"$${lib} $(SHLIBS_VERSION)"; \
			DH_OPTIONS=-p$${lib} dh_makeshlibs -V"$${lib} $(SHLIBS_VERSION)"; \
		done; \
	fi

	dh_installdeb
	dh_shlibdeps
	dh_gencontrol
	dh_md5sums
	dh_builddeb

# Build architecture independant packages using the common target.
binary-indep: build install
	$(MAKE) -f debian/rules DH_OPTIONS=-i binary-common

# Build architecture dependant packages using the common target.
binary-arch: build install
	$(MAKE) -f debian/rules DH_OPTIONS=-a binary-common

# Any other binary targets build just one binary package at a time.
binary-%: build install
	$(MAKE) -f debian/rules binary-common DH_OPTIONS=-p$*

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