1b1994897Sopenharmony_ci#!/bin/bash
2b1994897Sopenharmony_ci# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3b1994897Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
4b1994897Sopenharmony_ci# you may not use this file except in compliance with the License.
5b1994897Sopenharmony_ci# You may obtain a copy of the License at
6b1994897Sopenharmony_ci#
7b1994897Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0
8b1994897Sopenharmony_ci#
9b1994897Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
10b1994897Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
11b1994897Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1994897Sopenharmony_ci# See the License for the specific language governing permissions and
13b1994897Sopenharmony_ci# limitations under the License.
14b1994897Sopenharmony_ci
15b1994897Sopenharmony_ci#
16b1994897Sopenharmony_ci# Default argument values
17b1994897Sopenharmony_ci#
18b1994897Sopenharmony_ci
19b1994897Sopenharmony_ciQEMU_VERSION='6.2.0'
20b1994897Sopenharmony_ciDEFAULT_QEMU_PREFIX="/opt/qemu-$QEMU_VERSION"
21b1994897Sopenharmony_ciQEMU_PREFIX="$DEFAULT_QEMU_PREFIX"
22b1994897Sopenharmony_ci
23b1994897Sopenharmony_ci#
24b1994897Sopenharmony_ci# Aux functions
25b1994897Sopenharmony_ci#
26b1994897Sopenharmony_ci
27b1994897Sopenharmony_cifunction print_help
28b1994897Sopenharmony_ci{
29b1994897Sopenharmony_ci    HELP_MESSAGE="
30b1994897Sopenharmony_ci    It is the script for replacing packaged QEMU with vanilla QEMU $QEMU_VERSION
31b1994897Sopenharmony_ci    downloaded from the official QEMU web site. We need to provide a
32b1994897Sopenharmony_ci    replacement because:
33b1994897Sopenharmony_ci
34b1994897Sopenharmony_ci    1) Packaged QEMU contains bugs that hurt ARK unit tests.
35b1994897Sopenharmony_ci    2) Versions prior to $QEMU_VERSION do not play well with gdb-multiarch
36b1994897Sopenharmony_ci       (at least under Ubuntu 18.04).
37b1994897Sopenharmony_ci
38b1994897Sopenharmony_ci    The script should be run with superuser privileges.
39b1994897Sopenharmony_ci
40b1994897Sopenharmony_ci    EXAMPLE
41b1994897Sopenharmony_ci
42b1994897Sopenharmony_ci    $ ./scripts/install-deps-qemu --help
43b1994897Sopenharmony_ci    $ ./scripts/install-deps-qemu --qemu-prefix=/usr/local
44b1994897Sopenharmony_ci
45b1994897Sopenharmony_ci    SYNOPSIS
46b1994897Sopenharmony_ci
47b1994897Sopenharmony_ci    $0 [OPTIONS]
48b1994897Sopenharmony_ci
49b1994897Sopenharmony_ci    OPTIONS
50b1994897Sopenharmony_ci
51b1994897Sopenharmony_ci    --help, -h            Show this message and exit.
52b1994897Sopenharmony_ci
53b1994897Sopenharmony_ci    --qemu-prefix=PREFIX  Installation prefix for QEMU [$DEFAULT_QEMU_PREFIX].
54b1994897Sopenharmony_ci
55b1994897Sopenharmony_ci    CAVEATS
56b1994897Sopenharmony_ci
57b1994897Sopenharmony_ci    After QEMU is installed, the script attempts to symlink all files
58b1994897Sopenharmony_ci    from PREFIX/bin/qemu-* to /usr/bin. If other qemu binaries (or symlinks)
59b1994897Sopenharmony_ci    are already present in /usr/bin, they are left intact.
60b1994897Sopenharmony_ci
61b1994897Sopenharmony_ci    "
62b1994897Sopenharmony_ci
63b1994897Sopenharmony_ci    echo "$HELP_MESSAGE"
64b1994897Sopenharmony_ci}
65b1994897Sopenharmony_ci
66b1994897Sopenharmony_cifunction assert_root
67b1994897Sopenharmony_ci{
68b1994897Sopenharmony_ci    if [[ $(id -u) -ne 0 ]] ; then
69b1994897Sopenharmony_ci        echo "FATAL: Please run as root."
70b1994897Sopenharmony_ci        exit 1
71b1994897Sopenharmony_ci    fi
72b1994897Sopenharmony_ci}
73b1994897Sopenharmony_ci
74b1994897Sopenharmony_cifunction assert_ubuntu
75b1994897Sopenharmony_ci{
76b1994897Sopenharmony_ci    if [ ! -f /etc/os-release ]; then
77b1994897Sopenharmony_ci        echo "FATAL: /etc/os-release not found. Exiting..."
78b1994897Sopenharmony_ci        exit 1
79b1994897Sopenharmony_ci    fi
80b1994897Sopenharmony_ci
81b1994897Sopenharmony_ci    . /etc/os-release
82b1994897Sopenharmony_ci    if [[ "$NAME" != "Ubuntu" ]]; then
83b1994897Sopenharmony_ci        echo "FATAL: Only Ubuntu is supported. This is not. Exiting..."
84b1994897Sopenharmony_ci        exit 1
85b1994897Sopenharmony_ci    fi
86b1994897Sopenharmony_ci}
87b1994897Sopenharmony_ci
88b1994897Sopenharmony_cifunction install_vanilla_qemu
89b1994897Sopenharmony_ci{
90b1994897Sopenharmony_ci    local prefix="$1"
91b1994897Sopenharmony_ci    local qemu_name="qemu-$QEMU_VERSION"
92b1994897Sopenharmony_ci    local arch_name="$qemu_name.tar.xz"
93b1994897Sopenharmony_ci    local src_path="$prefix/src"
94b1994897Sopenharmony_ci    local arch_full="$src_path/$arch_name"
95b1994897Sopenharmony_ci
96b1994897Sopenharmony_ci    apt-get update
97b1994897Sopenharmony_ci
98b1994897Sopenharmony_ci    # Packages taken from: https://wiki.qemu.org/Hosts/Linux
99b1994897Sopenharmony_ci    apt-get install -y --no-install-recommends -o Dpkg::Options::="--force-overwrite" \
100b1994897Sopenharmony_ci        libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev \
101b1994897Sopenharmony_ci        curl tar ninja-build
102b1994897Sopenharmony_ci
103b1994897Sopenharmony_ci    mkdir -p "$src_path"
104b1994897Sopenharmony_ci    curl --retry 5 --retry-delay 0 -L "https://download.qemu.org/$arch_name" -o "$arch_full"
105b1994897Sopenharmony_ci
106b1994897Sopenharmony_ci    tar xfJ "$arch_full" -C "$src_path"
107b1994897Sopenharmony_ci
108b1994897Sopenharmony_ci    pushd "$src_path/$qemu_name"
109b1994897Sopenharmony_ci        ./configure --prefix="$prefix"
110b1994897Sopenharmony_ci        ninja -C ./build test
111b1994897Sopenharmony_ci        ninja -C ./build install
112b1994897Sopenharmony_ci    popd
113b1994897Sopenharmony_ci
114b1994897Sopenharmony_ci    # Try to symlink binaries to /usr/bin:
115b1994897Sopenharmony_ci    for fname in "$prefix"/bin/qemu-*; do
116b1994897Sopenharmony_ci        local lname="/usr/bin/$(basename "$fname")"
117b1994897Sopenharmony_ci        if [[ ! -f "$lname" ]]; then
118b1994897Sopenharmony_ci            ln -s "$fname" "$lname"
119b1994897Sopenharmony_ci        else
120b1994897Sopenharmony_ci            echo "WARNING: Unable to symlink $fname to $lname: $lname already exists"
121b1994897Sopenharmony_ci        fi
122b1994897Sopenharmony_ci    done
123b1994897Sopenharmony_ci}
124b1994897Sopenharmony_ci
125b1994897Sopenharmony_ci#
126b1994897Sopenharmony_ci# Main logic
127b1994897Sopenharmony_ci#
128b1994897Sopenharmony_ci
129b1994897Sopenharmony_ci#
130b1994897Sopenharmony_ci# Parse command-line arguments
131b1994897Sopenharmony_ci#
132b1994897Sopenharmony_ci
133b1994897Sopenharmony_cifor i in "$@"
134b1994897Sopenharmony_cido
135b1994897Sopenharmony_ci    case $i in
136b1994897Sopenharmony_ci    -h|--help)
137b1994897Sopenharmony_ci        print_help
138b1994897Sopenharmony_ci        exit 0
139b1994897Sopenharmony_ci        ;;
140b1994897Sopenharmony_ci    --qemu-prefix=*)
141b1994897Sopenharmony_ci        QEMU_PREFIX=${i//[-a-zA-Z0-9]*=/}
142b1994897Sopenharmony_ci      ;;
143b1994897Sopenharmony_ci    *)
144b1994897Sopenharmony_ci      echo "Error: Unsupported flag $i" >&2
145b1994897Sopenharmony_ci      exit 1
146b1994897Sopenharmony_ci      ;;
147b1994897Sopenharmony_ci  esac
148b1994897Sopenharmony_cidone
149b1994897Sopenharmony_ci
150b1994897Sopenharmony_ciassert_root
151b1994897Sopenharmony_ciassert_ubuntu
152b1994897Sopenharmony_ci
153b1994897Sopenharmony_ciqemu_installed_version=$(qemu-aarch64 --version 2>/dev/null \
154b1994897Sopenharmony_ci    | grep -Eo 'version [[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+' \
155b1994897Sopenharmony_ci    | head -n1)
156b1994897Sopenharmony_ciif [[ "$qemu_installed_version" == "" ]]; then
157b1994897Sopenharmony_ci    qemu_installed_version=$($QEMU_PREFIX/bin/qemu-aarch64 --version 2>/dev/null \
158b1994897Sopenharmony_ci        | grep -Eo 'version [[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+' \
159b1994897Sopenharmony_ci        | head -n1)
160b1994897Sopenharmony_cifi
161b1994897Sopenharmony_ci
162b1994897Sopenharmony_ciqemu_expected_version="version $QEMU_VERSION"
163b1994897Sopenharmony_ci
164b1994897Sopenharmony_ciif [[ "$qemu_installed_version" == "$qemu_expected_version" ]]; then
165b1994897Sopenharmony_ci    echo "Found expected QEMU $QEMU_VERSION, nothing to do"
166b1994897Sopenharmony_ci    exit 0
167b1994897Sopenharmony_cifi
168b1994897Sopenharmony_ci
169b1994897Sopenharmony_ciif [[ "$qemu_installed_version" == "" ]]; then
170b1994897Sopenharmony_ci    echo "No installed QEMU found"
171b1994897Sopenharmony_cielse
172b1994897Sopenharmony_ci    echo "Found installed QEMU $qemu_installed_version"
173b1994897Sopenharmony_cifi
174b1994897Sopenharmony_ci
175b1994897Sopenharmony_ciset -e
176b1994897Sopenharmony_ciinstall_vanilla_qemu "$QEMU_PREFIX"
177b1994897Sopenharmony_ci
178b1994897Sopenharmony_ciexit 0
179b1994897Sopenharmony_ci
180