dev_container: Add riscv64 support

Because bullseye's cross packages for riscv64 are broken, libcap needs to
be manually built and installed, and pkg-config needs a hacky define to
allow minijail to find it. Other than that, it's very similar to the
other architectures.

Change-Id: I903f7ccd2ccbd94168ba09b425fd649458fdee70
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4460942
Reviewed-by: Dennis Kempin <denniskempin@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
diff --git a/.cargo/config.debian.toml b/.cargo/config.debian.toml
index 97fcae3..b43458b 100644
--- a/.cargo/config.debian.toml
+++ b/.cargo/config.debian.toml
@@ -16,7 +16,7 @@
 PKG_CONFIG_x86_64-unknown-linux-gnu = "x86_64-linux-gnu-pkg-config"
 PKG_CONFIG_aarch64-unknown-linux-gnu = "aarch64-linux-gnu-pkg-config"
 PKG_CONFIG_armv7_unknown_linux_gnueabihf = "arm-linux-gnueabihf-pkg-config"
-PKG_CONFIG_riscv64-unknown-linux-gnu = "riscv64-linux-gnu-pkg-config"
+PKG_CONFIG_riscv64gc_unknown_linux_gnu = "riscv64-linux-gnu-pkg-config"
 
 # libslirp is currently not properly configured via pkg-config and cannot use the wrapper like
 # other architextures do.
diff --git a/tools/impl/dev_container/Dockerfile b/tools/impl/dev_container/Dockerfile
index 56ea3ad..4d86955 100644
--- a/tools/impl/dev_container/Dockerfile
+++ b/tools/impl/dev_container/Dockerfile
@@ -42,17 +42,18 @@
 RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
 
 # Install dependencies (APT and cargo packages are cached between image builds for faster iterative builds).
-COPY --chmod=555 tools/install-deps tools/install-aarch64-deps tools/install-armhf-deps tools/install-mingw64-deps tools/setup-wine64 rust-toolchain /tools/
+COPY --chmod=555 tools/install-deps tools/install-aarch64-deps tools/install-armhf-deps tools/install-mingw64-deps tools/install-riscv64-deps tools/setup-wine64 rust-toolchain /tools/
 RUN --mount=type=cache,target=/var/cache/apt,sharing=private \
     --mount=type=cache,target=/var/lib/apt,sharing=private \
     --mount=type=cache,target=/scratch/cargo_target,sharing=private \
     cd /tools \
     && apt-get update \
-    && apt-get install --yes sudo \
+    && apt-get install --yes sudo curl \
     && ./install-deps \
     && ./install-aarch64-deps \
     && ./install-armhf-deps \
-    && ./install-mingw64-deps
+    && ./install-mingw64-deps \
+    && ./install-riscv64-deps
 
 # Add wine64 to PATH, as debian removed alternative entry to wine64
 ENV PATH=/usr/lib/wine:$PATH
diff --git a/tools/install-riscv64-deps b/tools/install-riscv64-deps
new file mode 100644
index 0000000..535c733
--- /dev/null
+++ b/tools/install-riscv64-deps
@@ -0,0 +1,60 @@
+#!/usr/bin/env bash
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+set -ex
+
+sudo apt-get install --yes --no-install-recommends \
+    binutils-riscv64-linux-gnu \
+    g++-riscv64-linux-gnu \
+    libc6-dev-riscv64-cross
+
+# Add riscv64gc target to Rust
+rustup target add riscv64gc-unknown-linux-gnu
+
+# Clone, patch, build and install libcap for riscv
+# TODO(dgreid) - remove this when the standard libcap:riscv64 package is
+# functional from the dev_container debian version. At time of writing there is
+# a disfunctional libc:riscv64 dependency that breaks the host libc in debian:buster.
+LIBCAP_DIR=$(mktemp -d)
+pushd "$LIBCAP_DIR" || exit 1
+
+# Define a function to clean up the temporary directory
+cleanup() {
+  rm -rf "$LIBCAP_DIR"
+}
+
+# Register the cleanup function to be called on script exit
+trap cleanup EXIT
+
+git clone --depth 1 --branch v1.2.53 https://git.kernel.org/pub/scm/libs/libcap/libcap.git
+cd libcap
+# Patch cross compile issue with libcap using target CC to build host tools.
+cat <<EOF >> libcap.patch
+diff --git a/Make.Rules b/Make.Rules
+index 125f2aa..a78c656 100644
+--- a/Make.Rules
++++ b/Make.Rules
+@@ -58,7 +58,7 @@ CC := \$(CROSS_COMPILE)gcc
+ DEFINES := -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+ COPTS ?= -O2
+ CFLAGS ?= \$(COPTS) \$(DEFINES)
+-BUILD_CC ?= \$(CC)
++BUILD_CC ?= gcc
+ BUILD_COPTS ?= -O2
+ BUILD_CFLAGS ?= \$(BUILD_COPTS) \$(DEFINES) \$(IPATH)
+ AR := \$(CROSS_COMPILE)ar
+EOF
+patch -p1 < libcap.patch
+
+make ARCH=riscv64 CROSS_COMPILE=riscv64-linux-gnu- GOLANG=no
+
+sudo cp libcap/libcap.so* libcap/libpsx.so* /usr/riscv64-linux-gnu/lib/
+sudo mkdir -p /usr/lib/riscv64-linux-gnu/pkgconfig
+sudo cp libcap/*.pc /usr/lib/riscv64-linux-gnu/pkgconfig/
+sudo mkdir -p /usr/riscv64-linux-gnu/usr/include/sys/
+sudo cp ./libcap/include/sys/capability.h /usr/riscv64-linux-gnu/usr/include/sys/
+
+sudo ln -f /usr/bin/pkg-config /usr/bin/riscv64-linux-gnu-pkg-config
+
+popd || exit 1