#!/usr/bin/make -f

PACKAGE := ocaml
ALL_PACKAGES := $(shell dh_listpackages)
OCAMLMAJOR := 3.12
OCAMLMINOR := 1

# Build cache (for Debian debugging)
BUILDCACHE := $(wildcard ../ocaml.cache)

# These are defined here to avoid definition of them in ocamlvars.mk
OCAML_ABI := $(OCAMLMAJOR).$(OCAMLMINOR)
OCAML_STDLIB_DIR := /usr/lib/ocaml
OCAML_NATIVE_ARCHS := $(shell cat debian/native-archs)
OCAML_NATDYNLINK_ARCHS := $(shell cat debian/natdynlink-archs)
DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH)
OCAML_OPT_ARCH := $(findstring $(DEB_BUILD_ARCH),$(OCAML_NATIVE_ARCHS))
OCAML_HAVE_OCAMLOPT := $(if $(OCAML_OPT_ARCH),yes,no)
OCAML_OCAMLDOC_DESTDIR_HTML =

ifneq (,$(findstring $(DEB_BUILD_ARCH),$(OCAML_NATDYNLINK_ARCHS)))
  OCAML_NATDYNLINK := yes
else
  OCAML_NATDYNLINK := no
endif

# dh_ocamlinit cannot be used for ocaml itself
include debian/ocamlinit.mk

MD5SUMSDIR = /var/lib/ocaml/md5sums
INSTDIR = $(CURDIR)/debian/tmp/usr
DISTDIR = $(PACKAGE)-$(OCAML_ABI)
SRCTARBALL = $(PACKAGE)-source-$(OCAML_ABI).tar.bz2

ifneq (,$(findstring ocaml-source,$(ALL_PACKAGES)))
  TARBALL_TARGET = debian/$(SRCTARBALL)
else
  TARBALL_TARGET =
endif

# Environment variable for dh_ocaml
export OCAMLOBJINFO = OCAMLLIB=tools boot/ocamlrun tools/objinfo

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

export DH_OPTIONS
ifeq ($(OCAML_OPT_ARCH),)
  DH_OPTIONS += -Nocaml-native-compilers
endif

# This has to be exported to make gen_modules work
export OCAML_OPT_ARCH
export OCAML_STDLIB_DIR

CONFIGURE_OPTS := \
  --with-pthread -prefix /usr \
  -libdir $(OCAML_STDLIB_DIR) \
  -x11lib "$(shell pkg-config --variable=libdir x11)" \
  -mandir /usr/share/man \
  -tkdefs "-I/usr/include/tcl8.5" \
  -tklibs "-L/usr/lib -ltk8.5 -ltcl8.5"

CONFIGURE_SED := \
  -e "/LIBBFD_LINK/s%-lbfd%-Wl,-Bstatic -lbfd -Wl,-Bdynamic%" \
  -e "s%MANDIR=.*$$%MANDIR=\$$(PREFIX)/share/man%g" \
  -e "s%LIBDIR=.*$$%LIBDIR=\$$(PREFIX)/lib/ocaml%g" \
  -e "s%STUBLIBDIR=.*$$%STUBLIBDIR=\$$(PREFIX)/lib/ocaml/stublibs%g"

%:
	dh $@

ocamlinit-stamp: $(TARBALL_TARGET)

# Generate ocaml-native-compilers' Architecture field.
# Should never be called automatically.
.PHONY: debian/control
debian/control:
	sed -e 's/@OCamlNativeArchs@/$(OCAML_NATIVE_ARCHS)/g' debian/control.in > $@

pre-config-stamp: $(TARBALL_TARGET)
	chmod +x debian/gen_modules.pl
# Backup upstream config.{sub,guess}, and use most up-to-date ones
	for ext in sub guess; do \
	  if [ -f /usr/share/misc/config.$$ext ] && \
	    ! [ -f debian/config.orig.$$ext ]; then \
	    mv config/gnu/config.$$ext debian/config.orig.$$ext; \
	    cp -f /usr/share/misc/config.$$ext config/gnu/config.$$ext; \
	  fi; \
	done
	touch $@

ifneq (,$(TARBALL_TARGET))
$(TARBALL_TARGET):
# Make a copy of the current (patched) sources in debian/$(DISTDIR)
	ln -fs . $(DISTDIR)	# beware of the symlink recursion!
	mkdir debian/$(DISTDIR)
	tar --anchored -ch \
	  --exclude=$(DISTDIR)/$(DISTDIR)	\
	  --exclude-from=debian/ocaml-source.exclude \
	  $(DISTDIR)/ | tar -C debian -x
	rm -f $(DISTDIR)
# Copy patches and unapply them
	cp -a debian/patches debian/$(DISTDIR)/debian-patches
	cd debian/$(DISTDIR) && sort -r debian-patches/series | \
	while read u; do \
	  patch -R -V never -p1 < debian-patches/$$u; \
	done
# Create the tarball and cleanup
	tar -C debian -cjf $@ $(DISTDIR)
	rm -Rf debian/$(DISTDIR)
endif

.PHONY: override_dh_auto_configure
override_dh_auto_configure: config-stamp

config-stamp: pre-config-stamp ocamlinit-stamp
	./configure $(CONFIGURE_OPTS)
	sed -i $(CONFIGURE_SED) config/Makefile
	if test -z "`grep "OTHERLIBRARIES.*labltk" config/Makefile`"; then \
	  echo "Error, labltk library was not detected"; \
	  echo "Check your tcl/tk development packages"; \
	  echo "Aborting."; \
	  exit 1; \
	fi
	touch $@

.PHONY: override_dh_auto_build
override_dh_auto_build: build-stamp

build-stamp: config-stamp
	if test ! -d boot.debian; then \
	  cp -xa boot boot.debian; \
	fi
	rm -Rf debian/examples && mkdir debian/examples
	cp -a otherlibs/labltk/examples_labltk debian/examples/labltk
	find debian/examples/labltk -name .cvsignore -delete
ifeq ($(BUILDCACHE),)
	$(MAKE) world
	$(MAKE) bootstrap
	$(MAKE) -C tools dumpobj
ifeq (,$(OCAML_OPT_ARCH))
# As of 3.11.0, manpages are made only in `make opt.opt'
	make -C ocamldoc manpages \
	  OCAMLDOC_RUN="../boot/ocamlrun -I ../otherlibs/unix -I ../otherlibs/str ./ocamldoc"
else
	@echo "Building native compilers"
	$(MAKE) opt opt.opt
	touch opt-built-stamp
endif
else
	@echo "===> WARNING: $(BUILDCACHE) detected, compilation skipped! <==="
	rsync -a --exclude=debian --exclude=.git $(BUILDCACHE)/ .
	rm -f build-stamp install-stamp
endif
	touch $@

.PHONY: override_dh_auto_clean
override_dh_auto_clean: ocamlinit-clean
ifneq ($(wildcard $(CURDIR)/config/Makefile),)
	$(MAKE) clean
	$(MAKE) -C emacs clean
endif
# Restore files altered by the build process
	if test -d boot.debian; then \
	  rm -Rf boot; \
	  mv boot.debian boot; \
	fi
	for ext in sub guess; do \
	  if [ -f debian/config.orig.$$ext ] ; then \
	    mv -f debian/config.orig.$$ext config/gnu/config.$$ext; \
	  fi; \
	done
	if head -n 1 emacs/ocamltags.in | grep -q '^#!/bin/sh'; then \
		sed -i 1d emacs/ocamltags.in; \
	fi
# Remaining stuff
	-rm -Rf debian/$(SRCTARBALL) debian/examples

.PHONY: override_dh_auto_install
override_dh_auto_install: install-stamp

install-stamp:
ifneq (,$(findstring ocaml-mode,$(ALL_PACKAGES)))
# Install Emacs files
	$(MAKE) -C emacs \
	  EMACSDIR=$(CURDIR)/debian/ocaml-mode/usr/share/emacs/site-lisp/ocaml-mode \
	  NOCOMPILE=true simple-install
	if ! head -n 1 emacs/ocamltags.in | grep -q '^#!/bin/sh'; then \
	  sed -i -e '1 i #!/bin/sh' emacs/ocamltags.in; \
	fi
	$(MAKE) -C emacs SCRIPTDIR=$(CURDIR)/debian/ocaml-mode/usr/bin install-ocamltags
endif
# Install OCaml
	sed -e 's|PREFIX=\"/.*\"|PREFIX=\"$(INSTDIR)"|' < config/config.sh > config/config.debian.install.sh
	$(MAKE) install PREFIX=$(INSTDIR)
# Remove empty directory
	rmdir $(CURDIR)/debian/tmp$(OCAML_STDLIB_DIR)/ocamldoc/custom
# To avoid erroneous dh_install warnings
	rm -f $(INSTDIR)/share/man/man1/ocamlopt.opt.1 $(INSTDIR)/share/man/man1/ocamlc.opt.1
# Dispatch files with dh_install
	cd debian && \
	for u in ocaml ocaml-nox; do \
	  DESTDIR=tmp ./gen_modules.pl $$u.install > $$u.install.new; \
	  mv $$u.install.new $$u.install; \
	done
	if ! dh_install --list-missing; then \
	  echo "===> dh_install has failed <==="; \
	  find debian/tmp; \
	  exit 1; \
	fi
# Install additional files not handled by dh_install
# Beware: dh_install does not handle renamings, please pay attention
	cp otherlibs/labltk/README debian/ocaml/usr/share/doc/ocaml/README.labltk
	for u in dumpobj; do \
	  if [ -f tools/$$u ]; then \
	    cp tools/$$u debian/ocaml-nox/usr/bin/ocaml$$u; \
	  fi \
	done
	for mli in `find camlp4 -name '*.mli'` ; do \
	  cp --parents $$mli debian/camlp4$(OCAML_STDLIB_DIR); \
	done
	for pkg in ocaml ocaml-nox ocaml-base; do ( \
	  cd debian/$$pkg/usr/share/doc/$$pkg && \
	  ln -sf ../ocaml-base-nox/README.gz . && \
	  ln -sf ../ocaml-base-nox/README.Debian .; \
	); done
# Remaining stuff
	touch $@

.PHONY: override_dh_compress
override_dh_compress:
	dh_compress -Xexamples/labltk

.PHONY: override_dh_gencontrol
override_dh_gencontrol:
	for u in $(ALL_PACKAGES); do \
	  echo 'F:OCamlABI=$(OCAML_ABI)' >> debian/$$u.substvars; \
	done
ifeq (,$(OCAML_OPT_ARCH))
	echo 'F:BestProvides=ocaml-best-compilers' >> debian/ocaml-nox.substvars
else
	echo 'F:BestProvides=' >> debian/ocaml-nox.substvars
endif
# Create .md5sums files and compute dependencies. Use $(OCAML_ABI)
# because we know that OCaml ABI represents best dependencies for
# OCaml package.
	dh_ocaml -Xcompiler-libs -Xcamlp4-extra \
	 --runtime-map ocaml-nox:ocaml-base-nox,ocaml:ocaml-base,camlp4 \
	 --checksum $(OCAML_ABI)
	dh_gencontrol
# Check that OCAML_ABI is correct
	if [ "$(OCAML_ABI)" != "$(shell boot/ocamlrun ./ocamlc -version | { read a && echo $${a%%_*}; })" ]; then \
	  echo "Please adjust OCAML_ABI in debian/rules"; \
	  exit 2; \
	fi
