Make xcompile support multiple architectures

With this change the the xcompile script now creates environment variables
for more than one architecture.

Signed-off-by: David Hendricks <dhendrix@chromium.org>
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Signed-off-by: Stefan Reinauer <stepan@coresystems.de>

Change-Id: I349a1fd1d865ef16979f1dfd6aeca12b1ee2eed6
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Reviewed-on: http://review.coreboot.org/1915
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Tested-by: build bot (Jenkins)
This commit is contained in:
Ronald G. Minnich 2012-11-26 14:33:09 -08:00
parent 534c8a013f
commit e820e5cb3a
3 changed files with 194 additions and 82 deletions

View File

@ -78,7 +78,6 @@ HOSTCC = gcc
HOSTCXX = g++
HOSTCFLAGS := -g
HOSTCXXFLAGS := -g
LIBGCC_FILE_NAME := $(shell test -r `$(CC) -print-libgcc-file-name` && $(CC) -print-libgcc-file-name)
DOXYGEN := doxygen
DOXYGEN_OUTPUT_DIR := doxygen
@ -114,6 +113,31 @@ else
include $(HAVE_DOTCONFIG)
ARCHDIR-$(CONFIG_ARCH_ARM) := armv7
ARCHDIR-$(CONFIG_ARCH_X86) := x86
ARCH-y := $(ARCHDIR-y)
# If architecture folder name is different from GCC binutils architecture name,
# override here.
ARCH-$(CONFIG_ARCH_ARM) := littlearm
ARCH-$(CONFIG_ARCH_X86) := i386
CC := $(CC_$(ARCH-y))
AS := $(AS_$(ARCH-y))
LD := $(LD_$(ARCH-y))
NM := $(NM_$(ARCH-y))
OBJCOPY := $(OBJCOPY_$(ARCH-y))
OBJDUMP := $(OBJDUMP_$(ARCH-y))
READELF := $(READELF_$(ARCH-y))
STRIP := $(STRIP_$(ARCH-y))
AR := $(AR_$(ARCH-y))
CFLAGS += $(CFLAGS_$(ARCH-y))
LIBGCC_FILE_NAME := $(shell test -r `$(CC) -print-libgcc-file-name` && \
$(CC) -print-libgcc-file-name)
ifneq ($(INNER_SCANBUILD),y)
ifeq ($(CONFIG_COMPILER_LLVM_CLANG),y)
CC:=clang -m32 -mno-mmx -mno-sse

View File

@ -23,7 +23,6 @@ export KERNELVERSION := $(shell if [ -d "$(top)/.git" -a -f "`which git`" ]; the
#######################################################################
# Basic component discovery
ARCHDIR-$(CONFIG_ARCH_X86) := x86
MAINBOARDDIR=$(call strip_quotes,$(CONFIG_MAINBOARD_DIR))
export MAINBOARDDIR

View File

@ -3,6 +3,7 @@
# 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
@ -18,104 +19,192 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
testcc()
{
echo "_start(void) {}" > .$$$$.c
$1 -nostdlib -Werror $2 .$$$$.c -o .$$$$.tmp 2>/dev/null >/dev/null
ret=$?
rm -f .$$$$.c .$$$$.tmp
return $ret
TMPFILE=""
die() {
echo "ERROR: $*" >&2
exit 1
}
for make in make gmake gnumake; do
if [ "`$make --version 2>/dev/null | grep -c GNU`" -gt 0 ]; then
MAKE=$make
break
clean_up() {
if [ -n "$TMPFILE" ]; then
rm -f "$TMPFILE" "$TMPFILE.c" "$TMPFILE.o"
fi
done
}
GCCPREFIX=invalid
XGCCPATH=${1:-"`pwd`/util/crossgcc/xgcc/bin/"}
echo '# XGCCPATH='${XGCCPATH}
TMPFILE=`mktemp /tmp/temp.XXXX 2>/dev/null || echo /tmp/temp.78gOIUGz`
touch $TMPFILE
program_exists() {
type "$1" >/dev/null 2>&1
}
# This loops over all supported architectures in TARCH
TARCH=('i386' 'x86_64')
TWIDTH=32
for search_for in "${TARCH[@]}"; do
TARCH_SEARCH=("${TARCH_SEARCH[@]}" ${XGCCPATH}${search_for}-elf- ${search_for}-elf-)
done
echo '# TARCH_SEARCH='${TARCH_SEARCH[@]}
testcc() {
local tmp_c="$TMPFILE.c"
local tmp_o="$TMPFILE.o"
rm -f "$tmp_c" "$tmp_o"
echo "_start(void) {}" >"$tmp_c"
"$1" -nostdlib -Werror $2 "$tmp_c" -o "$tmp_o" >/dev/null 2>&1
}
for gccprefixes in "${TARCH_SEARCH[@]}" ""; do
if ! which ${gccprefixes}as 2>/dev/null >/dev/null; then
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
arm )
# testcc "$CC" "$CFLAGS -mcpu=cortex-a9" &&
# CFLAGS="$CFLAGS -mcpu=cortex-a9"
testcc "$CC" "\
$CFLAGS -ffixed-r8 -msoft-float -marm -mabi=aapcs-linux \
-mno-thumb-interwork -march=armv7 -mno-thumb-interwork" && CFLAGS="\
$CFLAGS -ffixed-r8 -msoft-float -marm -mabi=aapcs-linux \
-mno-thumb-interwork -march=armv7 -mno-thumb-interwork"
;;
esac
}
report_arch_toolchain() {
cat <<EOF
# elf${TWIDTH}-${TARCH} toolchain (${GCCPREFIX}gcc)
CC_${TARCH}:=${GCCPREFIX}gcc ${CFLAGS}
AS_${TARCH}:=${GCCPREFIX}as ${ASFLAGS}
LD_${TARCH}:=${GCCPREFIX}ld ${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 arm"
# ARM Architecture
TARCH_arm="littlearm"
TCLIST_arm="littlearm"
TWIDTH_arm="32"
# X86 Architecture
TARCH_x86="i386"
TCLIST_x86="i386 x86_64"
TWIDTH_x86="32"
# This loops over all supported architectures.
for architecture in $SUPPORTED_ARCHITECTURE; do
GCCPREFIX="invalid"
TARCH="$(eval echo \$TARCH_$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-"
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" "$TARCH" "" && break
testas "$gccprefixes" "$TWIDTH" "$TARCH" "TRUE" && break
done
if [ "$GCCPREFIX" = "invalid" ]; then
echo "Warning: no suitable GCC for $architecture." >&2
continue
fi
rm -f ${TMPFILE}.o
if ${gccprefixes}as -o ${TMPFILE}.o ${TMPFILE}; then
TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o`
if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then
GCCPREFIX=$gccprefixes
ASFLAGS=
CFLAGS=
LDFLAGS=
break
fi
fi
if ${gccprefixes}as --32 -o ${TMPFILE}.o ${TMPFILE}; then
TYPE=`${gccprefixes}objdump -p ${TMPFILE}.o`
if [ ${TYPE##* } == "elf${TWIDTH}-${TARCH}" ]; then
GCCPREFIX=$gccprefixes
ASFLAGS=--32
CFLAGS="-m32 -Wl,-b,elf32-i386 -Wl,-melf_i386 "
LDFLAGS="-b elf32-i386 -melf_i386"
break
fi
fi
CC="${GCCPREFIX}"gcc
detect_special_flags "$architecture"
report_arch_toolchain
done
rm -f $TMPFILE ${TMPFILE}.o
if [ "$GCCPREFIX" = "invalid" ]; then
echo '$(error no suitable gcc found)'
exit 1
fi
CC="${GCCPREFIX}gcc"
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 "
# 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 "
if which gcc 2>/dev/null >/dev/null; then
HOSTCC=gcc
else
HOSTCC=cc
fi
if [ "`${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI`" -gt 0 ]; then
if [ "$(${XGCCPATH}/iasl 2>/dev/null | grep -c ACPI)" -gt 0 ]; then
IASL=${XGCCPATH}iasl
else
IASL=iasl
fi
cat << EOF
# elf${TWIDTH}-${TARCH} toolchain
AS:=${GCCPREFIX}as ${ASFLAGS}
CC:=${GCCPREFIX}gcc ${CFLAGS}
AR:=${GCCPREFIX}ar
LD:=${GCCPREFIX}ld ${LDFLAGS}
STRIP:=${GCCPREFIX}strip
NM:=${GCCPREFIX}nm
OBJCOPY:=${GCCPREFIX}objcopy
OBJDUMP:=${GCCPREFIX}objdump
if program_exists gcc; then
HOSTCC=gcc
else
HOSTCC=cc
fi
cat <<EOF
IASL:=${IASL}
# native toolchain
HOSTCC:=${HOSTCC}
EOF