1#!/bin/sh
2# Starts an isolated build in a container
3set -e
4
5ARCH="x86_64"
6FROM_EXISTING_SOURCES=0
7
8while [[ $# -gt 0 ]]; do
9  case $1 in
10    --arch)
11      ARCH="$2"
12      shift 2
13      ;;
14    --from_existing_sources)
15      FROM_EXISTING_SOURCES=1
16      shift
17      ;;
18    *)
19      echo "Build QEMU from sources in a container."
20      echo
21      echo "usage: $0 [--from_existing_sources] [--arch x86_64|aarch64]"
22      echo
23      echo "Options:"
24      echo "  --from_existing_sources: Do not checkout sources with repo,"
25      echo "    and do not copy the prebuild back to the source directory."
26      shift
27      exit 1
28      ;;
29  esac
30done
31
32readonly SCRIPT_DIR="$(realpath "$(dirname "$0")")"
33readonly GIT_ROOT="$(realpath "${SCRIPT_DIR}/../..")"
34readonly WORK_DIR="/tmp/qemu-build-output"
35
36echo "Clear the working directory: ${WORK_DIR}"
37rm -rf "${WORK_DIR}"
38mkdir -p "${WORK_DIR}"
39
40if [ "$FROM_EXISTING_SOURCES" -eq 0 ]; then
41  readonly SRC_DIR="${HOME}/qemu-build-checkout"
42  echo "Check out sources with repo at: ${SRC_DIR}"
43  rm -rf "${SRC_DIR}"
44  mkdir -p "${SRC_DIR}"
45  cd "${SRC_DIR}"
46  repo init --manifest-url "${GIT_ROOT}" \
47    --manifest-name=qemu/manifest.xml
48
49  repo sync
50else
51  readonly SRC_DIR="$GIT_ROOT"
52  echo "Reuse existing source checkout at: ${SRC_DIR}"
53fi
54
55readonly COMMON_APT_PACKAGES="autoconf libgbm-dev libtool texinfo"
56readonly AARCH64_APT_PACKAGES="clang cmake curl libc++-dev libc++abi-dev \
57  libegl-dev libgcc-12-dev libxml2-utils llvm make ninja-build \
58  patchelf pkg-config python3 python3-distutils python3-venv"
59
60APT_PACKAGES="${COMMON_APT_PACKAGES}"
61RUSTUP_COMMAND=":"
62PYTHON_BIN="/src/qemu/third_party/python/bin/python3"
63if [[ "$ARCH" == "aarch64" ]]; then
64  APT_PACKAGES="${APT_PACKAGES} ${AARCH64_APT_PACKAGES}"
65  RUSTUP_COMMAND="curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -q -y"
66  PYTHON_BIN="python3"
67fi
68
69readonly COMMAND="apt-get update && \
70apt-get -qy install ${APT_PACKAGES} && \
71${RUSTUP_COMMAND} && \
72${PYTHON_BIN} /src/qemu/scripts/rebuild.py --arch ${ARCH} --build-dir /out"
73
74# Note: `/src` is mounted with a file overlay so that cargo can write
75# `third_party/crossvm/rutabaga_gfx/ffi/Cargo.lock` file. We didn't find
76# a way to prevent cargo from writing it.
77
78podman run --name qemu-build \
79    --replace \
80    --pids-limit=-1 \
81    --volume "${SRC_DIR}:/src:O" \
82    --volume "${WORK_DIR}:/out" \
83    --arch ${ARCH} \
84    docker.io/debian:12-slim \
85    bash -c "${COMMAND}"
86
87# Tip: Use `--interactive`, `--tty` and
88# `bash -c "${COMMAND};$SHELL"` for interactive debug.
89
90if [ "$FROM_EXISTING_SOURCES" -eq 0 ]; then
91  readonly DEST="${GIT_ROOT}/qemu/${ARCH}-linux-gnu"
92  echo "Overwrite prebuilt at: ${DEST}"
93  rm -rf "${DEST}/*"
94  tar -xvf "${WORK_DIR}/qemu-portable.tar.gz" -C "${DEST}"
95
96fi
97
98echo "Binary available at: ${WORK_DIR}/qemu-portable/bin"
99echo "Done."
100