#! /bin/bash

# URLs and versions
if [ -z "${GLIBC_VERS}" ]; then
	GLIBC_VERS='2.22'
	GLIBC_TARBALL_SHA256="a62610c4084a0fd8cec58eee12ef9e61fdf809c31e7cecbbc28feb8719f08be5"
fi
GLIBC_URL="http://ftp.gnu.org/gnu/glibc/glibc-${GLIBC_VERS}.tar.gz"
GLIBC_TARBALL="src/glibc-${GLIBC_VERS}.tar.gz"
GLIBC_DIR="glibc-${GLIBC_VERS}"

if [ -z "${GLIBC_PORTS_VERS}" ]; then
	GLIBC_PORTS_VERS='2.16.0'
	GLIBC_PORTS_TARBALL_SHA256="1092e81d0c9c1bc29343004c1d01fb0d89eb49dd0fd5339b2f2e64a44b582d10"
fi
GLIBC_PORTS_URL="http://ftp.gnu.org/gnu/glibc/glibc-ports-${GLIBC_PORTS_VERS}.tar.gz"
GLIBC_PORTS_TARBALL="src/glibc-ports-${GLIBC_PORTS_VERS}.tar.gz"
GLIBC_PORTS_DIR="$(pwd)/glibc-ports-${GLIBC_PORTS_VERS}"

# Main script
CCNAME="$1"
CCDIR="$2"
PREFIX="$3"
STAGE="$4"

# Clean
if [ "$1" = "distclean" ]; then
	rm -f "${GLIBC_TARBALL}"

	set -- clean
fi

if [ "$1" = "clean" ]; then
	rm -rf "${GLIBC_DIR}"
	rm -rf "${GLIBC_PORTS_DIR}"
	rm -rf glibc-*-*-*

	exit 0
fi

# Only build glibc for linux-gnu platforms
if ! echo "${CCNAME}" | grep -- '-unknown-linux-gnu' >/dev/null; then
	if ! echo "${CCNAME}" | grep -- '-generic-linux-gnu' >/dev/null; then
		exit 0
	fi
fi

# Determine additional addons
case "${GLIBC_VERS}" in
	2.0|2.1|2.2|2.3|2.4|2.5|2.6|2.7|2.8|2.9|2.10|2.11|2.12|2.13|2.14|2.15|2.16|2.17|2.18|2.19|2.0.*|2.1.*|2.2.*|2.3.*|2.4.*|2.5.*|2.6.*|2.7.*|2.8.*|2.9.*|2.10.*|2.11.*|2.12.*|2.13.*|2.14.*|2.15.*|2.16.*|2.17.*|2.18.*|2.19.*)
		GLIBC_ADDITIONAL_ADDONS="${GLIBC_ADDITIONAL_ADDONS},nptl"
		;;
esac


# Download source
. 'scripts/common'

if [ ! -d "${GLIBC_DIR}" ]; then
	download "${GLIBC_URL}" "${GLIBC_TARBALL}" "${GLIBC_TARBALL_SHA256}" || exit 1

	gzip -dc "${GLIBC_TARBALL}" | tar -xf -
fi

if [ ! -d "${GLIBC_PORTS_DIR}" ]; then
	download "${GLIBC_PORTS_URL}" "${GLIBC_PORTS_TARBALL}" "${GLIBC_PORTS_TARBALL_SHA256}" || exit 1

	gzip -dc "${GLIBC_PORTS_TARBALL}" | tar -xf -
fi

# Ensure that a stdio.h exists, even if it is blank for autoconf scripts
touch "${PREFIX}/include/stdio.h"

CC_SAVE="${CC}"
rebuild_binutils_needed='0'
for arch in $(multilib); do
	CC="${CC_SAVE} $(multilib --cflags "${arch}")"
	arch_host="$(multilib --host "${arch}")"
	arch_libdir="$(multilib --libdir --noprefix "${arch}")"

	if [ -e "${PREFIX}/${arch_libdir}/glibc-${GLIBC_VERS}-completed-${STAGE}" ]; then
		continue
	fi

	# Inform the user of what we are doing
	echo " * Building GNU C Library (glibc version ${GLIBC_VERS}) for ${arch_host}"

	rm -rf "glibc-${CCNAME}-${arch_host}"
	mkdir "glibc-${CCNAME}-${arch_host}"
	cd "glibc-${CCNAME}-${arch_host}" || exit 1

	echo "slibdir = ${arch_libdir}" > configparms

	case "${STAGE}" in
		stage1)
			"../${GLIBC_DIR}/configure" --prefix='/' --libdir="${arch_libdir}" --host="${arch_host}" \
				--disable-profile --without-gd --without-cvs --without-selinux --enable-add-ons="${GLIBC_PORTS_DIR}${GLIBC_ADDITIONAL_ADDONS}" --with-tls \
				libc_cv_forced_unwind=yes libc_cv_ctors_header=yes libc_cv_c_cleanup=yes libc_cv_ssp=no || exit 1
			echo '#define HAVE_TLS_SUPPORT 1' >> config.h

			${MAKE} ${BUILD_CC_MAKE_FLAGS} || exit 1

			${MAKE} ${BUILD_CC_MAKE_FLAGS} install_root="${PREFIX}" install || exit 1

			cd ..

			rm -rf "glibc-${CCNAME}-${arch_host}"
			mkdir "glibc-${CCNAME}-${arch_host}"
			cd "glibc-${CCNAME}-${arch_host}" || exit 1

			echo "slibdir = ${arch_libdir}" > configparms

			"../${GLIBC_DIR}/configure" --prefix='/' --libdir="${arch_libdir}" --host="${arch_host}" --enable-add-ons="${GLIBC_PORTS_DIR},libidn${GLIBC_ADDITIONAL_ADDONS}" \
				libc_cv_forced_unwind=yes libc_cv_ctors_header=yes libc_cv_c_cleanup=yes libc_cv_ssp=no || exit 1
			rebuild_binutils_needed='1'
			;;
		stage2)
			"../${GLIBC_DIR}/configure" --prefix='/' --libdir="${arch_libdir}" --host="${arch_host}" --enable-add-ons="${GLIBC_PORTS_DIR},libidn${GLIBC_ADDITIONAL_ADDONS}" \
				--enable-kernel=2.6.35.4 || exit 1
			;;
	esac

	${MAKE} ${BUILD_CC_MAKE_FLAGS} || exit 1

	${MAKE} ${BUILD_CC_MAKE_FLAGS} install_root="${PREFIX}" install || exit 1

	cd ..

	rm -rf "glibc-${CCNAME}-${arch_host}"

	touch "${PREFIX}/${arch_libdir}/glibc-${GLIBC_VERS}-completed-${STAGE}"
done

if [ "${rebuild_binutils_needed}" = '1' ]; then
	# Force rebuilding binutils
	touch "${CCDIR}/bin/${CCNAME}-rebuild-binutils"
fi

exit 0
