#!/bin/bash # # 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="" XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"} die() { echo "ERROR: $*" >&2 exit 1 } clean_up() { if [ -n "$TMPFILE" ]; then rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o" fi } # Create temporary file(s). TMPFILE="$(mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz)" touch "$TMPFILE" trap clean_up EXIT program_exists() { type "$1" >/dev/null 2>&1 } if [ "$(${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then IASL=${XGCCPATH}iasl elif [ "$(iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then IASL=iasl else die "no iasl found" fi if program_exists gcc; then HOSTCC=gcc elif program_exists cc; then HOSTCC=cc else die "no host compiler found" fi cat <"$tmp_c" "$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1 } testas() { local gccprefix="$1" local twidth="$2" local arch="$3" local use_dash_twidth="$4" local endian="$5" local obj_file="$TMPFILE.o" local full_arch="elf$twidth-$arch" rm -f "$obj_file" [ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth" [ -n "$endian" ] && endian="-$endian" ${gccprefix}as $use_dash_twidth $endian -o "$obj_file" $TMPFILE \ 2>/dev/null || return 1 # Check output content type. local obj_type="$(${gccprefix}objdump -p $obj_file)" local obj_arch="$(expr "$obj_type" : '.*format \(.[a-z0-9-]*\)')" [ "$obj_arch" = "$full_arch" ] || return 1 # Architecture matched. GCCPREFIX="$gccprefix" 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 -fno-stack-protector"&& CFLAGS="$CFLAGS -fno-stack-protector" testcc "$CC" "$CFLAGS -Wl,--build-id=none" && CFLAGS="$CFLAGS -Wl,--build-id=none" case "$architecture" in x86) testcc "$CC" "$CFLAGS -Wa,--divide" && CFLAGS="$CFLAGS -Wa,--divide" # Always build for i686 -- no sse/mmx instructions since SMM # modules are compiled using these flags. Note that this # doesn't prevent a project using xcompile to explicitly # specify -mmsse, etc flags. CFLAGS="$CFLAGS -march=i686" ;; mipsel) testcc "$CC" "$CFLAGS -mno-abicalls -fno-pic" && \ CFLAGS+=" -mno-abicalls -fno-pic" # Enforce little endian mode. testcc "$CC" "$CFLAGS -EL" && \ CFLAGS+=" -EL" ;; esac } report_arch_toolchain() { cat < /dev/null; then arch_config_$architecture else die "no architecture definition for $architecture" fi # 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-$TABI-" search="$search $toolchain-$TABI-" search="$search $toolchain-linux-gnu-" search="$search $toolchain-" done echo "# $architecture TARCH_SEARCH=$search" # Search toolchain by checking assembler capability. for TBFDARCH in $TBFDARCHS; do for gccprefix in $search ""; do program_exists "${gccprefix}as" || continue for endian in $TENDIAN ""; do testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \ "" "$endian" && return 0 testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \ "TRUE" "$endian" && return 0 done done done echo "Warning: no suitable GCC for $architecture." >&2 return 1 } # This loops over all supported architectures. for architecture in $SUPPORTED_ARCHITECTURES; do if test_architecture $architecture; then CC="${GCCPREFIX}"gcc detect_special_flags "$architecture" report_arch_toolchain fi done