#!/usr/bin/make -f

# POSIX.1-2008:
#   If the pathname does not begin with a '/' it shall be treated as relative to
#   the current working directory of the process, not relative to the directory
#   containing the makefile.
include ../source.mk
include ../targets.mk

base_version = $$(printf '%s\n' '$(OPK_SOURCE)' | sed 's/^gcc-//')

target = $$(printf '%s' '$@' | sed 's/^[a-z]*-//')

builddir = obj-$(target)
destdir = dest-$(target)

# /usr/lib/<target>/ld.so is a symbolic link for use by GCC to find the system's
# dynamic linker.  It should be provided by the development package of any
# standard C library.
# ProteanOS GCC should build binaries with an ELF INTERP field as follows:
#   /lib/<target>/<soname>
# <soname> is the SONAME of the target's dynamic linker.
elf_interp = /lib/$(target)/$(elf_interp_soname)
elf_interp_soname = $$(readelf -d "/usr/lib/$(target)/ld.so" | \
	sed -n 's/^.*(SONAME).*\[\([^]]*\)\].*$$/\1/p')

common_opts = \
	--with-pkgversion='GCC for ProteanOS' \
	--program-suffix="-$(base_version)" \
	--enable-linker-build-id \
	--with-system-zlib \
	--disable-multilib \
	--enable-multiarch \
	--without-included-gettext \
	--with-nls \
	--with-sysroot="$${OPK_SYSROOT}" \
	--with-gxx-include-dir=/usr/include/c++-4.7 \
	--enable-clocale=gnu

full_opts = \
	$(common_opts) \
	--enable-shared \
	--enable-threads=posix \
	--enable-languages=c,c++

bootstrap1_opts = \
	$(common_opts) \
	--without-headers \
	--with-newlib \
	--disable-shared \
	--disable-threads \
	--enable-languages=c,c++ \
	--disable-libgomp \
	--disable-libmudflap \
	--disable-libssp

include ../local.mk

nop:
	@:

../local.mk:
	>../local.mk

$(configure_targets):
	set -e; \
	. "../targets.d/$(target).sh"; \
	if [ 'x$(OPK_HOST_PLAT)' = 'xbootstrap1' ]; then \
		oh-autoconfigure -B "$(builddir)" -t "$(target)" -- \
		$(bootstrap1_opts) \
		$${target_opts}; \
	else \
		oh-autoconfigure -B "$(builddir)" -t "$(target)" -- \
		$(full_opts) \
		$${target_opts}; \
	fi
	touch $@

configure: $(configure_targets)
	touch $@

$(build_targets): configure
	# Set the default dynamic linker path inserted into ELF INTERP fields.
	# These default values are in header files in gcc/config.  They must be
	# edited here rather than in a patch because any given GCC target
	# configuration can be used by multiple ProteanOS targets.
	set -e; \
	. "../targets.d/$(target).sh"; \
	mv "src/gcc/config/$${gcc_config_file}" \
		"src/gcc/config/$${gcc_config_file}~"; \
	define_pattern=".define $${gcc_config_interp_macro}"; \
	sed "s|^\($${define_pattern}\) \".*\"$$|\1 \"$(elf_interp)\"|" \
		"src/gcc/config/$${gcc_config_file}~" \
		>"src/gcc/config/$${gcc_config_file}"; \
	sed "$${gcc_config_fragment_script}" \
		"src/gcc/config/$${gcc_config_fragment}" \
		>"src/gcc/config/$${gcc_config_fragment}~"; \
	mv "src/gcc/config/$${gcc_config_fragment}~" \
		"src/gcc/config/$${gcc_config_fragment}"; \
	printf '\nMULTIARCH_DIRNAME = %s\n' "$(target)" \
		>>"src/gcc/config/$${gcc_config_fragment}"
	if [ "x$(target)" = 'x$(OPK_HOST_ARCH)' ]; then \
		$(MAKE) -f ../build "buildnative-$(target)"; \
	else \
		$(MAKE) -f ../build "buildcross-$(target)"; \
	fi
	touch $@

$(buildnative_targets):
	libsubdir="/usr/lib/$(target)/gcc-$(base_version)" && \
	oh-autobuild -B "$(builddir)" -T bootstrap-lean -- -j $${JOBS:-1} \
		libsubdir="$${libsubdir}" \
		libexecsubdir="$${libsubdir}" \
		gcc_gxx_tool_include_dir="/usr/include/$(target)/c++-4.7" \
		libsubincludedir="$${libsubdir}/include" \
		fincludedir="$${libsubdir}/finclude" \
		toolexeclibdir="/usr/lib/$(target)" \
		MULTIOSDIR=.
	if [ '$(OPK_BUILD_ARCH)' = '$(OPK_HOST_ARCH)' ]; then \
		cd "$(builddir)" && make -k check; \
	fi

$(buildcross_targets):
	libsubdir="/usr/lib/$(target)/gcc-$(base_version)" && \
	oh-autobuild -B "$(builddir)" -T all-gcc -- -j $${JOBS:-1} \
		libsubdir="$${libsubdir}" \
		libexecsubdir="$${libsubdir}" \
		gcc_gxx_tool_include_dir="/usr/include/$(target)/c++-4.7" \
		libsubincludedir="$${libsubdir}/include" \
		fincludedir="$${libsubdir}/finclude" \
		toolexeclibdir="/usr/lib/$(target)" \
		MULTIOSDIR=.

build: $(build_targets)
	touch $@

$(install_targets): build
	if [ "x$(target)" = 'x$(OPK_HOST_ARCH)' ]; then \
		$(MAKE) -f ../build "installnative-$(target)"; \
	else \
		$(MAKE) -f ../build "installcross-$(target)"; \
	fi

$(installnative_targets):
	# The -T option is necessary because otherwise:
	#   * oh-autoinstall checks for an "install" target by running make with
	#     the -n option,
	#   * Many commands in GCC makefiles contain the "$(MAKE)" macro
	#     expansion, and
	#   * GNU Make executes any commands that contain "$(MAKE)", even if -n
	#     is specified.
	# See also: <http://gcc.gnu.org/ml/gcc/2013-04/msg00171.html>.
	libsubdir="/usr/lib/$(target)/gcc-$(base_version)" && \
	oh-autoinstall -B "$(builddir)" -d "$(destdir)" -T install -- \
		host_installdir=/usr/include/$(target)/c++-4.7/bits \
		libsubdir="$${libsubdir}" \
		libexecsubdir="$${libsubdir}" \
		libsubincludedir="$${libsubdir}/include" \
		fincludedir="$${libsubdir}/finclude" \
		toolexeclibdir="/usr/lib/$(target)" \
		MULTIOSDIR=.
	# Change the target architecture prefix of files in /usr/bin.
	rm -f $(destdir)/usr/bin/*-gcc-$(base_version).*
	for f in c++ g++ gcc gcc-ar gcc-nm gcc-ranlib; do \
		rm -f $(destdir)/usr/bin/$${f}-$(base_version); \
		mv $(destdir)/usr/bin/*-$${f}-$(base_version) \
			$(destdir)/usr/bin/$(target)-$$(printf '%s' \
				$(destdir)/usr/bin/*-$${f}-$(base_version) | \
				sed "s/^.*-\($${f}\)/\1/"); \
		ln -sf $(target)-$$(printf '%s' \
				$(destdir)/usr/bin/*-$${f}-$(base_version) | \
				sed "s/^.*-\($${f}\)/\1/") \
			$(destdir)/usr/bin/$$(printf '%s' \
				$(destdir)/usr/bin/*-$${f}-$(base_version) | \
				sed "s/^.*-\($${f}\)/\1/"); \
	done
	# Remove the internal libiberty.a.
	rm -f $(destdir)/usr/lib/$(target)/libiberty.a
	# Move libstdc++.so link.
	rm -f $(destdir)/usr/lib/$(target)/libstdc++.so
	ln -sf /usr/lib/$(target)/libstdc++.so.6 \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/libstdc++.so
	# Move libstdc++.a and libsupc++.a.
	mv $(destdir)/usr/lib/$(target)/libstdc++.a \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/
	mv $(destdir)/usr/lib/$(target)/libsupc++.a \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/
	# Move libmudflap.so and libmudflapth.so links.
	rm -f $(destdir)/usr/lib/$(target)/libmudflap.so
	ln -sf /usr/lib/$(target)/libmudflap.so.0 \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/libmudflap.so
	rm -f $(destdir)/usr/lib/$(target)/libmudflapth.so
	ln -sf /usr/lib/$(target)/libmudflapth.so.0 \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/libmudflapth.so
	# Move libmudflap.a and libmudflapth.a.
	mv $(destdir)/usr/lib/$(target)/libmudflap.a \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/
	mv $(destdir)/usr/lib/$(target)/libmudflapth.a \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/
	# Move libssp.so link.
	rm -f $(destdir)/usr/lib/$(target)/libssp.so
	ln -sf /usr/lib/$(target)/libssp.so.0 \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/libssp.so
	# Move libssp.a and libssp_nonshared.a.
	mv $(destdir)/usr/lib/$(target)/libssp.a \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/
	mv $(destdir)/usr/lib/$(target)/libssp_nonshared.a \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/
	# Move libgcc_s.so.1 under /lib.
	mkdir -p $(destdir)/lib/$(target)
	mv $(destdir)/usr/lib/$(target)/libgcc_s.so.1 $(destdir)/lib/$(target)
	# Move libgcc_s.so link.
	rm -f $(destdir)/usr/lib/$(target)/libgcc_s.so
	ln -sf /lib/$(target)/libgcc_s.so.1 \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/libgcc_s.so
	# Remove libquadmath files.
	rm -f $(destdir)/usr/lib/$(target)/libquadmath.*
	# Move libgomp.so link.
	rm -f $(destdir)/usr/lib/$(target)/libgomp.so
	ln -sf /usr/lib/$(target)/libgomp.so.1 \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/libgomp.so
	# Move libgomp.a and libgomp.spec.
	mv $(destdir)/usr/lib/$(target)/libgomp.a \
		$(destdir)/usr/lib/$(target)/libgomp.spec \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/
	# Move libitm.so link.
	rm -f $(destdir)/usr/lib/$(target)/libitm.so
	ln -sf /usr/lib/$(target)/libitm.so.1 \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/libitm.so
	# Move libitm.a and libitm.spec.
	mv $(destdir)/usr/lib/$(target)/libitm.a \
		$(destdir)/usr/lib/$(target)/libitm.spec \
		$(destdir)/usr/lib/$(target)/gcc-$(base_version)/
	# Remove libtool archives.
	libdir=/usr/lib/$(target) && \
	rm -f \
		$(destdir)$${libdir}/libmudflap.la \
		$(destdir)$${libdir}/libmudflapth.la \
		$(destdir)$${libdir}/libssp.la \
		$(destdir)$${libdir}/libssp_nonshared.la \
		$(destdir)$${libdir}/gcc-$(base_version)/liblto_plugin.la \
		$(destdir)$${libdir}/libquadmath.la \
		$(destdir)$${libdir}/libgomp.la \
		$(destdir)$${libdir}/libitm.la \
		$(destdir)$${libdir}/libstdc++.la \
		$(destdir)$${libdir}/libsupc++.la
	# Remove the info directory node.
	rm -f $(destdir)/usr/share/info/dir
	# Remove empty documentation files.
	find $(destdir)/usr/share/man -type f -a -size 0c -a \
		-exec rm -f '{}' ';'
	find $(destdir)/usr/share/info -type f -a -size 0c -a \
		-exec rm -f '{}' ';'
	# TODO: Provide these files in a fixincludes package (arch:any,
	# target-specific?).
	rm -Rf $(destdir)/usr/lib/$(target)/gcc-$(base_version)/install-tools/
	# TODO: Provide these files in a libstdc++-*-dbg package.
	rm -f $(destdir)/usr/lib/$(target)/libstdc++.so.*-gdb.py
	rm -Rf $(destdir)/usr/share/gcc-*/python/libstdcxx/
	# TODO: Provide these files in a doc package.
	rm -Rf $(destdir)/usr/share/man/ $(destdir)/usr/share/info/
	# TODO: Provide these files in a gcc-*-plugin-dev package.
	rm -Rf $(destdir)/usr/lib/$(target)/gcc-$(base_version)/plugin/
	oh-fixperms -d "$(destdir)"
	oh-strip -d "$(destdir)"
	OPK_PACKAGES="\
		gcc-$(base_version)-$(target) \
		cpp-$(base_version) \
		g++-$(base_version)-$(target) \
		libgcc.1 \
		libssp.0 \
		libgomp.1 \
		libitm.1 \
		libmudflap.0 \
		libmudflap.0-$(base_version)-dev \
		libstdc++.6 \
		libstdc++.6-$(base_version)-dev \
		gcc-$(base_version)-locales \
		"; \
	export OPK_PACKAGES; \
	oh-installfiles -d "$(destdir)"

$(installcross_targets):
	libsubdir="/usr/lib/$(target)/gcc-$(base_version)" && \
	oh-autoinstall -B "$(builddir)" -d "$(destdir)" -T install-gcc -- \
		gxx_include_dir=/usr/include/c++-4.7 \
		host_installdir=/usr/include/$(target)/c++-4.7/bits \
		libsubdir="$${libsubdir}" \
		libexecsubdir="$${libsubdir}" \
		libsubincludedir="$${libsubdir}/include" \
		fincludedir="$${libsubdir}/finclude" \
		toolexeclibdir="/usr/lib/$(target)" \
		MULTIOSDIR=.
	# Change the target architecture prefix of files in /usr/bin.
	rm -f $(destdir)/usr/bin/*-gcc-$(base_version).*
	for f in c++ g++ gcc gcc-ar gcc-nm gcc-ranlib; do \
		rm -f $(destdir)/usr/bin/$${f}-$(base_version); \
		mv $(destdir)/usr/bin/*-$${f}-$(base_version) \
			$(destdir)/usr/bin/$(target)-$$(printf '%s' \
				$(destdir)/usr/bin/*-$${f}-$(base_version) | \
				sed "s/^.*-\($${f}\)/\1/"); \
	done
	libdir=/usr/lib/$(target) && \
	rm -Rf \
		$(destdir)$${libdir}/gcc-$(base_version)/liblto_plugin.la \
		$(destdir)$${libdir}/gcc-$(base_version)/install-tools \
		$(destdir)$${libdir}/gcc-$(base_version)/plugin \
		$(destdir)/usr/share/locale \
		$(destdir)/usr/share/man \
		$(destdir)/usr/share/info
	oh-fixperms -d "$(destdir)"
	oh-strip -d "$(destdir)"
	OPK_PACKAGES="\
		gcc-$(base_version)-$(target) \
		g++-$(base_version)-$(target) \
		"; \
	export OPK_PACKAGES; \
	oh-installfiles -d "$(destdir)"

install: $(install_targets)