Files
xen/automation/build/yocto/build-yocto.sh
T
Stefano Stabellini a0c3b87a76 automation: add binaries/ to artifacts for Yocto arm32 job
Copy the build output of Yocto builds to binaries/ for the arm32 target,
and export binaries/ among the jobs artifacts so that they can be reused
by other jobs.

Signed-off-by: Stefano Stabellini <stefano.stabellini@amd.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
2023-02-27 13:19:31 -08:00

373 lines
9.7 KiB
Bash
Executable File

#!/bin/bash
#
# Yocto meta virtualization build and run script
#
# This script is building Yocto xen-image-minimal for qemu targets and run
# them using runqemu inside yocto to check that dom0 is booting properly.
# The build is using a local xen source tree so that specific patches can be
# tested.
# In order to optimize the build time, a build cache is used so that only xen
# packages and its dependencies are rebuilt (qemu and final image mainly).
#
# get command error even when piped.
set -o pipefail
# Directories
YOCTODIR="$HOME/yocto-layers"
CACHEDIR="$HOME/yocto-cache"
LOGDIR="$HOME/logs"
XENDIR="$HOME/xen"
BUILDDIR="$HOME/build"
OUTPUTDIR=`pwd`/binaries
# what yocto bsp we support
TARGET_SUPPORTED="qemuarm qemuarm64 qemux86-64"
VERBOSE="n"
TARGETLIST=""
BUILDJOBS="8"
# actions to do
do_clean="n"
do_build="y"
do_run="y"
do_localsrc="n"
do_dump="n"
do_copy="n"
build_result=0
# layers to include in the project
build_layerlist="poky/meta poky/meta-poky poky/meta-yocto-bsp \
meta-openembedded/meta-oe meta-openembedded/meta-python \
meta-openembedded/meta-filesystems \
meta-openembedded/meta-networking meta-virtualization"
# yocto image to build
build_image="xen-image-minimal"
function print_progress() {
echo -n "$(date +%T) $*"
}
function run_task() {
local task_name="$1"
local task_target="$2"
task_log="${task_name//project_}-${task_target}"
mkdir -p "${LOGDIR}"
print_progress
echo -n "${task_name//project_} ${task_target}: "
if [ "${VERBOSE}" = "n" ]; then
"$@" > "${LOGDIR}/${task_log}.log" 2>&1
else
"$@" 2>&1 | tee "${LOGDIR}/${task_log}.log"
fi
if [ ${?} -ne 0 ]; then
echo "Error"
build_result=$((build_result+1))
if [ "${do_dump}" = "y" ]; then
echo
echo "############ LOGS-START ############"
cat "${LOGDIR}/${task_log}.log"
echo "############ LOGS-END ############"
echo
fi
return 1
else
echo "OK"
return 0
fi
}
function project_create() {
target="${1:?}"
destdir="${BUILDDIR}/${target}"
(
# init yocto project
source "${YOCTODIR}/poky/oe-init-build-env" "${destdir}"
# add needed layers
for layer in ${build_layerlist}; do
bitbake-layers add-layer "${YOCTODIR}/${layer}" || exit 1
done
) || return 1
# Detect latest version available in Yocto and use it instead of default
# one.
XENVERS=$(grep -e "^XEN_REL" \
"${YOCTODIR}"/meta-virtualization/recipes-extended/xen/xen_*.bb \
2> /dev/null | tr -d ' ' | tr -d '?' | tr -d '"' \
| sed -e "s/.*=//" | sort -V | tail -n 1)
# customize project configuration
cat <<EOF >> "${destdir}/conf/local.conf"
# Yocto BSP
MACHINE = "${target}"
# Use local cache to reuse previous builds results
SSTATE_DIR = "${CACHEDIR}/sstate-cache"
DL_DIR = "${CACHEDIR}/downloads"
# Enable xen and virtualization
DISTRO_FEATURES = " virtualization xen ipv4"
# Speed up run by not generating ssh host keys
IMAGE_INSTALL:append:pn-xen-image-minimal = " ssh-pregen-hostkeys"
# Save some disk space
INHERIT += "rm_work"
# Reduce number of jobs
BB_NUMBER_THREADS="${BUILDJOBS}"
# Use latest Xen version
PREFERRED_VERSION:pn-xen = "${XENVERS}%"
PREFERRED_VERSION:pn-xen-tools = "${XENVERS}%"
# Use autorev for now as Xen SHA used by latest yocto recipe for Xen does not
# include fixes required to build x86 on arm
SRCREV:pn-xen = "\${AUTOREV}"
SRCREV:pn-xen-tools = "\${AUTOREV}"
# Disable all QA errors as the recipe is not up to date with changes in Xen
# when we use local sources
ERROR_QA:pn-xen = "arch"
ERROR_QA:pn-xen-tools = "arch"
EOF
if [ "${do_localsrc}" = "y" ]; then
XENBASE=$(dirname "$(realpath -m "${XENDIR}")")
XENSUB=$(basename "$(realpath -m "${XENDIR}")")
cat <<EOF >> "${destdir}/conf/local.conf"
# Use local sources for xen and xen-tools
FILESEXTRAPATHS:prepend:pn-xen := "${XENBASE}:"
FILESEXTRAPATHS:prepend:pn-xen-tools := "${XENBASE}:"
SRC_URI:pn-xen = "file://${XENSUB}/;subdir=local-xen/"
SRC_URI:pn-xen-tools = "file://${XENSUB}/;subdir=local-xen/"
S:pn-xen = "\${WORKDIR}/local-xen/${XENSUB}"
S:pn-xen-tools = "\${WORKDIR}/local-xen/${XENSUB}"
SRCPV:pn-xen = "1"
SRCPV:pn-xen-tools = "1"
EOF
fi
}
function project_build() {
target="${1:?}"
destdir="${BUILDDIR}/${target}"
(
source "${YOCTODIR}/poky/oe-init-build-env" "${destdir}"
bitbake "${build_image}" || exit 1
if [ $do_copy = "y" ]
then
if [ $target = "qemuarm" ]
then
mkdir -p $OUTPUTDIR
cp $BUILDDIR/tmp/deploy/images/qemuarm/zImage $OUTPUTDIR
cp $BUILDDIR/tmp/deploy/images/qemuarm/xen-qemuarm $OUTPUTDIR
cp $BUILDDIR/tmp/deploy/images/qemuarm/xen-image-minimal-qemuarm.tar.bz2 $OUTPUTDIR
fi
fi
) || return 1
}
function project_clean() {
target="${1:?}"
destdir="${BUILDDIR}/${target}"
rm -rf "${destdir}"
}
function project_run() {
target="${1:?}"
destdir="${BUILDDIR}/${target}"
(
source "${YOCTODIR}/poky/oe-init-build-env" "${destdir}" > /dev/null 2>&1
/usr/bin/expect <<EOF
set timeout 1000
spawn bash -c "runqemu serialstdio nographic slirp"
expect_after {
-re "(.*)\r" {
exp_continue
}
timeout {send_user "ERROR-Timeout!\n"; exit 1}
eof {send_user "ERROR-EOF!\n"; exit 1}
}
# wait initial login
expect -re ".* login: "
send "root\r"
expect -re "root@.*# "
EOF
exit $?
) || return 1
}
function help() {
cat <<EOF
Usage: ${0} [TARGET1] [TARGET2]
This script is build the yocto xen-image-minimal for different qemu targets
and is running it after.
Without any target specified, all supported targets are done.
Options:
-h, --help Print this help
-v, --verbose Verbose build
--list-target List supported targets
--clean Clean existing project before starting
--no-build Do not build (to run an already built project)
--no-run Do not run
--num-jobs=NUM Define the number of parallel jobs in Yocto.
Default: ${BUILDJOBS}
--dump-log On error, dump the logs on the console
--image=IMG Yocto image or package to build
Default: xen-image-minimal
--xen-dir=DIR path to xen hypervisor source tree
if not provide, normal yocto version of xen is built
Default: ${XENDIR}
--out-dir=DIR directory where to create the projectss
Default: ${BUILDDIR}
--log-dir=DIR directory to store logs
Default: ${LOGDIR}
--cache-dir=DIR directory where to take and store build cache
Default: ${CACHEDIR}
--layer-dir=DIR directory containing the checkout of yocto layers
Default: ${YOCTODIR}
--copy-output Copy output binaries to binaries/
EOF
}
for OPTION in "$@"
do
case ${OPTION} in
-h|--help)
help
exit 0
;;
-v|--verbose)
VERBOSE="y"
;;
--list-targets)
echo "${TARGET_SUPPORTED}"
exit 0
;;
--clean)
do_clean="y"
;;
--no-build)
do_build="n"
;;
--no-run)
do_run="n"
;;
--dump-log)
do_dump="y"
;;
--num-jobs=*)
BUILDJOBS="${OPTION#*=}"
;;
--image=*)
build_image="${OPTION#*=}"
;;
--xen-dir=*)
XENDIR="${OPTION#*=}"
if [ ! -e "${XENDIR}/xen/Makefile" ]; then
echo "No Xen source tree in ${XENDIR}"
exit 1
fi
do_localsrc="y"
;;
--out-dir=*)
BUILDDIR="${OPTION#*=}"
;;
--log-dir=*)
LOGDIR="${OPTION#*=}"
;;
--cache-dir=*)
CACHEDIR="${OPTION#*=}"
;;
--layer-dir=*)
YOCTODIR="${OPTION#*=}"
;;
--copy-output)
do_copy="y"
;;
--*)
echo "Invalid option ${OPTION}"
help
exit 1
;;
*)
if echo "${TARGET_SUPPORTED}" | grep -q -w "${OPTION}"; then
TARGETLIST="${TARGETLIST} ${OPTION}"
else
echo "Unsupported target ${OPTION}"
exit 1
fi
;;
esac
done
# if no target is specified build all targets
if [ -z "${TARGETLIST}" ]; then
TARGETLIST="${TARGET_SUPPORTED}"
fi
mkdir -p "${CACHEDIR}"
mkdir -p "${LOGDIR}"
mkdir -p "${BUILDDIR}"
# Make sure we have an absolute path
YOCTODIR=$(realpath -m "${YOCTODIR}")
CACHEDIR=$(realpath -m "${CACHEDIR}")
BUILDDIR=$(realpath -m "${BUILDDIR}")
LOGDIR=$(realpath -m "${LOGDIR}")
if [ "${do_localsrc}" = "y" ]; then
XENDIR=$(realpath -m "${XENDIR}")
fi
# Check that we have all the layers we need
for f in ${build_layerlist}; do
if [ ! -f "${YOCTODIR}/${f}/conf/layer.conf" ]; then
echo "Layer ${f} missing in ${YOCTODIR}"
exit 1
fi
done
for f in ${TARGETLIST}; do
if [ "${do_clean}" = "y" ]; then
run_task project_clean "${f}"
fi
if [ ! -f "${BUILDDIR}/${f}/conf/local.conf" ]; then
run_task project_create "${f}"
fi
if [ -f "${BUILDDIR}/${f}/conf/local.conf" ]; then
if [ "${do_build}" = "y" ]; then
run_task project_build "${f}"
fi
if [ "${do_run}" = "y" ]; then
run_task project_run "${f}"
fi
fi
done
print_progress "Build Complete (${build_result} errors)"
echo
exit ${build_result}