libpayload: update xcompile script

Copy from coreboot. at some point it probably should just reuse coreboot's
version.

Change-Id: Iee905a9060983ff85e2e70bde69a221c64a07cbc
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Reviewed-on: http://review.coreboot.org/10756
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Patrick Georgi 2015-07-01 20:53:00 +02:00 committed by Patrick Georgi
parent 417f16bc75
commit 885ec48b95
1 changed files with 210 additions and 107 deletions

View File

@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# This file is part of the coreboot project.
#
@ -20,6 +20,7 @@
#
TMPFILE=""
XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}
die() {
echo "ERROR: $*" >&2
@ -32,46 +33,78 @@ clean_up() {
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 <<EOF
# platform agnostic and host tools
IASL:=${IASL}
HOSTCC?=${HOSTCC}
EOF
testcc() {
local tmp_c="$TMPFILE.c"
local tmp_o="$TMPFILE.o"
rm -f "$tmp_c" "$tmp_o"
echo "_start(void) {}" >"$tmp_c"
"$1" -nostdinc -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
echo "void _start(void) {}" >"$tmp_c"
"$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
}
testas() {
local gccprefixes="$1"
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"
${gccprefixes}as $use_dash_twidth -o "$obj_file" $TMPFILE 2>/dev/null ||
return 1
[ -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="$(${gccprefixes}objdump -p $obj_file)"
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="$gccprefixes"
GCCPREFIX="$gccprefix"
if [ -z "$use_dash_twidth" ]; then
ASFLAGS=""
CFLAGS=""
LDFLAGS=""
else
unset ASFLAGS LDFLAGS
unset CFLAGS_GCC CFLAGS_CLANG
if [ -n "$use_dash_twidth" ]; then
ASFLAGS="--$twidth"
CFLAGS="-m$twidth"
CFLAGS_GCC="-m$twidth"
CFLAGS_CLANG="-m$twidth"
LDFLAGS="-b $full_arch"
fi
@ -80,7 +113,8 @@ testas() {
[ -n "$use_dash_twidth" ] && case "$full_arch" in
"elf32-i386" )
LDFLAGS="$LDFLAGS -melf_i386"
CFLAGS="$CFLAGS -Wl,-b,elf32-i386 -Wl,-melf_i386"
CFLAGS_GCC="$CFLAGS_GCC -Wl,-b,elf32-i386 -Wl,-melf_i386"
CFLAGS_CLANG="$CFLAGS_GCC -Wl,-b,elf32-i386 -Wl,-melf_i386"
;;
esac
@ -91,94 +125,160 @@ 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 "
testcc "$GCC" "$CFLAGS_GCC -Wno-unused-but-set-variable " &&
CFLAGS_GCC="$CFLAGS_GCC -Wno-unused-but-set-variable "
# Check for an operational -m32/-m64
testcc "$GCC" "$CFLAGS_GCC -m$TWIDTH " &&
CFLAGS_GCC="$CFLAGS_GCC -m$TWIDTH "
# Use bfd linker instead of gold if available:
testcc "$CC" "$CFLAGS -fuse-ld=bfd" &&
CFLAGS="$CFLAGS -fuse-ld=bfd" && LINKER_SUFFIX='.bfd'
testcc "$GCC" "$CFLAGS_GCC -fuse-ld=bfd" &&
CFLAGS_GCC="$CFLAGS_GCC -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"
testcc "$GCC" "$CFLAGS_GCC -fno-stack-protector"&&
CFLAGS_GCC="$CFLAGS_GCC -fno-stack-protector"
testcc "$GCC" "$CFLAGS_GCC -Wl,--build-id=none" &&
CFLAGS_GCC="$CFLAGS_GCC -Wl,--build-id=none"
case "$architecture" in
arm )
# testcc "$CC" "$CFLAGS -mcpu=cortex-a9" &&
# CFLAGS="$CFLAGS -mcpu=cortex-a9"
;;
x86)
testcc "$GCC" "$CFLAGS_GCC -Wa,--divide" &&
CFLAGS_GCC="$CFLAGS_GCC -Wa,--divide"
testcc "$CLANG" "$CFLAGS_CLANG -Wa,--divide" &&
CFLAGS_CLANG="$CFLAGS_CLANG -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_GCC="$CFLAGS_GCC -march=i686"
;;
x64)
testcc "$GCC" "$CFLAGS_GCC -Wa,--divide" &&
CFLAGS_GCC="$CFLAGS_GCC -Wa,--divide"
testcc "$CLANG" "$CFLAGS_CLANG -Wa,--divide" &&
CFLAGS_CLANG="$CFLAGS_CLANG -Wa,--divide"
;;
mipsel)
testcc "$GCC" "$CFLAGS_GCC -mno-abicalls -fno-pic" && \
CFLAGS_GCC+=" -mno-abicalls -fno-pic"
arm64-generic )
;;
mips )
testcc "$CC" "CFLAGS -mxgot" &&
CFLAGS="$CFLAGS -mxgot"
;;
# Enforce little endian mode.
testcc "$GCC" "$CFLAGS_GCC -EL" && \
CFLAGS_GCC+=" -EL"
;;
esac
}
detect_compiler_runtime() {
test -z "$CLANG" || \
CC_RT_CLANG="`${CLANG} ${CFLAGS} -print-librt-file-name 2>/dev/null`"
test -z "$GCC" || \
CC_RT_GCC="`${GCC} ${CFLAGS} -print-libgcc-file-name`"
}
report_arch_toolchain() {
cat <<EOF
# elf${TWIDTH}-${TBFDARCH} toolchain (${GCCPREFIX}gcc)
CC_${TARCH}:=${GCCPREFIX}gcc ${CFLAGS}
# elf${TWIDTH}-${TBFDARCH} toolchain (${GCC})
ARCH_SUPPORTED+=${TARCH}
SUBARCH_SUPPORTED+=${TSUPP-${TARCH}}
ifeq (\$(CONFIG_COMPILER_GCC),y)
CC_${TARCH}:=${GCC}
CFLAGS_${TARCH}:=${CFLAGS_GCC}
COMPILER_RT_${TARCH}:=${CC_RT_GCC}
COMPILER_RT_FLAGS_${TARCH}:=${CC_RT_EXTRA_GCC}
else
CC_${TARCH}:=${CLANG}
CFLAGS_${TARCH}:=${CFLAGS_CLANG}
CFLAGS_${TARCH}+=-no-integrated-as -Qunused-arguments -m${TWIDTH}
# tone down compiler warnings
CFLAGS_${TARCH}+=-Wno-unused-variable -Wno-unused-function -Wno-tautological-compare -Wno-shift-overflow
COMPILER_RT_${TARCH}:=${CC_RT_CLANG}
COMPILER_RT_FLAGS_${TARCH}:=${CC_RT_EXTRA_CLANG}
endif
CPP_${TARCH}:=${GCCPREFIX}cpp
AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
LD_${TARCH}:=${GCCPREFIX}ld ${LDFLAGS}
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
CROSS_COMPILE_${TARCH}:=${GCCPREFIX}
EOF
}
# Create temporary file(s).
TMPFILE="$(mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz)"
touch "$TMPFILE"
trap clean_up EXIT
# Architecture definitions
SUPPORTED_ARCHITECTURES="arm arm64 mipsel riscv x64 x86"
# Architecture definition
SUPPORTED_ARCHITECTURE="arm arm64 mipsel x86"
arch_config_arm() {
TARCH="arm"
TBFDARCHS="littlearm"
TCLIST="armv7a armv7-a"
TWIDTH="32"
TSUPP="arm armv4 armv7 armv7_m"
TABI="eabi"
}
# ARM Architecture
TARCH_arm="arm"
TBFDARCH_arm="littlearm"
TCLIST_arm="armv7a armv7-a"
TWIDTH_arm="32"
arch_config_arm64() {
TARCH="arm64"
TBFDARCHS="littleaarch64"
TCLIST="aarch64"
TWIDTH="64"
TSUPP="arm64 armv8_64"
TABI="elf"
}
# ARM64 Architecture
TARCH_arm64="arm64"
TBFDARCH_arm64="littleaarch64"
TCLIST_arm64="aarch64"
TWIDTH_arm64="64"
arch_config_riscv() {
TARCH="riscv"
TBFDARCHS="littleriscv"
TCLIST="riscv"
TWIDTH="64"
TABI="elf"
}
# MIPS Architecture (Little Endian)
TARCH_mipsel="mipsel"
TBFDARCH_mipsel="tradlittlemips littlemips"
TCLIST_mipsel="mipsel"
TWIDTH_mipsel="32"
arch_config_x64() {
TARCH="x86_64"
TBFDARCHS="x86-64"
TCLIST="x86_64"
TWIDTH="64"
TABI="elf"
}
# X86 Architecture
TARCH_x86="i386"
TBFDARCH_x86="i386"
TCLIST_x86="i386 x86_64"
TWIDTH_x86="32"
arch_config_x86() {
TARCH="x86_32"
TBFDARCHS="i386"
TCLIST="i386 x86_64"
TWIDTH="32"
TABI="elf"
CC_RT_EXTRA_GCC="--wrap __divdi3 --wrap __udivdi3 --wrap __moddi3 --wrap __umoddi3"
}
XGCCPATH=${1:-"`pwd`/../../util/crossgcc/xgcc/bin/"}
arch_config_mipsel() {
TARCH="mips"
TBFDARCHS="tradlittlemips littlemips"
TCLIST="mipsel"
TWIDTH="32"
TSUPP="mips mipsel"
TABI="elf"
TENDIAN="EL"
}
test_architecture() {
local architecture=$1
local endian gccprefix search
# This loops over all supported architectures.
for architecture in $SUPPORTED_ARCHITECTURE; do
GCCPREFIX="invalid"
TARCH="$(eval echo \$TARCH_$architecture)"
TBFDARCHS="$(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."
unset TABI TARCH TBFDARCH TCLIST TENDIAN TSUPP TWIDTH
unset CC_RT_EXTRA_GCC CC_RT_EXTRA_CLANG
unset GCC CLANG
if type arch_config_$architecture > /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.
@ -187,48 +287,51 @@ for architecture in $SUPPORTED_ARCHITECTURE; do
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-"
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 gccprefixes in $search ""; do
program_exists "${gccprefixes}as" || continue
testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "" && break
testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "TRUE" && break
for gccprefix in $search ""; do
program_exists "${gccprefix}as" || continue
for endian in $TENDIAN ""; do
testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \
"" "$endian" && break 3
testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \
"TRUE" "$endian" && break 3
done
done
[ "$GCCPREFIX" = "invalid" ] || break
done
if [ "invalid" != "$GCCPREFIX" ]; then
GCC="${GCCPREFIX}gcc"
fi
for clang_arch in $TCLIST invalid; do
testcc "clang" "-target ${clang_arch}-$TABI -c" && break
done
if [ "$GCCPREFIX" = "invalid" ]; then
echo "Warning: no suitable GCC for $architecture." >&2
continue
if [ "invalid" != "$clang_arch" ]; then
# FIXME: this may break in a clang && !gcc configuration,
# but that's more of a clang limitation. Let's be optimistic
# that this will change in the future.
CLANG="clang -target ${clang_arch}-${TABI} -ccc-gcc-name ${GCC}"
fi
CC="${GCCPREFIX}"gcc
detect_special_flags "$architecture"
report_arch_toolchain
if [ -z "$GCC" -a -z "$CLANG" ]; then
echo "Warning: no suitable compiler for $architecture." >&2
return 1
fi
}
# This loops over all supported architectures.
for architecture in $SUPPORTED_ARCHITECTURES; do
if test_architecture $architecture; then
detect_special_flags "$architecture"
detect_compiler_runtime "$architecture"
report_arch_toolchain
fi
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