#!/bin/sh
#
# This file is part of the coreboot project.
#
# Copyright (C) 2007-2010 coresystems GmbH
#
# 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; version 2 of the License.
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
#

testcc()
{
	echo "_start(void) {}" > .$$$$.c
	$1 -nostdlib -Werror $2 .$$$$.c -o .$$$$.tmp 2>/dev/null >/dev/null
	ret=$?
	rm -f .$$$$.c .$$$$.tmp
	return $ret
}

for make in make gmake gnumake; do
	if [ "`$make --version 2>/dev/null | grep -c GNU`" -gt 0 ]; then
		MAKE=$make
		break
	fi
done

GCCPREFIX=invalid
XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}
echo '# XGCCPATH='${XGCCPATH}
TMPFILE=`mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz`
touch $TMPFILE

# This loops over all supported architectures in TARCH
TARCH=('i386' 'x86_64')
TWIDTH=32
for search_for in "${TARCH[@]}"; do
	TARCH_SEARCH=("${TARCH_SEARCH[@]}" ${XGCCPATH}${search_for}-elf- ${search_for}-elf-)
done
echo '# TARCH_SEARCH='${TARCH_SEARCH[@]}

for gccprefixes in "${TARCH_SEARCH[@]}" ""; do
	if ! which ${gccprefixes}as 2>/dev/null >/dev/null; then
		continue
	fi
	rm -f ${TMPFILE}.o
	if ${gccprefixes}as -o ${TMPFILE}.o ${TMPFILE}; then
		TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o`
		if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then
			GCCPREFIX=$gccprefixes
			ASFLAGS=
			CFLAGS=
			LDFLAGS=
			break
		fi
	fi
	if ${gccprefixes}as --32 -o ${TMPFILE}.o ${TMPFILE}; then
		TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o`
		if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then
			GCCPREFIX=$gccprefixes
			ASFLAGS=--32
			CFLAGS="-m32 -Wl,-b,elf32-i386 -Wl,-melf_i386 "
			LDFLAGS="-b elf32-i386 -melf_i386"
			break
		fi
	fi
done
rm -f $TMPFILE ${TMPFILE}.o

if [ "$GCCPREFIX" = "invalid" ]; then
	echo '$(error no suitable gcc found)'
	exit 1
fi

CC="${GCCPREFIX}gcc"
testcc "$CC" "$CFLAGS-Wa,--divide " && CFLAGS="$CFLAGS-Wa,--divide "
testcc "$CC" "$CFLAGS-fno-stack-protector " && CFLAGS="$CFLAGS-fno-stack-protector "
testcc "$CC" "$CFLAGS-Wl,--build-id=none " && CFLAGS="$CFLAGS-Wl,--build-id=none "
# GCC 4.6 is much more picky about unused variables. Turn off it's warnings for
# now:
testcc "$CC" "$CFLAGS-Wno-unused-but-set-variable " && \
	       CFLAGS="$CFLAGS-Wno-unused-but-set-variable "

if which gcc 2>/dev/null >/dev/null; then
	HOSTCC=gcc
else
	HOSTCC=cc
fi

if [ "`${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI`" -gt 0 ]; then
	IASL=${XGCCPATH}iasl
else
	IASL=iasl
fi

cat << EOF
# elf${TWIDTH}-${TARCH} toolchain
AS:=${GCCPREFIX}as ${ASFLAGS}
CC:=${GCCPREFIX}gcc ${CFLAGS}
AR:=${GCCPREFIX}ar
LD:=${GCCPREFIX}ld ${LDFLAGS}
STRIP:=${GCCPREFIX}strip
NM:=${GCCPREFIX}nm
OBJCOPY:=${GCCPREFIX}objcopy
OBJDUMP:=${GCCPREFIX}objdump

IASL:=${IASL}

# native toolchain
HOSTCC:=${HOSTCC}
EOF

