In commit e820e5cb3a titled
"Make xcompile support multiple architectures" the LINKER_SUFFIX
variable was introduced to bypass gold if the bfd linker was
available. However, the LINKER_SUFFIX wasn't honored when
the compiler evironment variables were set. Fix the original
intention.
Change-Id: I608f1e0cc3d0bea3ba1e51b167d88c66d266bceb
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/2879
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
		
	
		
			
				
	
	
		
			212 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			212 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| #!/bin/sh
 | |
| #
 | |
| # This file is part of the coreboot project.
 | |
| #
 | |
| # Copyright (C) 2007-2010 coresystems GmbH
 | |
| # Copyright (C) 2012 Google Inc
 | |
| #
 | |
| # 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
 | |
| #
 | |
| 
 | |
| TMPFILE=""
 | |
| 
 | |
| die() {
 | |
| 	echo "ERROR: $*" >&2
 | |
| 	exit 1
 | |
| }
 | |
| 
 | |
| clean_up() {
 | |
| 	if [ -n "$TMPFILE" ]; then
 | |
| 		rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o"
 | |
| 	fi
 | |
| }
 | |
| 
 | |
| program_exists() {
 | |
| 	type "$1" >/dev/null 2>&1
 | |
| }
 | |
| 
 | |
| testcc() {
 | |
| 	local tmp_c="$TMPFILE.c"
 | |
| 	local tmp_o="$TMPFILE.o"
 | |
| 	rm -f "$tmp_c" "$tmp_o"
 | |
| 	echo "void _start(void) {}" >"$tmp_c"
 | |
| 	"$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
 | |
| }
 | |
| 
 | |
| testas() {
 | |
| 	local gccprefixes="$1"
 | |
| 	local twidth="$2"
 | |
| 	local arch="$3"
 | |
| 	local use_dash_twidth="$4"
 | |
| 	local obj_file="$TMPFILE.o"
 | |
| 	local full_arch="elf$twidth-$arch"
 | |
| 
 | |
| 	rm -f "$obj_file"
 | |
| 	[ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth"
 | |
| 	${gccprefixes}as $use_dash_twidth -o "$obj_file" $TMPFILE 2>/dev/null ||
 | |
| 		return 1
 | |
| 
 | |
| 	# Check output content type.
 | |
| 	local obj_type="$(${gccprefixes}objdump -p $obj_file)"
 | |
| 	local obj_arch="$(expr "$obj_type" : '.*format \(.[a-z0-9-]*\)')"
 | |
| 	[ "$obj_arch" = "$full_arch" ] || return 1
 | |
| 
 | |
| 	# Architecture matched.
 | |
| 	GCCPREFIX="$gccprefixes"
 | |
| 
 | |
| 	if [ -z "$use_dash_twidth" ]; then
 | |
| 		ASFLAGS=""
 | |
| 		CFLAGS=""
 | |
| 		LDFLAGS=""
 | |
| 	else
 | |
| 		ASFLAGS="--$twidth"
 | |
| 		CFLAGS="-m$twidth"
 | |
| 		LDFLAGS="-b $full_arch"
 | |
| 
 | |
| 	fi
 | |
| 
 | |
| 	# Special parameters only available in dash_twidth mode.
 | |
| 	[ -n "$use_dash_twidth" ] && case "$full_arch" in
 | |
| 		"elf32-i386" )
 | |
| 			LDFLAGS="$LDFLAGS -melf_i386"
 | |
| 			CFLAGS="$CFLAGS -Wl,-b,elf32-i386 -Wl,-melf_i386"
 | |
| 			;;
 | |
| 	esac
 | |
| 
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| detect_special_flags() {
 | |
| 	local architecture="$1"
 | |
| 	# 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 "
 | |
| 
 | |
| 	# Use bfd linker instead of gold if available:
 | |
| 	testcc "$CC"   "$CFLAGS -fuse-ld=bfd" &&
 | |
| 		CFLAGS="$CFLAGS -fuse-ld=bfd" && LINKER_SUFFIX='.bfd'
 | |
| 
 | |
| 	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"
 | |
| 
 | |
| 	case "$architecture" in
 | |
| 	armv7 )
 | |
| 		ARMFLAGS=""
 | |
| 		testcc "$CC" "$CFLAGS $ARMFLAGS"&&CFLAGS="$CFLAGS $ARMFLAGS"
 | |
| 			;;
 | |
| 	esac
 | |
| }
 | |
| 
 | |
| report_arch_toolchain() {
 | |
| 	cat <<EOF
 | |
| # elf${TWIDTH}-${TBFDARCH} toolchain (${GCCPREFIX}gcc)
 | |
| CC_${TARCH}:=${GCCPREFIX}gcc ${CFLAGS}
 | |
| AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
 | |
| LD_${TARCH}:=${GCCPREFIX}ld${LINKER_SUFFIX} ${LDFLAGS}
 | |
| NM_${TARCH}:=${GCCPREFIX}nm
 | |
| OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy
 | |
| OBJDUMP_${TARCH}:=${GCCPREFIX}objdump
 | |
| READELF_${TARCH}:=${GCCPREFIX}readelf
 | |
| STRIP_${TARCH}:=${GCCPREFIX}strip
 | |
| AR_${TARCH}:=${GCCPREFIX}ar
 | |
| 
 | |
| EOF
 | |
| }
 | |
| 
 | |
| # Create temporary file(s).
 | |
| TMPFILE="$(mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz)"
 | |
| touch "$TMPFILE"
 | |
| trap clean_up EXIT
 | |
| 
 | |
| # Architecture definition
 | |
| SUPPORTED_ARCHITECTURE="x86 armv7"
 | |
| 
 | |
| # ARM Architecture
 | |
| TARCH_armv7="armv7"
 | |
| TBFDARCH_armv7="littlearm"
 | |
| TCLIST_armv7="armv7a"
 | |
| TWIDTH_armv7="32"
 | |
| 
 | |
| # X86 Architecture
 | |
| TARCH_x86="i386"
 | |
| TBFDARCH_x86="i386"
 | |
| TCLIST_x86="i386 x86_64"
 | |
| TWIDTH_x86="32"
 | |
| XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}
 | |
| 
 | |
| # This loops over all supported architectures.
 | |
| for architecture in $SUPPORTED_ARCHITECTURE; do
 | |
| 	GCCPREFIX="invalid"
 | |
| 	TARCH="$(eval echo \$TARCH_$architecture)"
 | |
| 	TBFDARCH="$(eval echo \$TBFDARCH_$architecture)"
 | |
| 	TCLIST="$(eval echo \$TCLIST_$architecture)"
 | |
| 	TWIDTH="$(eval echo \$TWIDTH_$architecture)"
 | |
| 	[ -z "$TARCH" -o -z "$TCLIST" -o -z "$TWIDTH" ] &&
 | |
| 		die "Missing architecture definition for $architecture."
 | |
| 
 | |
| 	# To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as
 | |
| 	# environment variable.
 | |
| 	# Ex: CROSS_COMPILE_arm="armv7a-cros-linux-gnueabi-"
 | |
| 	#     CROSS_COMPILE_x86="i686-pc-linux-gnu-"
 | |
| 	search="$(eval echo \$CROSS_COMPILE_$architecture 2>/dev/null)"
 | |
| 	search="$search $CROSS_COMPILE"
 | |
| 	for toolchain in $TCLIST; do
 | |
| 		search="$search $XGCCPATH$toolchain-elf-"
 | |
| 		search="$search $toolchain-elf-"
 | |
| 		search="$search $XGCCPATH$toolchain-eabi-"
 | |
| 		search="$search $toolchain-eabi-"
 | |
| 	done
 | |
| 	echo "# $architecture TARCH_SEARCH=$search"
 | |
| 
 | |
| 	# Search toolchain by checking assembler capability.
 | |
| 	for gccprefixes in $search ""; do
 | |
| 		program_exists "${gccprefixes}as" || continue
 | |
| 		testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "" && break
 | |
| 		testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "TRUE" && break
 | |
| 	done
 | |
| 
 | |
| 	if [ "$GCCPREFIX" = "invalid" ]; then
 | |
| 		echo "Warning: no suitable GCC for $architecture." >&2
 | |
| 		continue
 | |
| 	fi
 | |
| 	CC="${GCCPREFIX}"gcc
 | |
| 
 | |
| 	detect_special_flags "$architecture"
 | |
| 	report_arch_toolchain
 | |
| done
 | |
| 
 | |
| if [ "$(${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
 | |
| 	IASL=${XGCCPATH}iasl
 | |
| else
 | |
| 	IASL=iasl
 | |
| fi
 | |
| 
 | |
| if program_exists gcc; then
 | |
| 	HOSTCC=gcc
 | |
| else
 | |
| 	HOSTCC=cc
 | |
| fi
 | |
| 
 | |
| cat <<EOF
 | |
| IASL:=${IASL}
 | |
| 
 | |
| # native toolchain
 | |
| HOSTCC:=${HOSTCC}
 | |
| EOF
 |