blob: 7fd342d7d44511ba9dbf7e34aa6e846ccf48aeae [file] [log] [blame]
#!/usr/bin/env bash
# Copyright 2019 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT
set -o pipefail
# exit when any command fails
set -e
declare -r TERMINA_GUEST_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
declare -r FUCHSIA_DIR="${TERMINA_GUEST_DIR}/../../../../"
# The revision of Termina to build. The latest build revision can be read
# from:
#
# https://storage.googleapis.com/chromeos-image-archive/{tatl|tael}-full/LATEST-master
declare -r TERMINA_REVISION=R109-15236.B
# Cross compile filed used for building 32bit Vulkan ICD
meson_cross_file="
[binaries]
c = '/usr/bin/gcc'
cpp = '/usr/bin/g++'
ar = '/usr/bin/gcc-ar'
strip = '/usr/bin/strip'
pkgconfig = '/usr/bin/pkg-config'
llvm-config = '/usr/bin/llvm-config32'
[properties]
c_args = ['-m32']
c_link_args = ['-m32']
cpp_args = ['-m32']
cpp_link_args = ['-m32']
[host_machine]
system = 'linux'
cpu_family = 'x86'
cpu = 'i686'
endian = 'little'"
print_usage_and_exit() {
echo "Build Termina images for Machina."
echo ""
echo "Usage:"
echo " update_cipd_prebuilts.sh work_dir (x64|arm64) [-t target] [-n] [-f]"
echo ""
echo "Where:"
echo " work_dir - An empty directory to place source trees and build artifacts."
echo " Note: script may generate contents of ~125 GB"
echo ""
echo " -t target - An optional target: all,clean,debian,angle,termina"
echo ""
echo " -n Dry run. Don't actually upload anything, just show what would be"
echo " uploaded."
echo ""
echo " -f Force. Script will refuse to upload unless this flag is specified."
echo ""
echo "NOTE: incremental builds are partially supported, use with caution."
exit $1
}
check_depot_tools() {
type -P cros_sdk &>/dev/null && return 0
echo "ChromeOS depot_tools not found"
echo ""
echo "This script requires a ChromeOS workspace to run. For setup instructions,"
echo "see:"
echo " https://sites.google.com/a/chromium.org/dev/chromium-os/quick-start-guide"
exit 1
}
board_for_arch() {
case "${1}" in
arm64)
echo tael ;;
x64)
echo tatl ;;
*)
>&2 echo "Unsupported arch ${1}; should be one of x64, arm64";
exit -1;;
esac
}
create_cros_tree() {
local -r cros_dir="$1"
local -r termina_revision="$2"
local -r mesa_branch="$3"
if [ -d ${cros_dir} ]; then
return
fi
mkdir -p "${cros_dir}"
pushd "${cros_dir}"
repo init -u https://chrome-internal.googlesource.com/chromeos/manifest-internal -b release-"${termina_revision}"
repo sync -j8
(cd src/overlays; git remote update; git checkout "cros/release-${termina_revision}-test-magma")
(cd src/third_party/chromiumos-overlay; git remote update; git checkout "cros/release-${termina_revision}-test-magma")
(cd src/platform2; git remote update; git checkout "cros/release-${termina_revision}-test-magma")
# Apply patches to termina temporarily
(cd src/platform/tremplin; git fetch https://chromium.googlesource.com/chromiumos/platform/tremplin refs/changes/34/3302234/1 && git cherry-pick FETCH_HEAD)
# Switch to Fuchsia's mesa branch
(cd src/third_party/mesa && \
git config remote.fuchsia.url >&- || \
git remote add fuchsia https://fuchsia.googlesource.com/third_party/mesa && \
git remote update fuchsia && \
git checkout fuchsia/${mesa_branch})
git clone https://fuchsia.googlesource.com/fuchsia src/third_party/fuchsia
cros_sdk bash -c "setup_board --board=${board}"
# Switch to source build for mesa
cros_sdk bash -c "cros_workon --board=${board} start mesa"
# Switch to source build of sommelier
cros_sdk bash -c "cros_workon --board=${board} start sommelier"
# Switch to source build of magma
cros_sdk bash -c "cros_workon --board=${board} start magma"
# Switch to source build of tremplin
cros_sdk bash -c "cros_workon --board=${board} start tremplin"
popd
}
build_debian_drivers() {
local -r debian_dir="$1"
local -r arch="$2"
local -r mesa_branch="$3"
if [ "${arch}" != "x64" ]; then
echo "Debian build only supports x64"
fi
local chroot_dir="${debian_dir}/chroot"
if [ ! -d ${debian_dir} ]; then
mkdir -p ${debian_dir}/src
sudo debootstrap --arch amd64 bullseye ${chroot_dir} http://deb.debian.org/debian
# Bind mount sources into chroot so we can edit as regular user outside the chroot
sudo mkdir ${chroot_dir}/src
sudo mount --bind ${debian_dir}/src ${chroot_dir}/src
sudo chroot ${chroot_dir} bash -c "dpkg --add-architecture i386"
sudo chroot ${chroot_dir} bash -c "apt update"
sudo chroot ${chroot_dir} bash -c "apt install --yes git gcc-multilib g++-multilib meson \
python3-setuptools python3-mako rapidjson-dev googletest libvulkan-dev libvulkan-dev:i386 \
pkg-config bison flex libwayland-dev libwayland-dev:i386 wayland-protocols \
libwayland-egl-backend-dev libwayland-egl-backend-dev:i386 libdrm-dev libdrm-dev:i386 \
libxrandr-dev libxrandr-dev:i386 libdrm-dev libdrm-dev:i386 libx11-xcb-dev \
libx11-xcb-dev:i386 libxcb-dri2-0-dev libxcb-dri2-0-dev:i386 libxcb-dri3-dev \
libxcb-dri3-dev:i386 libxcb-present-dev libxcb-present-dev:i386 libxcb-randr0 \
libxcb-randr0:i386 libxcb-shm0 libxcb-shm0:i386 libxshmfence-dev libxshmfence-dev:i386 \
zlib1g-dev zlib1g-dev:i386 libxfixes-dev libxfixes-dev:i386 libxcb-glx0-dev \
libxcb-glx0-dev:i386 libxcb-shm0-dev libxcb-shm0-dev:i386 libxxf86vm-dev libxxf86vm-dev:i386 \
libpciaccess-dev libpciaccess-dev:i386"
prefix="/src/out/install"
mkdir -p ${debian_dir}${prefix}
echo "${meson_cross_file}" > ${debian_dir}/src/crossfile
# For dependencies that are newer than the system provided, build from source
git clone https://gitlab.freedesktop.org/wayland/wayland-protocols -b 1.24 ${debian_dir}/src/wayland-protocols
git clone https://gitlab.freedesktop.org/mesa/drm.git -b libdrm-2.4.109 ${debian_dir}/src/drm
sudo chroot ${chroot_dir} bash -c "meson --prefix=${prefix} /src/wayland-protocols /src/out/wayland-protocols"
sudo chroot ${chroot_dir} bash -c "ninja -C /src/out/wayland-protocols install"
sudo chroot ${chroot_dir} bash -c "meson --prefix=${prefix} /src/drm /src/out/drm/build64"
sudo chroot ${chroot_dir} bash -c "ninja -C /src/out/drm/build64 install"
sudo chroot ${chroot_dir} bash -c "PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig \
meson --cross-file /src/crossfile --prefix=${prefix} /src/drm /src/out/drm/build32"
sudo chroot ${chroot_dir} bash -c "ninja -C /src/out/drm/build32 install"
# Mesa for Vulkan ICD build and Fuchsia dependency
git clone https://fuchsia.googlesource.com/third_party/mesa -b ${mesa_branch} ${debian_dir}/src/mesa
git clone https://fuchsia.googlesource.com/fuchsia ${debian_dir}/src/mesa/subprojects/fuchsia
# Mesa for Zink
git clone https://fuchsia.googlesource.com/third_party/mesa -b sandbox/zink-magma ${debian_dir}/src/zink
mkdir -p ${debian_dir}/src/out/mesa/build64
mkdir -p ${debian_dir}/src/out/mesa/build32
(cd ${debian_dir}/src/mesa/subprojects/fuchsia && ln -s src/graphics/lib/magma/meson-top/meson.build meson.build)
(cd ${debian_dir}/src/mesa/subprojects/fuchsia && ln -s src/graphics/lib/magma/meson-top/meson_options.txt meson_options.txt)
sudo chroot ${chroot_dir} bash -c "PKG_CONFIG_PATH=${prefix}/lib64/pkgconfig:${prefix}/share/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig \
meson --buildtype release /src/out/mesa/build64 /src/mesa \
-Ddriver-backend=magma \
-Ddri-drivers= \
-Dgallium-drivers= \
-Dvulkan-drivers=intel \
-Dgles1=disabled \
-Dgles2=disabled \
-Dopengl=false \
-Dgbm=enabled \
-Degl=disabled \
-Dprefix=/usr"
sudo chroot ${chroot_dir} bash -c "PKG_CONFIG_PATH=${prefix}/lib/pkgconfig:${prefix}/share/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig \
meson --cross-file /src/crossfile --buildtype release /src/out/mesa/build32 /src/mesa \
-Ddriver-backend=magma \
-Ddri-drivers= \
-Dgallium-drivers= \
-Dvulkan-drivers=intel \
-Dgles1=disabled \
-Dgles2=disabled \
-Dopengl=false \
-Dgbm=disabled \
-Degl=disabled \
-Dprefix=/usr \
-Dlibdir=lib/i386-linux-gnu"
sudo chroot ${chroot_dir} bash -c "PKG_CONFIG_PATH=${prefix}/lib64/pkgconfig:${prefix}/share/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig \
meson --buildtype release /src/zink /src/out/zink/build64 \
-Ddrm-stubs=true \
-Ddri-drivers= \
-Dgallium-drivers=zink \
-Dvulkan-drivers= \
-Dgles1=enabled \
-Dgles2=enabled \
-Dopengl=true \
-Dgbm=disabled \
-Degl=enabled \
-Dprefix=/usr \
-Dlibdir=lib/x86_64-linux-gnu \
-Ddri-search-path=/opt/google/cros-containers/drivers/lib64/dri \
-Dsysconfdir=/opt/google/cros-containers/drivers/etc"
sudo chroot ${chroot_dir} bash -c "PKG_CONFIG_PATH=${prefix}/lib/pkgconfig:${prefix}/share/pkgconfig:/usr/lib/i386-linux-gnu/pkgconfig \
meson --cross-file /src/crossfile --buildtype release /src/zink /src/out/zink/build32 \
-Ddrm-stubs=true \
-Ddri-drivers= \
-Dgallium-drivers=zink \
-Dvulkan-drivers= \
-Dgles1=enabled \
-Dgles2=enabled \
-Dopengl=true \
-Dgbm=disabled \
-Degl=enabled \
-Dprefix=/usr \
-Dlibdir=lib/i386-linux-gnu \
-Ddri-search-path=/opt/google/cros-containers/drivers/lib32/dri \
-Dsysconfdir=/opt/google/cros-containers/drivers/etc"
fi
sudo chroot ${chroot_dir} bash -c "ninja -C /src/out/mesa/build32"
sudo chroot ${chroot_dir} bash -c "ninja -C /src/out/mesa/build64"
sudo chroot ${chroot_dir} bash -c "ninja -C /src/out/zink/build64"
sudo chroot ${chroot_dir} bash -c "ninja -C /src/out/zink/build32"
}
copy_debian_drivers() {
local -r debian_dir="$1"
local -r dest_dir="$2"
mkdir -p "${dest_dir}/lib64"
cp -fv "${debian_dir}/src/out/mesa/build64/src/intel/vulkan/libvulkan_intel.so" "${dest_dir}/lib64"
cp -fv "${debian_dir}/src/out/mesa/build64/src/gbm/libgbm.so.1.0.0" "${dest_dir}/lib64"
mkdir -p "${dest_dir}/meta"
cp -fv "${debian_dir}/src/out/mesa/build64/src/intel/vulkan/intel_icd.x86_64.json" "${dest_dir}/meta"
cp -fv "${debian_dir}/src/out/zink/build64/src/gallium/targets/dri/libgallium_dri.so" "${dest_dir}/lib64/zink_dri.so"
cp -fv "${debian_dir}/src/out/zink/build64/src/glx/libGL.so.1.2.0" "${dest_dir}/lib64"
cp -fv "${debian_dir}/src/out/zink/build64/src/egl/libEGL.so.1.0.0" "${dest_dir}/lib64"
cp -fv "${debian_dir}/src/out/zink/build64/src/mapi/es2api/libGLESv2.so.2.0.0" "${dest_dir}/lib64"
mkdir -p "${dest_dir}/lib32"
cp -fv "${debian_dir}/src/out/mesa/build32/src/intel/vulkan/libvulkan_intel.so" "${dest_dir}/lib32"
mkdir -p "${dest_dir}/meta"
cp -fv "${debian_dir}/src/out/mesa/build32/src/intel/vulkan/intel_icd.i686.json" "${dest_dir}/meta"
cp -fv "${debian_dir}/src/out/zink/build32/src/gallium/targets/dri/libgallium_dri.so" "${dest_dir}/lib32/zink_dri.so"
cp -fv "${debian_dir}/src/out/zink/build32/src/glx/libGL.so.1.2.0" "${dest_dir}/lib32"
cp -fv "${debian_dir}/src/out/zink/build32/src/egl/libEGL.so.1.0.0" "${dest_dir}/lib32"
cp -fv "${debian_dir}/src/out/zink/build32/src/mapi/es2api/libGLESv2.so.2.0.0" "${dest_dir}/lib32"
}
build_angle() {
local -r angle_dir="$1"
local -r arch="$2"
[ ! -d "${angle_dir}" ] && git clone https://chromium.googlesource.com/angle/angle "${angle_dir}"
pushd "${angle_dir}"
fuchsia-vendored-python scripts/bootstrap.py
gclient sync
build/linux/sysroot_scripts/install-sysroot.py --arch=${arch}
gn gen out --args="\
is_debug=false \
target_cpu=\"${arch}\" \
target_os=\"linux\" \
ozone_platform_x11=true \
use_ozone=true \
angle_enable_trace=false \
angle_enable_d3d9=false \
angle_enable_d3d11=false \
angle_enable_gl=false \
angle_enable_metal=false \
angle_enable_null=false \
angle_enable_vulkan=true \
angle_enable_essl=false \
angle_enable_glsl=false \
angle_build_all=true \
angle_enable_swiftshader=false \
angle_use_custom_libvulkan=false \
angle_egl_extension=\"so.1\" \
angle_glesv2_extension=\"so.2\""
ninja -C out angle gles2_torus_lighting
popd
}
# Builds the Termina image, for details see:
# https://chromium.googlesource.com/chromiumos/overlays/board-overlays/+/main/project-termina/#building
#
# $1 - Architecture (x64 or arm64).
# $2 - Path to a ChromeOS workspace.
build_termina_image() {
local -r arch="$1"
local -r cros_dir="$2"
local -r board="`board_for_arch ${arch}`"
# Note that the references to $HOME here will be resoved inside the ChromeOS
# chroot and not the current users $HOME. This is because the ChromeOS build
# system relies on doing a chroot into a sysroot to support the build. This
# is handled by the 'cros_sdk' command below.
local -r chroot_outdir="~/termina-${board}-image"
local -r input_image="~/trunk/src/build/images/${board}/latest/chromiumos_base_image.bin"
pushd "${cros_dir}"
# Not needed for clean build but ensure that any of the prebuilts are picked up
# For debug: preface with FEATURES=\"nostrip noclean -splitdebug\"
cros_sdk bash -c "emerge-${board} termina_container_tools"
# Build chromeos image
cros_sdk bash -c "./build_packages --board=${board} --nowithautotest && \
./build_image --board=${board} --noenable_rootfs_verification base"
# Extract Termina from chromeos image
cros_sdk bash -c "sudo rm -rf ${chroot_outdir} && \
sudo ~/trunk/src/platform/container-guest-tools/termina/termina_build_image.py ${input_image} ${chroot_outdir}"
popd
}
build_extras_image() {
local -r extras_dir="$1"
local -r image_file="$2"
declare -r BLOCK_SIZE=4096
declare -r ADDITIONAL_BLOCKS=1024
declare -r SIZE=$(du -sb ${extras_dir} | grep -o '^[0-9]*')
declare -r BLOCKS=$(($((${SIZE}/${BLOCK_SIZE}))+${ADDITIONAL_BLOCKS}))
rm -f "${image_file}"
mke2fs -q -d "${extras_dir}" -t ext2 -b ${BLOCK_SIZE} "${image_file}" ${BLOCKS}
}
main() {
if [[ $# < 2 ]]; then
print_usage_and_exit
fi
work_dir="$1"
shift
arch="$1"
shift
if [[ "${arch}" != "x64" && "${arch}" != "arm64" ]]; then
echo "Expected x64 or arm64, got: ${arch}"
print_usage_and_exit
fi
target="all"
mesa_branch="main"
while getopts "nft:m:h" FLAG; do
case "${FLAG}" in
n) dry_run=true ;;
f) force=true ;;
h) print_usage_and_exit 0 ;;
t) target=${OPTARG} ;;
m) mesa_branch=${OPTARG} ;;
*) print_usage_and_exit 1 ;;
esac
done
shift $((OPTIND - 1))
if [[ ! -d "${work_dir}" ]]; then
echo "Work directory doesn't exist: ${work_dir}"
exit 1
fi
if [[ "${target}" != "all" && "${target}" != "debian" && "${target}" != "angle" && "${target}" != "termina" && "${target}" != "clean" ]]; then
print_usage_and_exit 1
fi
echo "Working on target ${target} in ${work_dir}..."
declare -r cipd="${FUCHSIA_DIR}/.jiri_root/bin/cipd"
declare -r dry_run=${dry_run}
declare -r force=${force}
declare jiri_entries=" <!-- termina guest images -->"
# Ensure one of "dry-run" or "force" is given.
if [ "$dry_run" == "$force" ];
then
print_usage_and_exit 1
fi
check_depot_tools
board=`board_for_arch ${arch}`
termina_revision=$TERMINA_REVISION
jiri_entries="${jiri_entries}
<package name=\"fuchsia_internal/linux/termina-${arch}\"
version=\"<insert-instance-ID-here>\"
path=\"prebuilt/virtualization/packages/termina_guest/images/${arch}\"
internal=\"true\"/>"
if [ "${target}" == "all" ]; then
echo "*** Prepare chromeos tree"
create_cros_tree "${work_dir}/cros" "${termina_revision}" "${mesa_branch}"
fi
if [[ "${target}" == "all" || "${target}" == "debian" ]]; then
if [ "${arch}" == "x64" ]; then
echo "*** Prepare debian and build"
build_debian_drivers "${work_dir}/debian" "${arch}" "${mesa_branch}"
echo "*** Copy debian drivers to chromeos tree"
dest_dir=${work_dir}/cros/src/third_party/chromiumos-overlay/chromeos-base/termina_container_tools/files/prebuilt-${arch}
copy_debian_drivers "${work_dir}/debian" "${dest_dir}"
fi
fi
if [[ "${target}" == "all" || "${target}" == "angle" ]]; then
echo "*** Prepare ANGLE and build"
build_angle "${work_dir}/angle" "${arch}"
# Tael board is 32bit userspace so we can't link in our 64bit libraries
if [ "${arch}" == "x64" ]; then
echo "*** Copy ANGLE outputs to chromeos tree"
dest_dir=${work_dir}/cros/src/third_party/chromiumos-overlay/chromeos-base/termina_container_tools/files/prebuilt-${arch}
mkdir -p "${dest_dir}/angle"
cp -fv "${work_dir}/angle/out/libEGL.so.1" "${dest_dir}/angle"
cp -fv "${work_dir}/angle/out/libGLESv2.so.2" "${dest_dir}/angle"
fi
fi
if [[ "${target}" == "all" || "${target}" == "termina" ]]; then
echo "*** Build Termina image"
build_termina_image "${arch}" "${work_dir}/cros"
echo "*** Copy Termina image"
cp -av "${work_dir}/cros/chroot/home/${USER}/termina-${board}-image" "${work_dir}"
echo "*** Build extras image"
local -r extras_dir="${work_dir}/extras-${arch}"
mkdir -p ${extras_dir}
cp -av ${work_dir}/cros/chroot/build/${board}/usr/bin/aplay ${extras_dir}
cp -av ${work_dir}/cros/chroot/build/${board}/usr/bin/arecord ${extras_dir}
build_extras_image "${extras_dir}" "${work_dir}/termina-${board}-image/vm_extras.img"
fi
if [[ "${target}" == "all" || "${target}" == "termina" ]]; then
options=()
options+=("create")
options+=("-in" "${work_dir}/termina-${board}-image")
options+=("-name" "fuchsia_internal/linux/termina-${arch}")
options+=("-install-mode" "copy")
options+=("-tag" "termina-custom:${termina_revision}")
echo cipd ${options[*]}
if [ "$dry_run" != true ] ; then
echo "*** Running CIPD - note the instance ID"
${cipd} ${options[*]}
echo "Update //integration/fuchsia/prebuilts with the following:"
echo "${jiri_entries}"
fi
fi
if [[ "${target}" == "clean" ]]; then
if [[ -d "${work_dir}/debian/chroot/src" ]]; then
sudo umount -q "${work_dir}/debian/chroot/src"
fi
sudo rm -rf ${work_dir}/*
fi
echo "*** Done"
}
main "$@"