summaryrefslogtreecommitdiff
path: root/payloads/libpayload/util/xcompile
diff options
context:
space:
mode:
authorPatrick Georgi <pgeorgi@chromium.org>2015-07-01 20:53:00 +0200
committerPatrick Georgi <pgeorgi@google.com>2015-07-03 09:38:18 +0200
commit885ec48b953e29014b405e4e3f4a6df64fbd1d43 (patch)
tree38e543394b9f29ceb38d23dac6d6acfde654eab3 /payloads/libpayload/util/xcompile
parent417f16bc750761997905989be5b812f3d71b27e2 (diff)
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>
Diffstat (limited to 'payloads/libpayload/util/xcompile')
-rw-r--r--payloads/libpayload/util/xcompile/xcompile317
1 files changed, 210 insertions, 107 deletions
diff --git a/payloads/libpayload/util/xcompile/xcompile b/payloads/libpayload/util/xcompile/xcompile
index 859688cc4d..1af02ad28a 100644
--- a/payloads/libpayload/util/xcompile/xcompile
+++ b/payloads/libpayload/util/xcompile/xcompile
@@ -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"
- ;;
-
- arm64-generic )
- ;;
- mips )
- testcc "$CC" "CFLAGS -mxgot" &&
- CFLAGS="$CFLAGS -mxgot"
- ;;
+ 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"
+
+ # 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 [ "$GCCPREFIX" = "invalid" ]; then
- echo "Warning: no suitable GCC for $architecture." >&2
- continue
+ if [ "invalid" != "$GCCPREFIX" ]; then
+ GCC="${GCCPREFIX}gcc"
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
+ for clang_arch in $TCLIST invalid; do
+ testcc "clang" "-target ${clang_arch}-$TABI -c" && break
+ done
-if program_exists gcc; then
- HOSTCC=gcc
-else
- HOSTCC=cc
-fi
+ 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
-cat <<EOF
-IASL:=${IASL}
+ if [ -z "$GCC" -a -z "$CLANG" ]; then
+ echo "Warning: no suitable compiler for $architecture." >&2
+ return 1
+ fi
+}
-# native toolchain
-HOSTCC:=${HOSTCC}
-EOF
+# 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