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

View File

@ -1,4 +1,4 @@
#!/bin/sh #!/bin/bash
# #
# This file is part of the coreboot project. # This file is part of the coreboot project.
# #
@ -20,6 +20,7 @@
# #
TMPFILE="" TMPFILE=""
XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}
die() { die() {
echo "ERROR: $*" >&2 echo "ERROR: $*" >&2
@ -32,46 +33,78 @@ clean_up() {
fi 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() { program_exists() {
type "$1" >/dev/null 2>&1 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() { testcc() {
local tmp_c="$TMPFILE.c" local tmp_c="$TMPFILE.c"
local tmp_o="$TMPFILE.o" local tmp_o="$TMPFILE.o"
rm -f "$tmp_c" "$tmp_o" rm -f "$tmp_c" "$tmp_o"
echo "_start(void) {}" >"$tmp_c" echo "void _start(void) {}" >"$tmp_c"
"$1" -nostdinc -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1 "$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
} }
testas() { testas() {
local gccprefixes="$1" local gccprefix="$1"
local twidth="$2" local twidth="$2"
local arch="$3" local arch="$3"
local use_dash_twidth="$4" local use_dash_twidth="$4"
local endian="$5"
local obj_file="$TMPFILE.o" local obj_file="$TMPFILE.o"
local full_arch="elf$twidth-$arch" local full_arch="elf$twidth-$arch"
rm -f "$obj_file" rm -f "$obj_file"
[ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth" [ -n "$use_dash_twidth" ] && use_dash_twidth="--$twidth"
${gccprefixes}as $use_dash_twidth -o "$obj_file" $TMPFILE 2>/dev/null || [ -n "$endian" ] && endian="-$endian"
return 1 ${gccprefix}as $use_dash_twidth $endian -o "$obj_file" $TMPFILE \
2>/dev/null || return 1
# Check output content type. # 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-]*\)')" local obj_arch="$(expr "$obj_type" : '.*format \(.[a-z0-9-]*\)')"
[ "$obj_arch" = "$full_arch" ] || return 1 [ "$obj_arch" = "$full_arch" ] || return 1
# Architecture matched. # Architecture matched.
GCCPREFIX="$gccprefixes" GCCPREFIX="$gccprefix"
if [ -z "$use_dash_twidth" ]; then unset ASFLAGS LDFLAGS
ASFLAGS="" unset CFLAGS_GCC CFLAGS_CLANG
CFLAGS=""
LDFLAGS="" if [ -n "$use_dash_twidth" ]; then
else
ASFLAGS="--$twidth" ASFLAGS="--$twidth"
CFLAGS="-m$twidth" CFLAGS_GCC="-m$twidth"
CFLAGS_CLANG="-m$twidth"
LDFLAGS="-b $full_arch" LDFLAGS="-b $full_arch"
fi fi
@ -80,7 +113,8 @@ testas() {
[ -n "$use_dash_twidth" ] && case "$full_arch" in [ -n "$use_dash_twidth" ] && case "$full_arch" in
"elf32-i386" ) "elf32-i386" )
LDFLAGS="$LDFLAGS -melf_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 esac
@ -91,94 +125,160 @@ detect_special_flags() {
local architecture="$1" local architecture="$1"
# GCC 4.6 is much more picky about unused variables. # GCC 4.6 is much more picky about unused variables.
# Turn off it's warnings for now: # Turn off it's warnings for now:
testcc "$CC" "$CFLAGS -Wno-unused-but-set-variable " && testcc "$GCC" "$CFLAGS_GCC -Wno-unused-but-set-variable " &&
CFLAGS="$CFLAGS -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: # Use bfd linker instead of gold if available:
testcc "$CC" "$CFLAGS -fuse-ld=bfd" && testcc "$GCC" "$CFLAGS_GCC -fuse-ld=bfd" &&
CFLAGS="$CFLAGS -fuse-ld=bfd" && LINKER_SUFFIX='.bfd' CFLAGS_GCC="$CFLAGS_GCC -fuse-ld=bfd" && LINKER_SUFFIX='.bfd'
testcc "$CC" "$CFLAGS -Wa,--divide" && testcc "$GCC" "$CFLAGS_GCC -fno-stack-protector"&&
CFLAGS="$CFLAGS -Wa,--divide" CFLAGS_GCC="$CFLAGS_GCC -fno-stack-protector"
testcc "$CC" "$CFLAGS -fno-stack-protector"&& testcc "$GCC" "$CFLAGS_GCC -Wl,--build-id=none" &&
CFLAGS="$CFLAGS -fno-stack-protector" CFLAGS_GCC="$CFLAGS_GCC -Wl,--build-id=none"
testcc "$CC" "$CFLAGS -Wl,--build-id=none" &&
CFLAGS="$CFLAGS -Wl,--build-id=none"
case "$architecture" in case "$architecture" in
arm ) x86)
# testcc "$CC" "$CFLAGS -mcpu=cortex-a9" && testcc "$GCC" "$CFLAGS_GCC -Wa,--divide" &&
# CFLAGS="$CFLAGS -mcpu=cortex-a9" 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 ) # Enforce little endian mode.
;; testcc "$GCC" "$CFLAGS_GCC -EL" && \
mips ) CFLAGS_GCC+=" -EL"
testcc "$CC" "CFLAGS -mxgot" && ;;
CFLAGS="$CFLAGS -mxgot"
;;
esac 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() { report_arch_toolchain() {
cat <<EOF cat <<EOF
# elf${TWIDTH}-${TBFDARCH} toolchain (${GCCPREFIX}gcc) # elf${TWIDTH}-${TBFDARCH} toolchain (${GCC})
CC_${TARCH}:=${GCCPREFIX}gcc ${CFLAGS} 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} AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
LD_${TARCH}:=${GCCPREFIX}ld ${LDFLAGS} LD_${TARCH}:=${GCCPREFIX}ld${LINKER_SUFFIX} ${LDFLAGS}
NM_${TARCH}:=${GCCPREFIX}nm NM_${TARCH}:=${GCCPREFIX}nm
OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy OBJCOPY_${TARCH}:=${GCCPREFIX}objcopy
OBJDUMP_${TARCH}:=${GCCPREFIX}objdump OBJDUMP_${TARCH}:=${GCCPREFIX}objdump
READELF_${TARCH}:=${GCCPREFIX}readelf READELF_${TARCH}:=${GCCPREFIX}readelf
STRIP_${TARCH}:=${GCCPREFIX}strip STRIP_${TARCH}:=${GCCPREFIX}strip
AR_${TARCH}:=${GCCPREFIX}ar AR_${TARCH}:=${GCCPREFIX}ar
CROSS_COMPILE_${TARCH}:=${GCCPREFIX}
EOF EOF
} }
# Create temporary file(s). # Architecture definitions
TMPFILE="$(mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz)" SUPPORTED_ARCHITECTURES="arm arm64 mipsel riscv x64 x86"
touch "$TMPFILE"
trap clean_up EXIT
# Architecture definition arch_config_arm() {
SUPPORTED_ARCHITECTURE="arm arm64 mipsel x86" TARCH="arm"
TBFDARCHS="littlearm"
TCLIST="armv7a armv7-a"
TWIDTH="32"
TSUPP="arm armv4 armv7 armv7_m"
TABI="eabi"
}
# ARM Architecture arch_config_arm64() {
TARCH_arm="arm" TARCH="arm64"
TBFDARCH_arm="littlearm" TBFDARCHS="littleaarch64"
TCLIST_arm="armv7a armv7-a" TCLIST="aarch64"
TWIDTH_arm="32" TWIDTH="64"
TSUPP="arm64 armv8_64"
TABI="elf"
}
# ARM64 Architecture arch_config_riscv() {
TARCH_arm64="arm64" TARCH="riscv"
TBFDARCH_arm64="littleaarch64" TBFDARCHS="littleriscv"
TCLIST_arm64="aarch64" TCLIST="riscv"
TWIDTH_arm64="64" TWIDTH="64"
TABI="elf"
}
# MIPS Architecture (Little Endian) arch_config_x64() {
TARCH_mipsel="mipsel" TARCH="x86_64"
TBFDARCH_mipsel="tradlittlemips littlemips" TBFDARCHS="x86-64"
TCLIST_mipsel="mipsel" TCLIST="x86_64"
TWIDTH_mipsel="32" TWIDTH="64"
TABI="elf"
}
# X86 Architecture arch_config_x86() {
TARCH_x86="i386" TARCH="x86_32"
TBFDARCH_x86="i386" TBFDARCHS="i386"
TCLIST_x86="i386 x86_64" TCLIST="i386 x86_64"
TWIDTH_x86="32" 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" GCCPREFIX="invalid"
TARCH="$(eval echo \$TARCH_$architecture)" unset TABI TARCH TBFDARCH TCLIST TENDIAN TSUPP TWIDTH
TBFDARCHS="$(eval echo \$TBFDARCH_$architecture)" unset CC_RT_EXTRA_GCC CC_RT_EXTRA_CLANG
TCLIST="$(eval echo \$TCLIST_$architecture)" unset GCC CLANG
TWIDTH="$(eval echo \$TWIDTH_$architecture)" if type arch_config_$architecture > /dev/null; then
[ -z "$TARCH" -o -z "$TCLIST" -o -z "$TWIDTH" ] && arch_config_$architecture
die "Missing architecture definition for $architecture." else
die "no architecture definition for $architecture"
fi
# To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as # To override toolchain, define CROSS_COMPILE_$arch or CROSS_COMPILE as
# environment variable. # environment variable.
@ -187,48 +287,51 @@ for architecture in $SUPPORTED_ARCHITECTURE; do
search="$(eval echo \$CROSS_COMPILE_$architecture 2>/dev/null)" search="$(eval echo \$CROSS_COMPILE_$architecture 2>/dev/null)"
search="$search $CROSS_COMPILE" search="$search $CROSS_COMPILE"
for toolchain in $TCLIST; do for toolchain in $TCLIST; do
search="$search $XGCCPATH$toolchain-elf-" search="$search $XGCCPATH$toolchain-$TABI-"
search="$search $toolchain-elf-" search="$search $toolchain-$TABI-"
search="$search $XGCCPATH$toolchain-eabi-" search="$search $toolchain-linux-gnu-"
search="$search $toolchain-eabi-" search="$search $toolchain-"
done done
echo "# $architecture TARCH_SEARCH=$search" echo "# $architecture TARCH_SEARCH=$search"
# Search toolchain by checking assembler capability. # Search toolchain by checking assembler capability.
for TBFDARCH in $TBFDARCHS; do for TBFDARCH in $TBFDARCHS; do
for gccprefixes in $search ""; do for gccprefix in $search ""; do
program_exists "${gccprefixes}as" || continue program_exists "${gccprefix}as" || continue
testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "" && break for endian in $TENDIAN ""; do
testas "$gccprefixes" "$TWIDTH" "$TBFDARCH" "TRUE" && break testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \
"" "$endian" && break 3
testas "$gccprefix" "$TWIDTH" "$TBFDARCH" \
"TRUE" "$endian" && break 3
done
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 done
if [ "$GCCPREFIX" = "invalid" ]; then if [ "invalid" != "$clang_arch" ]; then
echo "Warning: no suitable GCC for $architecture." >&2 # FIXME: this may break in a clang && !gcc configuration,
continue # 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 fi
CC="${GCCPREFIX}"gcc
detect_special_flags "$architecture" if [ -z "$GCC" -a -z "$CLANG" ]; then
report_arch_toolchain 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 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