10008107b7
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>
681 lines
20 KiB
Bash
Executable file
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
|