coreboot-kgpe-d16/util/abuild/abuild
Martin Roth 10008107b7 abuild: Add option of starting with an existing defconfig file
We want to start testing builds with additional Kconfig options to try
to get more coverage.  This will allow us to enable various options to
test without having to add each individual option to the abuild script.

Change-Id: I9bb2bb6f38589e3bcc1282dc4cad51cf6f5149aa
Signed-off-by: Martin Roth <martinroth@google.com>
Reviewed-on: https://review.coreboot.org/14016
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
2016-03-13 03:05:43 +01:00

681 lines
20 KiB
Bash
Executable file

#!/bin/bash
#
# coreboot autobuild
#
# This script builds coreboot images for all available targets.
#
# (C) 2004 by Stefan Reinauer <stepan@openbios.org>
# (C) 2006-2010 by coresystems GmbH <info@coresystems.de>
# (C) 2013-2014 Sage Electronic Engineering, LLC
# (C) 2014 Patrick Georgi <patrick@georgi-clan.de>
#
# This file is subject to the terms and conditions of the GNU General
# Public License. See the file COPYING in the main directory of this
# archive for more details.
#
#set -x # Turn echo on....
ABUILD_DATE="Oct 13, 2015"
ABUILD_VERSION="0.9.4"
TOP=$PWD
# Where shall we place all the build trees?
TARGET=${COREBOOT_BUILD_DIR:-coreboot-builds}
XMLFILE=$TOP/abuild.xml
REAL_XMLFILE=$XMLFILE
export KCONFIG_OVERWRITECONFIG=1
# path to payload. Should be more generic
PAYLOAD=/dev/null
# path to coreboot XGCC
XGCCPATH="`pwd`/util/crossgcc/xgcc/bin/"
# Add XGCC to the path.
if [ -d "$XGCCPATH" ] && [[ ":$PATH:" != *":$XGCCPATH:"* ]]; then
PATH="$XGCCPATH:$PATH"
fi
# Lines of error context to be printed in FAILURE case
CONTEXT=12
# Configure-only mode
configureonly=0
# Did any board fail to build?
failed=0
# default: single CPU build
cpus=1
# One might want to adjust these in case of cross compiling
for i in make gmake gnumake nonexistant_make; do
$i --version 2>/dev/null |grep "GNU Make" >/dev/null && break
done
if [ "$i" = "nonexistant_make" ]; then
echo No GNU Make found.
exit 1
fi
MAKE=$i
# this can be changed to junit by -J
mode=text
# silent mode.. no compiler calls, only warnings in the log files.
# this is disabled per default but can be enabled with -s
silent=
# quiet mode: only print pass, failure, and 'skipped' messages
quiet=false
# clang mode enabled by -sb option.
scanbuild=false
ARCH=`uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/i86pc/i386/ \
-e s/arm.*/arm/ -e s/sa110/arm/ -e s/x86_64/amd64/ \
-e "s/Power Macintosh/ppc/"`
trap interrupt INT
function interrupt
{
printf "\n$0: execution interrupted manually.\n"
if [ "$mode" == "junit" ]; then
printf "$0: deleting incomplete xml output file.\n"
fi
exit 1
}
function debug
{
test "$verbose" == "true" && printf "$*\n"
}
function junit
{
test "$mode" == "junit" && printf "$*\n" >> $XMLFILE
return 0
}
function junitfile
{
test "$mode" == "junit" && {
printf '<![CDATA[\n'
cat $1
printf ']]>\n'
} >> $XMLFILE
}
# Return mainboard descriptors.
# By default all mainboards are listed, but when passing a two-level path
# below src/mainboard, such as emulation/qemu-i440fx, or emulation/*, it
# returns all board descriptors in that hierarchy.
function get_mainboards
{
local search_space=${1-*/*}
grep -h "^[[:space:]]*config\>[[:space:]]*\<BOARD_" \
${ROOT}/src/mainboard/${search_space}/Kconfig.name 2>/dev/null | \
sed "s,^.*\<BOARD_\([A-Z0-9_]*\)\>.*$,\1,"
}
# Given a mainboard descriptor, return its directory below src/mainboard
function mainboard_directory
{
local MAINBOARD=$1
grep -l "^[[:space:]]*config\>[[:space:]]*\<BOARD_${MAINBOARD}\>" \
${ROOT}/src/mainboard/*/*/Kconfig.name | \
sed "s:^$ROOT/src/mainboard/\(.*\)/Kconfig.name$:\1:"
}
# Given a mainboard descriptor, return its vendor (CONFIG_VENDOR_*)
function mainboard_vendor
{
local MAINBOARD=$1
local kconfig_file=$( \
grep -l "^[[:space:]]*config\>[[:space:]]*\<BOARD_${MAINBOARD}\>" \
${ROOT}/src/mainboard/*/*/Kconfig.name | \
sed "s:^\(${ROOT}/src/mainboard/.*\)/.*/\(Kconfig.name\)$:\1/\2:" )
if [ ! -f "$kconfig_file" ]; then
exit 1
fi
grep "^[[:space:]]*config\>[[:space:]]*\<VENDOR_" $kconfig_file | \
sed "s,^.*\<VENDOR_\([A-Z0-9_]*\)\>.*$,\1,"
}
# Accepts directory names (eg. emulation/qemu-i440fx) and mainboard
# descriptors (eg. EMULATION_QEMU_X86_I440F} and returns the latter
# format.
# If a directory contains multiple boards, returns them all.
function normalize_target
{
local targets=$(get_mainboards $1)
if [ -n "$targets" ]; then
echo $targets
return
fi
local targets=$(echo $1 | tr ',' ' ')
for i in $targets; do
if [ -n "$(mainboard_directory $i)" ]; then
echo $i
else
echo "$i is not a valid target" >&2
exit 1
fi
done
}
function create_config
{
local MAINBOARD=$1
local build_dir=$TARGET/${MAINBOARD}
local config_file=${build_dir}/config.build
local board_srcdir=$(mainboard_directory ${MAINBOARD})
# get a working payload for the board if we have one.
# the --payload option expects a directory containing
# a shell script payload.sh
# Usage: payload.sh [BOARD]
# the script returns an absolute path to the payload binary.
if [ -f $payloads/payload.sh ]; then
local PAYLOAD=`sh $payloads/payload.sh $MAINBOARD`
if [ $? -gt 0 ]; then
echo "problem with payload"
exit 1
fi
if [ "$quiet" == "false" ]; then printf "Using payload $PAYLOAD\n"; fi
elif [ "$payloads" = "none" ]; then
local PAYLOAD=none
fi
mkdir -p ${build_dir}
mkdir -p $TARGET/sharedutils
if [ "$quiet" == "false" ]; then printf " Creating config file for $MAINBOARD... \n"; fi
printf "CONFIG_VENDOR_$(mainboard_vendor ${MAINBOARD})=y\n" > ${config_file}
printf "CONFIG_BOARD_${MAINBOARD}=y\n" >> ${config_file}
grep "select[\t ]*ARCH" ${ROOT}/src/mainboard/${board_srcdir}/Kconfig | \
sed "s,^.*\(ARCH_.*\)[^A-Z0-9_]*,CONFIG_\1=y," >> ${config_file}
printf "CONFIG_MAINBOARD_DIR=\"${board_srcdir}\"\n" >> ${config_file}
if [ "$PAYLOAD" = "none" ]; then
printf "CONFIG_PAYLOAD_NONE=y\n" >> ${config_file}
elif [ "$PAYLOAD" != "/dev/null" ]; then
printf "# CONFIG_PAYLOAD_NONE is not set\n" >> ${config_file}
printf "# CONFIG_PAYLOAD_SEABIOS is not set\n" >> ${config_file}
printf "CONFIG_PAYLOAD_ELF=y\n" >> ${config_file}
printf "CONFIG_PAYLOAD_FILE=\"$PAYLOAD\"\n" >> ${config_file}
fi
if [ "$quiet" == "false" ]; then printf " $MAINBOARD ($customizing)\n"; fi
printf "$configoptions" >> ${config_file}
yes "" 2>/dev/null | $MAKE oldconfig $silent DOTCONFIG=${config_file} obj=${build_dir} objutil=$TARGET/sharedutils &> ${build_dir}/config.log
ret=$?
if [ $ret -eq 0 ]; then
if [ "$quiet" == "false" ]; then printf " $MAINBOARD config created.\n"; fi
return 0
else
# Does this ever happen?
if [ "$quiet" == "false" ]; then printf "$MAINBOARD config creation FAILED!\nLog excerpt:\n"; fi
tail -n $CONTEXT $build_dir/config.log 2> /dev/null || tail -$CONTEXT $build_dir/config.log
return 1
fi
}
function create_buildenv
{
local MAINBOARD=$1
create_config $MAINBOARD
ret=$?
# Allow simple "make" in the target directory
local MAKEFILE=$TARGET/${MAINBOARD}/Makefile
echo "# autogenerated" > $MAKEFILE
echo "TOP=$ROOT" >> $MAKEFILE
echo "BUILD=$TARGET" >> $MAKEFILE
echo "OBJ=\$(BUILD)/${MAINBOARD}" >> $MAKEFILE
echo "OBJUTIL=\$(BUILD)/sharedutils" >> $MAKEFILE
echo "all:" >> $MAKEFILE
echo " @cp -a config.h config.h.bak" >> $MAKEFILE
echo " @cd \$(TOP); \$(MAKE) oldconfig DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)" >> $MAKEFILE
echo " @tail -n+6 config.h > config.new; tail -n+6 config.h.bak > config.old" >> $MAKEFILE
echo " @cmp -s config.new config.old && cp -a config.h.bak config.h || echo \"Config file changed\"" >> $MAKEFILE
echo " @rm config.h.bak config.new config.old" >> $MAKEFILE
echo " @cd \$(TOP); \$(MAKE) DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)" >> $MAKEFILE
return $ret
}
function compile_target
{
local MAINBOARD=$1
if [ "$quiet" == "false" ]; then printf " Compiling $MAINBOARD image$cpuconfig...\n"; fi
CURR=$( pwd )
#stime=`perl -e 'print time();' 2>/dev/null || date +%s`
build_dir=$TARGET/${MAINBOARD}
eval $BUILDPREFIX $MAKE $silent DOTCONFIG=${build_dir}/config.build obj=${build_dir} objutil=$TARGET/sharedutils \
&> ${build_dir}/make.log
ret=$?
cp .xcompile ${build_dir}/xcompile.build
cd $TARGET/${MAINBOARD}
etime=`perl -e 'print time();' 2>/dev/null || date +%s`
duration=$(( $etime - $stime ))
junit " <testcase classname='board${testclass/#/.}' name='$MAINBOARD' time='$duration' >"
if [ $ret -eq 0 ]; then
junit "<system-out>"
junitfile make.log
junit "</system-out>"
printf "ok\n" > compile.status
printf "$MAINBOARD built successfully. (took ${duration}s)\n"
else
ret=1
junit "<failure type='BuildFailed'>"
junitfile make.log
junit "</failure>"
printf "failed\n" > compile.status
printf "$MAINBOARD build FAILED after ${duration}s!\nLog excerpt:\n"
tail -n $CONTEXT make.log 2> /dev/null || tail -$CONTEXT make.log
failed=1
fi
cd $CURR
if [ $clean_work = "true" ]; then
rm -rf $TARGET/${MAINBOARD}
fi
return $ret
}
function build_target
{
local MAINBOARD=$1
local board_srcdir=$(mainboard_directory ${MAINBOARD})
if [ "`cat $TARGET/${MAINBOARD}/compile.status 2>/dev/null`" = "ok" -a \
"$buildall" = "false" ]; then
printf "Skipping $MAINBOARD; (already successful)\n"
return
fi
HOSTCC='gcc'
if [ $chromeos = true -a `grep -c "^[[:space:]]*select[[:space:]]*MAINBOARD_HAS_CHROMEOS\>" ${ROOT}/src/mainboard/${board_srcdir}/Kconfig` -eq 0 ]; then
echo "${MAINBOARD} doesn't support Chrome OS, skipping."
return
fi
if [ -f src/mainboard/${board_srcdir}/abuild.disabled ]; then
echo "${MAINBOARD} disabled:"
cat src/mainboard/${board_srcdir}/abuild.disabled
return
fi
if [ "$quiet" == "false" ]; then printf "Building $MAINBOARD\n"; fi
mkdir -p $TARGET/${MAINBOARD} $TARGET/abuild
ABSPATH=`cd $TARGET/abuild; pwd`
XMLFILE=$ABSPATH/${MAINBOARD}.xml
rm -f ${XMLFILE}
stime=`perl -e 'print time();' 2>/dev/null || date +%s`
create_buildenv $MAINBOARD
required_arches=`egrep "^CONFIG_ARCH_(BOOTBLOCK|R.MSTAGE|VERSTAGE)" $TARGET/${MAINBOARD}/config.build | \
sed "s,^CONFIG_ARCH_[^_]*_\([^=]*\)=.*$,\1," |sort -u |tr 'A-Z\n\r' 'a-z '`
missing_arches=`printf 'include .xcompile\nall: ; @echo $(foreach arch,'"$required_arches"',$(if $(filter $(arch),$(SUBARCH_SUPPORTED)),,$(arch)))' | make --no-print-directory -f -`
if [ -n "$missing_arches" ]; then
printf "skipping $MAINBOARD because we're missing compilers for ($missing_arches)\n"
return
fi
if [ $? -eq 0 -a $configureonly -eq 0 ]; then
BUILDPREFIX=
if [ "$scanbuild" = "true" ]; then
scanbuild_out=$TARGET/${MAINBOARD}-scanbuild
rm -rf ${scanbuild_out}
BUILDPREFIX="scan-build -o ${scanbuild_out}tmp"
fi
compile_target ${MAINBOARD}
if [ "$scanbuild" = "true" ]; then
mv ${scanbuild_out}tmp/* ${scanbuild_out}
rmdir ${scanbuild_out}tmp
fi
fi
# Not calculated here because we still print it in compile_target
#etime=`perl -e 'print time();' 2>/dev/null || date +%s`
#duration=$(( $etime - $stime ))
junit "</testcase>"
}
function remove_target
{
if [ "$remove" != "true" ]; then
return 0
fi
local MAINBOARD=$1
# Save the generated coreboot.rom file of each board.
if [ -r "$TARGET/${MAINBOARD}/coreboot.rom" ]; then
cp $TARGET/${MAINBOARD}/coreboot.rom \
${MAINBOARD}_coreboot.rom
fi
printf "Removing build dir for board $MAINBOARD...\n"
rm -rf $TARGET/${MAINBOARD}
return 0
}
function myhelp
{
cat << __END_OF_HELP
Usage: $0 [-v] [-a] [-b] [-r] [-t <vendor/board>] [-p <dir>] [lbroot]
$0 [-V|--version]
$0 [-h|--help]
Options:\n"
[-v|--verbose] print more messages
[-q|--quiet] print fewer messages
[-a|--all] build previously succeeded ports as well
[-r|--remove] remove output dir after build
[-t|--target <vendor/board>] attempt to build target vendor/board only
[-p|--payloads <dir>] use payloads in <dir> to build images
[-V|--version] print version number and exit
[-h|--help] print this help and exit
[-J|--junit] write JUnit formatted xml log file
(defaults to $XMLFILE)
[-T|--test] submit image(s) to automated test system
[-c|--cpus <numcpus>] build on <numcpus> at the same time
[-s|--silent] omit compiler calls in logs
[-y|--ccache] use ccache
[-C|--config] configure-only mode
[-l|--loglevel <num>] set loglevel
[-u|--update] update existing image
[-P|--prefix <name>] file name prefix in CBFS
[-B|--blobs] Allow using binary files
[-z|--clean] Remove build results when finished
[-o|--outdir <path>] store build results in path
(defaults to $TARGET)
[-L|--clang] Use clang
[-K|--kconfig <name>] Prepend file to generated Kconfig
[-x|--chromeos] Build with CHROMEOS enabled
Skip boards without Chrome OS support
[-X|--xmlfile <name>] set JUnit XML log file filename
[--scan-build] use clang's static analyzer
[cbroot] absolute path to coreboot sources
(defaults to $ROOT)
__END_OF_HELP
}
function myversion
{
cat << EOF
coreboot autobuild v$ABUILD_VERSION ($ABUILD_DATE)
Copyright (C) 2004 by Stefan Reinauer <stepan@openbios.org>
Copyright (C) 2006-2010 by coresystems GmbH <info@coresystems.de>
This program is free software; you may redistribute it under the terms
of the GNU General Public License. This program has absolutely no
warranty.
EOF
}
# default options
target=""
buildall=false
verbose=false
test -f util/sconfig/sconfig.l && ROOT=$( pwd )
test -f ../util/sconfig/sconfig.l && ROOT=$( cd ..; pwd )
test "$ROOT" = "" && ROOT=$( cd ../..; pwd )
# Look if we have getopt. If not, build it.
export PATH=$PATH:util/abuild
getopt - > /dev/null 2>/dev/null || gcc -o util/abuild/getopt util/abuild/getopt.c
# command line for xargs parallelization. Thus overwrite -c X
cmdline="$* -c 1"
# parse parameters.. try to find out whether we're running GNU getopt
getoptbrand="`getopt -V`"
if [ "${getoptbrand:0:6}" == "getopt" ]; then
# Detected GNU getopt that supports long options.
args=`getopt -l version,verbose,quiet,help,all,target:,payloads:,cpus:,silent,junit,config,loglevel:,remove,prefix:,update,scan-build,ccache,blobs,clang,clean,outdir:,chromeos,xmlfile:,kconfig: -o Vvqhat:p:c:sJCl:rP:uyBLzo:xX:K: -- "$@"` || exit 1
eval set -- $args
else
# Detected non-GNU getopt
args=`getopt Vvqhat:p:c:sJCl:rP:uyBLzo:xX:K: $*`
set -- $args
fi
if [ $? != 0 ]; then
myhelp
exit 1
fi
chromeos=false
clean_work=false
customizing=""
configoptions=""
# testclass needs to be undefined if not used for variable expansion to work
unset testclass
while true ; do
case "$1" in
-J|--junit) shift; mode=junit; rm -f $XMLFILE ;;
-t|--target) shift; target="$1"; shift;;
-a|--all) shift; buildall=true;;
-r|--remove) shift; remove=true;;
-v|--verbose) shift; verbose=true; silent='V=1';;
-q|--quiet) shift; quiet=true;;
-V|--version) shift; myversion; exit 0;;
-h|--help) shift; myversion; myhelp; exit 0;;
-p|--payloads) shift; payloads="$1"; shift;;
-c|--cpus) shift
export MAKEFLAGS="-j $1"
cpus=$1
test "$MAKEFLAGS" == "-j max" && export MAKEFLAGS="-j" && cpuconfig=" in parallel"
test "$1" == "1" && cpuconfig=" on 1 cpu"
expr "$1" : '-\?[0-9]\+$' > /dev/null && test 0$1 -gt 1 && cpuconfig=" on $1 cpus in parallel"
shift;;
-s|--silent) shift; silent="-s";;
--scan-build) shift
scanbuild=true
customizing="${customizing}, scan-build"
;;
-y|--ccache) shift
customizing="${customizing}, ccache"
configoptions="${configoptions}CONFIG_CCACHE=y\n"
;;
-C|--config) shift; configureonly=1;;
-l|--loglevel) shift
customizing="${customizing}, loglevel $1"
configoptions="${configoptions}CONFIG_DEFAULT_CONSOLE_LOGLEVEL_$1=y\n"
configoptions="${configoptions}CONFIG_DEFAULT_CONSOLE_LOGLEVEL=$1\n"
shift;;
-u|--update) shift
customizing="${customizing}, update"
configoptions="${configoptions}CONFIG_UPDATE_IMAGE=y\n"
;;
-P|--prefix) shift
customizing="${customizing}, cbfs prefix $1"
configoptions="${configoptions}CONFIG_CBFS_PREFIX=\"$1\""
shift;;
-B|--blobs) shift
customizing="${customizing}, blobs"
configoptions="${configoptions}CONFIG_USE_BLOBS=y\n"
;;
-L|--clang) shift
customizing="${customizing}, clang"
configoptions="${configoptions}CONFIG_COMPILER_LLVM_CLANG=y\n# CONFIG_COMPILER_GCC is not set\n"
;;
-z|--clean) shift
customizing="${customizing}, clean"
clean_work=true
;;
-o|--outdir) shift
TARGET=$1; shift
;;
-x|--chromeos) shift
chromeos=true
testclass=chromeos
customizing="${customizing}, chrome os"
configoptions="${configoptions}CONFIG_CHROMEOS=y\n"
;;
-X|--xmlfile) shift; XMLFILE=$1; REAL_XMLFILE=$1; shift;;
-K|--kconfig) shift
testclass=="$(basename $1 | tr '.' '_' )"
customizing="${customizing}, $1 config"
configoptions="$(cat "$1")${configoptions}\n"
shift;;
--) shift; break;;
-*) printf "Invalid option\n\n"; myhelp; exit 1;;
*) break;;
esac
done
if [ -z "$TARGET" -o "$TARGET" = "/" ]; then
echo "Please specify a valid, non-root build directory."
exit 1
fi
customizing=`echo $customizing |cut -c3-`
if [ "$customizing" = "" ]; then
customizing="default configuration"
fi
USE_XARGS=0
if [ "$cpus" != "1" ]; then
# Limit to 32 parallel builds for now.
# Thrashing all caches because we run
# 160 abuilds in parallel is no fun.
if [ "$cpus" = "max" ]; then
cpus=32
fi
# Test if xargs supports the non-standard -P flag
# FIXME: disabled until we managed to eliminate all the make(1) quirks
echo | xargs -P ${cpus:-0} -n 1 echo 2>/dev/null >/dev/null && USE_XARGS=1
fi
if [ "$USE_XARGS" = "0" ]; then
test "$MAKEFLAGS" == "" && test "$cpus" != "" && export MAKEFLAGS="-j $cpus"
build_targets()
{
local targets=${*-$(get_mainboards)}
for MAINBOARD in $targets; do
build_target ${MAINBOARD}
remove_target ${MAINBOARD}
done
}
else
build_targets()
{
local targets=${*-$(get_mainboards)}
# seed shared utils
TMPCFG=`mktemp`
printf "$configoptions" > $TMPCFG
$MAKE -j $cpus DOTCONFIG=$TMPCFG obj=$TARGET/temp objutil=$TARGET/sharedutils allnoconfig
printf "$configoptions" >> $TMPCFG
yes "" 2>/dev/null | $MAKE -j $cpus DOTCONFIG=$TMPCFG obj=$TARGET/temp objutil=$TARGET/sharedutils oldconfig 2>/dev/null |head > /dev/null
BUILDPREFIX=
if [ "$scanbuild" = "true" ]; then
scanbuild_out=$TARGET/sharedutils-scanbuild
rm -rf ${scanbuild_out}
BUILDPREFIX="scan-build -o ${scanbuild_out}tmp"
fi
mkdir -p $TARGET/abuild
local ABSPATH=`cd $TARGET/abuild; pwd`
local XMLFILE=$ABSPATH/__util.xml
rm -f ${XMLFILE}
local stime=`perl -e 'print time();' 2>/dev/null || date +%s`
$BUILDPREFIX $MAKE -j $cpus DOTCONFIG=$TMPCFG obj=$TARGET/temp objutil=$TARGET/sharedutils tools > $TARGET/sharedutils/make.log 2>&1
local ret=$?
local etime=`perl -e 'print time();' 2>/dev/null || date +%s`
local duration=$(( $etime - $stime ))
junit " <testcase classname='util' name='all' time='$duration' >"
if [ $ret -eq 0 ]; then
junit "<system-out>"
junitfile $TARGET/sharedutils/make.log
junit "</system-out>"
junit "</testcase>"
else
junit "<failure type='BuildFailed'>"
junitfile $TARGET/sharedutils/make.log
junit "</failure>"
junit "</testcase>"
return
fi
if [ $ret -eq 1 ]; then
return
fi
if [ "$scanbuild" = "true" ]; then
mv ${scanbuild_out}tmp/* ${scanbuild_out}
rmdir ${scanbuild_out}tmp
fi
rm -rf $TARGET/temp $TMPCFG
echo $targets | xargs -P ${cpus:-0} -n 1 $0 $cmdline -t
}
fi
test -z "$1" || ROOT=$1
debug "ROOT=$ROOT"
junit '<?xml version="1.0" encoding="utf-8"?>'
junit '<testsuite>'
if [ "$target" != "" ]; then
# build a single board
MAINBOARD=$(normalize_target ${target})
if [ -z "${MAINBOARD}" ]; then
printf "No such target: $target\n"
exit 1
fi
build_srcdir=$(mainboard_directory ${MAINBOARD})
if [ "$(echo ${MAINBOARD} | wc -w)" -gt 1 ]; then
build_targets ${MAINBOARD}
elif [ ! -r $ROOT/src/mainboard/${build_srcdir} ]; then
printf "No such target: ${MAINBOARD}\n"
exit 1
else
build_target ${MAINBOARD}
remove_target ${MAINBOARD}
test "$mode" != "text" && \
test -f $TARGET/abuild/${MAINBOARD}.xml && \
cat $TARGET/abuild/${MAINBOARD}.xml >> $REAL_XMLFILE
XMLFILE=$REAL_XMLFILE
fi
else
build_targets
rm -f $REAL_XMLFILE
XMLFILE=$REAL_XMLFILE
junit '<?xml version="1.0" encoding="utf-8"?>'
junit '<testsuite>'
if [ "$mode" != "text" ]; then
for xmlfile in $TARGET/abuild/*_*.xml; do
cat $xmlfile >> $REAL_XMLFILE
done
fi
XMLFILE=$REAL_XMLFILE
fi
junit '</testsuite>'
exit $failed