#!/usr/bin/make -f

, := ,
space :=
space +=
$(space) := 
$(space) +=

vendor := $(shell if dpkg-vendor --derives-from Ubuntu; then echo ubuntu; else echo debian; fi)

GCC_VER := $(shell dpkg-parsechangelog |egrep ^Source:|cut -f2 -d' '|cut -f2 -d'-')

ifeq ($(GCC_VER),4.8)
  MIN_VER_GCC      := 4.8.1-16
  PPA_VER_GCC      := 4.8.1
endif

ifeq ($(GCC_VER),4.9)
  MIN_VER_GCC      := 4.9.2-10ubuntu5~
  PPA_VER_GCC      := 4.9.1
endif

ifeq ($(GCC_VER),5)
  MIN_VER_GCC      := 5.1.1-5~
  PPA_VER_GCC      := 5.1.1
endif

ifndef MIN_VER_GCC
  MIN_VER_GCC      := ${GCC_VER}.0-0~
endif

DEB_NAME_ACT     := $(shell dpkg-parsechangelog| sed -n 's/-*//; s/^Source: \(.*\)/\1/p')
DEB_SVER_ACT     := $(shell dpkg-parsechangelog| sed -n 's/-*//; s/^Version: \(.*\)/\1/p')
DEB_VER_ACT      := $(shell /bin/sh debian/new_cross_version.sh)
CROSS_EXT       := cross$(DEB_VER_ACT)

VER_GCC        := $(shell dpkg-parsechangelog -l/usr/src/gcc-${GCC_VER}/debian/changelog | egrep '^Version:' | cut -f 2 -d ' '|cut -f 1 -d '-')
GCC_DIR        := /usr/src/gcc-${GCC_VER}
VER_BINUTILS   := 2.25
MIN_VER_BINUTILS   := 2.25
VER_ISL      := 0.14-1~
MIN_VER_GLIBC   := 2.19

DEB_VER_GCC    := $(shell dpkg-parsechangelog -l${GCC_DIR}/debian/changelog | egrep '^Version:' | cut -f 2 -d ' ')

CROSS_BIARCH_armhf:=armel
CROSS_BIARCH_armel:=armhf
CROSS_BIARCH_powerpc:=ppc64

HOST_ARCHS_armhf = amd64 i386 arm64
HOST_ARCHS_armel = amd64 i386 arm64
HOST_ARCHS_powerpc = amd64 i386 ppc64el
HOST_ARCHS_arm64 = amd64 i386
HOST_ARCHS_ppc64el = amd64 i386

HOST_GNU_TYPE    := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
HOST_ARCH        := $(shell dpkg-architecture -qDEB_HOST_ARCH)
stamp            := stamp-dir/

CROSS_ARCHES     ?= ppc64el powerpc arm64 armhf armel
ifeq ($(HOST_ARCH),arm64)
  CROSS_ARCHES = armhf
else ifeq ($(HOST_ARCH),ppc64el)
  CROSS_ARCHES = powerpc
endif
CROSS_ARCH       = $(subst .,,$(suffix $@))
KERNEL_ARCH      = $(KERNEL_ARCH_$(CROSS_ARCH))
CROSS_BIARCH     = $(CROSS_BIARCH_$(CROSS_ARCH))
_gnu_type        = $(shell dpkg-architecture -a$(1) -qDEB_HOST_GNU_TYPE -f)
CROSS_GNU_TYPE   = $(call _gnu_type,${CROSS_ARCH})
HOST_ARCHS       = $(HOST_ARCH_$(CROSS_ARCH))

ARM32_MULTILIBS :=
ifeq ($(vendor),ubuntu)
  ARM32_MULTILIBS := yes
endif

ifeq ($(vendor),ubuntu)
  keep_dbg_packages = yes
endif

BINUTILS_BUILD_DEPS = $(foreach a,$(CROSS_ARCHES),binutils-$(call _gnu_type,$(a)) (>= $(MIN_VER_BINUTILS)) [$(HOST_ARCHS_$(a))]$(,))
GLIBC_BUILD_DEPS = $(foreach a,$(CROSS_ARCHES),libc6-dev-$(a)-cross (>= $(MIN_VER_GLIBC)) [$(HOST_ARCHS_$(a))]$(,))

# build multilib cross compilers
ifeq ($(ARM32_MULTILIBS),yes)
  ifneq (,$(filter armel, $(CROSS_ARCHES)))
    EXTRA_BUILD_DEPS += libc6-dev-armhf-cross [$(HOST_ARCHS_armel)],
  endif

  ifneq (,$(filter armhf, $(CROSS_ARCHES)))
    EXTRA_BUILD_DEPS += libc6-dev-armel-cross [$(HOST_ARCHS_armhf)],
  endif
endif

ifneq (,$(filter powerpc, $(CROSS_ARCHES)))
  EXTRA_BUILD_DEPS += libc6-dev-ppc64-powerpc-cross [$(HOST_ARCHS_powerpc)],
endif

PHOBOS_ARCHS = amd64 i386 x32 armel armhf
PHOBOS_DEP = libphobos-GCC_VER-dev-CROSS_ARCH-cross (= $${gcc:Version}),

info:
	@echo "Package name:             ${DEB_NAME_ACT} ${DEB_VER_ACT}"
	@echo
	@echo "GCC ${GCC_VER} version:          ${VER_GCC}     	${DEB_VER_GCC}"
	@echo
	@echo "Target architecture:      ${CROSS_ARCH}"
	@echo "Target GNU type:          ${CROSS_GNU_TYPE}"
	@echo "Host architecture:        ${HOST_ARCH}"
	@echo "Host GNU type:            ${HOST_GNU_TYPE}"

$(stamp)init-gcc:
	@echo START $@
	mkdir -p gcc
	set -ex; \
	cd gcc ; \
	ln -sf ${GCC_DIR}/gcc-${VER_GCC}.tar.xz gcc-${VER_GCC}.tar.xz ;\
	cp -a  ${GCC_DIR}/debian/ . ; \
	if [ -n "$$(grep -v '^\#' ${CURDIR}/debian/patches/gcc-${GCC_VER}/series)" ]; then \
	  QUILT_PATCHES=${CURDIR}/debian/patches/gcc-${GCC_VER} quilt push -a ; \
	fi
	touch $@

$(stamp)build-gcc.%: $(stamp)init-gcc
	@echo START $@
	echo ${CROSS_ARCH} >gcc/debian/target
	# cross build do not do docs so we do not have all build dependencies
	cd gcc && WITH_SYSROOT=/ PKG_IGNORE_CURRENTLY_BUILDING=1 BACKPORT=false dpkg-buildpackage -b -uc -us -d
	touch $@

clean:
	rm -rf gcc tmp
	rm -f  *.*deb *.changes debian/files
	rm -rf $(stamp)
	rm -f debian/no-packages
	mkdir $(stamp)
	dh_clean

define repack_debs
	umask 022; \
	cross_arch=$$(echo $1); \
	cross_gnu_type=$(call _gnu_type,$1); \
	for deb in $2; \
	do \
	    if [ "$(keep_dbg_packages)" != yes ]; then \
	      case $$deb in *-dbg*) continue; esac; \
	    fi; \
	    echo "repack $$deb ..."; \
	    rm -rf tmp/*; \
	    dpkg-deb -x $$deb tmp; \
	    dpkg-deb -e $$deb tmp/DEBIAN; \
	    pkgname=`echo $$deb | cut -d'_' -f1`; \
	    sed -i -e's/^Source:.*/Source: $(DEB_NAME_ACT) ($(DEB_SVER_ACT))/' \
	      -e "/^Depends:/s/$(DEB_VER_GCC)/$(DEB_VER_GCC)$(CROSS_EXT)/g" \
	      -e "/^Recommends:/s/$(DEB_VER_GCC)/$(DEB_VER_GCC)$(CROSS_EXT)/g" \
	      -e "/^Suggests:/s/$(DEB_VER_GCC)/$(DEB_VER_GCC)$(CROSS_EXT)/g" \
	      -e "/^Version:/s/$(DEB_VER_GCC)/$(DEB_VER_GCC)$(CROSS_EXT)/" tmp/DEBIAN/control ; \
	    case $$deb in \
	      gcc-$(GCC_VER)-$(call _gnu_type,$1)) \
	        sed -i -e '/Depends/s/\(libcc1[^,]*\)$(CROSS_EXT)/\1/' tmp/DEBIAN/control; \
	    esac; \
	    sed -i -e "s/$(CROSS_EXT)$(CROSS_EXT)/$(CROSS_EXT)/g" tmp/DEBIAN/control ; \
	    install -d -m 755 tmp/usr/share/lintian/overrides; \
	    if [ -e debian/overrides/$$pkgname ]; then \
		  cp debian/overrides/$$pkgname tmp/usr/share/lintian/overrides/; \
	    fi; \
	    case "$$pkgname" in \
	      gcc-$(GCC_VER)-multilib) \
	        echo "$$pkgname binary: binary-from-other-architecture" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname \
	        ;; \
	      *-multilib-*) \
	        ;; \
	      cpp*|g*) \
	        echo "$$pkgname binary: binary-from-other-architecture" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname \
	        ;; \
	      *-dev-$1-cross) \
	        echo "$$pkgname binary: arch-independent-package-contains-binary-or-object" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        echo "$$pkgname binary: non-standard-dir-in-usr" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        echo "$$pkgname binary: " \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        ;; \
	      *-dbg-$1-cross) \
	        echo "$$pkgname binary: arch-independent-package-contains-binary-or-object" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        echo "$$pkgname binary: debug-package-should-be-named-dbg" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        ;; \
	      *-pic-$1-cross) \
	        echo "$$pkgname binary: arch-independent-package-contains-binary-or-object" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        ;; \
	      *-$1-cross) \
	        echo "$$pkgname binary: arch-independent-package-contains-binary-or-object" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        echo "$$pkgname binary: non-standard-dir-in-usr" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        echo "$$pkgname binary: shlibs-declares-dependency-on-other-package" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        echo "$$pkgname binary: postinst-has-useless-call-to-ldconfig" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        echo "$$pkgname binary: postrm-has-useless-call-to-ldconfig" \
	          >> tmp/usr/share/lintian/overrides/$$pkgname; \
	        ;; \
	    esac; \
	    if [ -e tmp/usr/share/doc/gcc-${GCC_VER}-$${cross_gnu_type}-base/changelog.Debian.gz ]; then \
	      mv tmp/usr/share/doc/gcc-${GCC_VER}-$${cross_gnu_type}-base/changelog.Debian.gz \
	         tmp/usr/share/doc/gcc-${GCC_VER}-$${cross_gnu_type}-base/changelog.Debian.gcc-${GCC_VER}.gz; \
	      gzip -c9 debian/changelog > tmp/usr/share/doc/gcc-${GCC_VER}-$${cross_gnu_type}-base/changelog.Debian.gz;\
	    fi ; \
	    rm -f tmp/DEBIAN/md5sums; \
	    (cd tmp && find usr -type f | LC_ALL=C sort | xargs -r md5sum >>DEBIAN/md5sums); \
	    find tmp/DEBIAN -name md5sums -empty | xargs -r rm -f; \
	    newdeb=`echo $$deb|sed -e "s/\(.*\)_\(.*\)_\(.*\)/\1_\2$(CROSS_EXT)_\3/g"`; \
	    dpkg-deb -b tmp ../$$newdeb; \
	    rm -rf tmp/*; \
	done;
endef

$(stamp)repack-debs-arch: build
	@echo START $@
	$(call repack_debs,$(HOST_ARCH), *_$(HOST_ARCH).deb)
	$(call repack_debs,$(HOST_ARCH), *$(DEB_VER_GCC)_$(HOST_ARCH).ddeb)
	rm -f *$(DEB_VER_GCC)_$(HOST_ARCH).ddeb
	if [ -f ../gcc-$(GCC_VER)-$(call _gnu_type,$(HOST_ARCH))-dbgsym_${DEB_VER_GCC}$(CROSS_EXT)_$(HOST_ARCH).ddeb ]; then mv -f ../*.ddeb . ; fi
	touch $@

$(stamp)repack-debs-indep: $(foreach arch,$(CROSS_ARCHES),$(addsuffix .$(arch),$(stamp)repack-debs-indep))
	touch $@

$(stamp)repack-debs-indep.%: build
	@echo START $@
	$(call repack_debs,$(CROSS_ARCH), *-$(CROSS_ARCH)-cross_*_all.deb)
	touch $@

build:	$(stamp)build
$(stamp)build: $(foreach arch,$(CROSS_ARCHES),$(addsuffix .$(arch),$(stamp)build-gcc))
	@echo START $@
	# why remove the plugin package?
	rm -f gcc-*-plugin-dev-*.*deb

build-arch:  $(stamp)build mangle-debian-files-arch
build-indep: $(stamp)build mangle-debian-files-indep

binary: binary-arch binary-indep
binary-arch:  build-arch
binary-indep: build-indep

define generate_debian_files
	for deb in $1; do \
	  if [ "$(keep_dbg_packages)" != yes ]; then \
	    case $$deb in *-dbg*) continue; esac; \
	  fi; \
	  echo -n "`basename $$deb` " >>debian/files; \
	  dpkg-deb -I $$deb | grep Section  | cut -d ' ' -f 3 | tr "\n" ' ' >>debian/files; \
	  dpkg-deb -I $$deb | grep Priority | cut -d ' ' -f 3 | tr -d "\n" >>debian/files; \
	  echo "" >>debian/files; \
	done
endef

mangle-debian-files-arch: $(stamp)debian-files-base build $(stamp)repack-debs-arch
	@echo START $@
	$(call generate_debian_files, *_$(HOST_ARCH).deb)
	sed -i -e "s/${DEB_VER_GCC}_/${DEB_VER_GCC}$(CROSS_EXT)_/g" debian/files

mangle-debian-files-indep: $(stamp)debian-files-base $(stamp)repack-debs-indep
	@echo START $@
	$(call generate_debian_files, *_all.deb)
	sed -i -e "s/${DEB_VER_GCC}_/${DEB_VER_GCC}$(CROSS_EXT)_/g" debian/files

$(stamp)debian-files-base:
	@echo START $@
	rm -f debian/files
	touch $@


control:
	sed -e "s/MIN_VER_GCC/${MIN_VER_GCC}/g" \
	    -e "s/BINUTILS_BUILD_DEPS/$(BINUTILS_BUILD_DEPS)/g" \
	    -e "s/GLIBC_BUILD_DEPS/$(GLIBC_BUILD_DEPS)/g" \
	    -e "s/EXTRA_BUILD_DEPS/${EXTRA_BUILD_DEPS}/g" \
	    -e "s/GCC_VER/${GCC_VER}/g" \
	    -e "s/MIN_VER_BINUTILS/${MIN_VER_BINUTILS}/g" \
	    -e "s/VER_BINUTILS/${VER_BINUTILS}/g" \
	    -e "s/VER_ISL/${VER_ISL}/g" \
	    $(CURDIR)/debian/control.source.in >$(CURDIR)/debian/control

	$(foreach a,$(CROSS_ARCHES), \
	  sed \
	    -e 's/PHOBOS_DEP/$(if $(filter $(a),$(PHOBOS_ARCHS)),${PHOBOS_DEP})/g' \
	    -e 's/CROSS_ARCH/$(a)/g' \
	    -e 's/CROSS_GNU_TYPE/$(call _gnu_type,$(a))/g' \
	    -e 's/MIN_VER_GCC/${MIN_VER_GCC}/g' \
	    -e 's/GCC_VER/${GCC_VER}/g' \
	    -e 's/MIN_VER_BINUTILS/${MIN_VER_BINUTILS}/g' \
	    -e 's/@host_archs@/$(HOST_ARCHS_$(a))/g' \
	    $(CURDIR)/debian/control.$(a).in >>$(CURDIR)/debian/control; )

ifeq ($(vendor),ubuntu)
	grep -v multilib-arm-linux-gnueabi debian/no-packages.in > debian/no-packages
else
	cp debian/no-packages.in debian/no-packages
endif
	python3 debian/remove-unbuilt \
	  $(if $(filter yes,$(keep_dbg_packages)), --keep-dbg-packages) \
	  debian/control debian/no-packages \
	  > debian/control.new && mv debian/control.new debian/control

.PRECIOUS: $(stamp)init-dirs \
	$(stamp)init-gcc \
	$(stamp)build-gcc.% \
	$(stamp)debian-files-base \
	$(stamp)repack-debs-arch \
	$(stamp)repack-debs-indep \
	$(stamp)repack-debs-indep.% \
	mangle-debian-files-arch
	mangle-debian-files-indep \
	build build-arch build-indep binary binary-arch binary-indep
