#!/usr/bin/make -f
# -*- makefile -*-
# Build gnat-mingw-w64 using gcc-4.8-source.
# Copyright © 2010-2014 Stephen Kitt <skitt@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

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

target_version := 4.8

top_dir := $(shell pwd)
gcc_dir := /usr/src/gcc-$(target_version)
upstream_dir := $(top_dir)/src
build_dir := $(top_dir)/build
stampdir := $(top_dir)/stamps
source_version := $(shell dpkg-query -W -f="\$${Version}\n" gcc-$(target_version)-source)
deb_version := $(source_version)+$(shell dpkg-parsechangelog | sed -ne "s/^Version: \(.*\)/\1/p")
deb_upstream_version := $(shell echo $(deb_version) | cut -d- -f1)
deb_upstream_nextversion := $(shell echo $(deb_upstream_version) | awk -F. "{ for (i = 1; i < NF; i++) { printf \"%d.\",\$$i; }; print (\$$NF + 1); }")
base_version := $(shell echo $(deb_version) | sed -e 's/\([1-9]\.[0-9]\).*-.*/\1/')
derives_from_ubuntu := $(shell (dpkg-vendor --derives-from Ubuntu && echo "yes") || echo "no")

# First split version
first_split_version := 4.6.3-3+4
ifeq ($(derives_from_ubuntu),yes)
  first_split_version := 4.6.3-1ubuntu5+5ubuntu1
endif

# Include the rules variant - symlink rules.bootstrap to produce the
# minimal gcc required to build mingw-w64, or rules.full to produce
# the full gcc.
include debian/rules.variant

targets := i686-w64-mingw32 x86_64-w64-mingw32

# No hardening support for now
dpkg_buildflags = DEB_BUILD_MAINT_OPTIONS="hardening=-all" dpkg-buildflags

CC = gcc-$(target_version)
CXX = g++-$(target_version)
CFLAGS = $(shell $(dpkg_buildflags) --get CFLAGS)
CFLAGS += -Wall
CPPFLAGS = $(shell $(dpkg_buildflags) --get CPPFLAGS)
CXXFLAGS = $(shell $(dpkg_buildflags) --get CXXFLAGS)
CXXFLAGS += -Wall
FFLAGS = $(shell $(dpkg_buildflags) --get FFLAGS)
LDFLAGS = $(shell $(dpkg_buildflags) --get LDFLAGS)
LDFLAGS += -Wl,--as-needed
export CC CXX CFLAGS CPPFLAGS CXXFLAGS FFLAGS LDFLAGS

# Number of jobs to run for build
ifeq ($(USE_NJOBS),no)
  NJOBS :=
  USE_CPUS := 1
else
  # Increase to 192 if building Java
  MEM_PER_CPU = 128
  NUM_CPUS := $(shell if echo $(USE_NJOBS) | grep -q -E '^[0-9]+$$'; \
                        then echo $(USE_NJOBS); \
                        else getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1; fi)
  USE_CPUS := $(shell mt=`awk '/^MemTotal/ { print $$2 }' /proc/meminfo`; \
                        awk -vn=$(NUM_CPUS) -vmt=$$mt -vm=$(MEM_PER_CPU) \
                                'END { mt/=1024; n2 = int(mt/m); print n==1 ? 1 : n2<n+1 ? n2 : n+1}' < /dev/null)
  ifneq (,$(strip $(USE_CPUS)))
    NJOBS := -j $(USE_CPUS)
  endif
endif

# Support parallel=<n> in DEB_BUILD_OPTIONS (see #209008)
ifneq (,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS))))
  NJOBS := -j $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS))))
endif

# Patch targets
patchdir = $(gcc_dir)/debian/patches
series_file = series
unpack_stamp = $(stampdir)/unpack
patch_stamp = $(stampdir)/patch
GFDL_INVARIANT_FREE=yes
srcdir=$(upstream_dir)
include $(gcc_dir)/debian/rules.patch

unpack: $(unpack_stamp)
$(unpack_stamp):
	tar xf $(gcc_dir)/gcc-*.tar.*
	rm -rf $(upstream_dir)
	mv gcc-$(deb_upstream_version) $(upstream_dir)
	# Apply our extra patches here...
	# We can't use a separate target for this because the patches
	# need to be applied before gcc-4.8-source's
	patch -p0 < debian/patches/disable-multilib.patch
	mkdir -p $(stampdir)
	touch $@

clean: control
	dh_testdir
	dh_testroot
	rm -rf $(stampdir) $(build_dir) $(upstream_dir) .pc autotools_files series *-stamp
	dh_clean

# Configuration constructed as in the gcc package
PF=usr
libdir=lib
libexecdir=$(PF)/$(libdir)

# Standard Debian configuration flags
CONFFLAGS = \
	--prefix=/$(PF) \
	--enable-shared \
	--enable-static \
	--disable-multilib \
	--with-system-zlib \
	--libexecdir=/$(libexecdir) \
	--without-included-gettext \
	--libdir=/$(PF)/$(libdir) \
	--enable-libstdcxx-time=yes \
	--with-tune=generic
# MinGW-w64 flags
# version-specific-runtime-libs puts target-specific libraries in
# /usr/lib/gcc rather than /usr/$(target)
CONFFLAGS += \
	--enable-version-specific-runtime-libs \
	--enable-threads=posix \
	--enable-fully-dynamic-string \
	--enable-sjlj-exceptions \
	--enable-libgomp
# Languages
CONFFLAGS += \
	--enable-languages=$(languages)
# LTO
CONFFLAGS += \
	--enable-lto \
	--with-plugin-ld

# Patches applied or unapplied after the upstream sources have been
# unpacked and patched using the gcc-4.8-source package's patches
mingw-w64-patch: mingw-w64-patch-stamp
mingw-w64-patch-stamp: $(patch_stamp)
	# Remove the patch building libstdc++_pic.a before configuring
	patch -R -p2 -d$(upstream_dir) < $(gcc_dir)/debian/patches/libstdc++-pic.diff
	touch $@

configure: configure-stamp
configure-stamp: control-stamp mingw-w64-patch-stamp
	dh_testdir
	set -e; \
	echo ============= Building with the following debian/control =============
	cat debian/control
	echo ======================================================================
	for target in $(targets); do \
		dh_auto_configure -B$(build_dir)/$$target -D$(upstream_dir) -- \
			$(CONFFLAGS) \
			--target=$$target \
			--with-gxx-include-dir=/$(PF)/include/c++/$(base_version) \
			--with-as=/usr/bin/$$target-as \
			--with-ld=/usr/bin/$$target-ld; \
	done
	touch $@

build: build-arch build-indep
build-arch: build-arch-stamp
build-arch-stamp: configure-stamp
	dh_testdir
	set -e; \
	for target in $(targets); do \
		cd $(build_dir)/$$target && $(MAKE) $(NJOBS) $(BUILD_TARGET); \
	done
	touch $@
build-indep: build-indep-stamp
build-indep-stamp:
	touch $@

install-arch: install-arch-stamp
install-arch-stamp: build-arch-stamp
	dh_testdir
	dh_testroot
	dh_prep
	set -e; \
	for target in $(targets); do \
		cd $(build_dir)/$$target && $(MAKE) DESTDIR=$(top_dir)/debian/tmp $(INSTALL_TARGET); \
	done

	# Remove files which conflict with other packages
	# gcc-$(target_version)-locales
	rm -rf $(top_dir)/debian/tmp/usr/share/locale
	# binutils-dev
	rm -f $(top_dir)/debian/tmp/usr/lib/libiberty.a
	# libstdc++6-$(target_version)-dbg (potentially)
	rm -rf $(top_dir)/debian/tmp/usr/share/gcc-*/python
	# libstdc++6-$(target_version)-dev
	ls -1 $(top_dir)/debian/tmp/usr/include/c++/$(base_version)/|grep -v w64-mingw32|xargs -I{} rm -rf $(top_dir)/debian/tmp/usr/include/c++/$(base_version)/{}
	# -doc packages
	rm -rf $(top_dir)/debian/tmp/usr/share/info
	rm -rf $(top_dir)/debian/tmp/usr/share/man/man7

	# No need to ship empty manpages
	rm -rf $(top_dir)/debian/tmp/usr/share/man/man1

	# Drop .la files
	find $(top_dir)/debian/tmp -name \*.la -delete

	# Move libraries to base directories and add version-specific links
	if [ "$$(basename debian/tmp/usr/share/gcc-*)" != "gcc-*" ]; then \
		for gnu_upstream_version in $$(basename debian/tmp/usr/share/gcc-*|cut -d- -f2); do \
			if [ "$$gnu_upstream_version" != "$(base_version)" ]; then \
				[ -d $(top_dir)/debian/tmp/usr/include/c++ ] && cd $(top_dir)/debian/tmp/usr/include/c++ && ln -s $(base_version) $$gnu_upstream_version || true; \
				for target in $(targets); do \
					cd $(top_dir)/debian/tmp/$(PF)/lib/gcc/$$target && \
					mv $$gnu_upstream_version $(base_version) && \
					ln -s $(base_version) $$gnu_upstream_version; \
				done; \
			fi; \
		done; \
	fi

	# Move misplaced DLLs and libraries
	for target in $(targets); do \
		if [ -f $(top_dir)/debian/tmp/usr/lib/gcc/$$target/lib/*.a ]; then \
			mv $(top_dir)/debian/tmp/usr/lib/gcc/$$target/lib/*.a $(top_dir)/debian/tmp/usr/lib/gcc/$$target/$(base_version)/; \
		fi; \
		if [ -f $(top_dir)/debian/tmp/usr/lib/gcc/$$target/*.dll ]; then \
			mv $(top_dir)/debian/tmp/usr/lib/gcc/$$target/*.dll $(top_dir)/debian/tmp/usr/lib/gcc/$$target/$(base_version)/; \
		fi; \
	done

	for i in 1 2; do \
		find $(top_dir)/debian/tmp/ -type d -empty | while read i; do rmdir $$i; done; \
	done

	touch $@

binary-indep: build-indep
	dh_testdir
	dh_testroot
	dh_installdocs -i --link-doc=gnat-mingw-w64-base
	dh_installchangelogs -i $(upstream_dir)/ChangeLog
	dh_lintian -i
	dh_link -i
	dh_compress -i
	dh_fixperms -i
	dh_installdeb -i
	dh_gencontrol -i -- -v$(deb_version) -Vlocal:Version=$(deb_upstream_version) -Vlocal:NextVersion=$(deb_upstream_nextversion) -Vgcc:Version=$(source_version) -Vsplit:Version=$(first_split_version)
	dh_md5sums -i
	dh_builddeb -i

binary-arch: build-arch install-arch
	dh_testdir
	dh_testroot
	dh_install -a --list-missing
	dh_installdocs -a --link-doc=gnat-mingw-w64-base
	dh_installman -a
	dh_installchangelogs -a $(upstream_dir)/ChangeLog
	# Strip the binaries
ifneq (,$(findstring ada,$(languages)))
	dh_strip -a -Xw64-mingw32/lib -Xw64-mingw32/$(base_version)/lib -Xw64-mingw32/$(base_version)/adalib
else
	dh_strip -a -Xw64-mingw32/lib -Xw64-mingw32/$(base_version)/lib
endif
	# Strip the libraries
ifeq (,$(filter nostrip,$(DEB_BUILD_OPTIONS)))
	find $(top_dir)/debian -type f -name liblto_plugin.so.\*.\*.\* | xargs strip --remove-section=.comment --remove-section=.note --strip-unneeded
	for target in $(targets); do \
		find $(top_dir)/debian -type f -name lib\*.a | grep $$target | xargs -r $$target-strip --strip-unneeded; \
	done
endif
	dh_lintian -a
	dh_link -a
	dh_compress -a
	dh_fixperms -a
	# Fix permissions further
ifneq (,$(findstring ada,$(languages)))
	# *.ali files must be read-only
	find $(top_dir)/debian -name \*.ali | xargs -r chmod 444
endif
	# *.dll files shouldn't be executable
	find $(top_dir)/debian -name \*.dll | xargs -r chmod 644
	dh_installdeb -a
	dh_shlibdeps -a
	dh_gencontrol -a -- -v$(deb_version) -Vlocal:Version=$(deb_upstream_version) -Vlocal:NextVersion=$(deb_upstream_nextversion) -Vgcc:Version=$(source_version) -Vsplit:Version=$(first_split_version)
	dh_md5sums -a
	dh_builddeb -a

binary: binary-indep binary-arch

.PHONY: binary-indep binary-arch binary clean build-indep build-arch build install-arch configure mingw-w64-patch
