|
#!/bin/bash |
|
set -euo pipefail |
|
|
|
# Configuration |
|
KERNEL_VERSION=$(uname -r) |
|
OUTPUT_DIR="$HOME/waydroid/module/${KERNEL_VERSION}" |
|
MODULE_PATH="${OUTPUT_DIR}/binder_linux.ko" |
|
BASE_IMAGE="ghcr.io/steamdeckhomebrew/holo-base:latest" |
|
PREBUILT_IMAGE="local/holo-base-prepped:latest" |
|
MODULE_SOURCE="https://github.com/llyyr/anbox-modules" |
|
FORCE_MODULE=false |
|
FORCE_IMAGE=false |
|
|
|
# Parse arguments |
|
while getopts "fb" opt; do |
|
case $opt in |
|
f) FORCE_MODULE=true ;; |
|
b) FORCE_IMAGE=true ;; |
|
*) echo "Usage: $0 [-f] [-b]" |
|
echo "Options:" |
|
echo " -f Force rebuild module" |
|
echo " -b Force rebuild container image" |
|
exit 1 ;; |
|
esac |
|
done |
|
|
|
# Create output directory |
|
mkdir -p "${OUTPUT_DIR}" |
|
|
|
# --- Container Image Preparation --- |
|
echo "[INFO] Preparing container environment..." |
|
if [[ "$FORCE_IMAGE" == true ]]; then |
|
echo "[INFO] Forcing rebuild of pre-configured image..." |
|
echo "[INFO] Pulling latest base image..." |
|
if ! podman pull "$BASE_IMAGE"; then |
|
echo "[ERROR] Failed to pull base image" >&2 |
|
exit 1 |
|
fi |
|
podman rmi "$PREBUILT_IMAGE" 2>/dev/null || true |
|
fi |
|
|
|
if ! podman image exists "$PREBUILT_IMAGE" || [[ "$FORCE_IMAGE" == true ]]; then |
|
echo "[INFO] Building pre-configured image with custom pacman.conf..." |
|
|
|
BUILD_DIR=$(mktemp -d) |
|
cp /etc/pacman.conf "$BUILD_DIR/" |
|
|
|
cat > "$BUILD_DIR/Containerfile" <<EOF |
|
FROM $BASE_IMAGE |
|
COPY pacman.conf /etc/pacman.conf |
|
RUN pacman -Sy --noconfirm --needed archlinux-keyring && \ |
|
pacman -Syu --noconfirm --needed && \ |
|
yes | pacman -Scc && \ |
|
rm -rf /usr/share/{doc,info,man} |
|
EOF |
|
|
|
if ! podman build --squash -t "$PREBUILT_IMAGE" -f "$BUILD_DIR/Containerfile" "$BUILD_DIR"; then |
|
echo "[ERROR] Failed to build pre-configured image" >&2 |
|
rm -rf "$BUILD_DIR" |
|
exit 1 |
|
fi |
|
|
|
rm -rf "$BUILD_DIR" |
|
echo "[INFO] Pre-configured image ready" |
|
else |
|
echo "[INFO] Using existing pre-configured image" |
|
fi |
|
|
|
# --- Module Existence Check --- |
|
if [[ "$FORCE_MODULE" == false ]] && [[ -f "${MODULE_PATH}" ]]; then |
|
echo "[INFO] Module already exists at ${MODULE_PATH}, skipping compilation." |
|
echo "[INFO] Use -f to force module rebuild or -b to rebuild image." |
|
exit 0 |
|
fi |
|
|
|
# Verify output directory is writable |
|
if [[ ! -w "${OUTPUT_DIR}" ]]; then |
|
echo "[ERROR] Cannot write to output directory: ${OUTPUT_DIR}" >&2 |
|
exit 1 |
|
fi |
|
|
|
# --- Module Building --- |
|
KERNEL_PKG=$(basename /boot/vmlinuz-* | sed 's/vmlinuz-//') |
|
HEADERS_PKG="${KERNEL_PKG}-headers" |
|
|
|
echo "[INFO] Building module with kernel headers: ${HEADERS_PKG}" |
|
|
|
if ! podman run --rm \ |
|
--user 0 \ |
|
--security-opt label=disable \ |
|
--cap-add=SYS_MODULE \ |
|
-v /etc/pacman.conf:/tmp/pacman.conf:ro \ |
|
-v "${OUTPUT_DIR}:/output:z" \ |
|
-v /tmp:/tmp:z \ |
|
"$PREBUILT_IMAGE" \ |
|
/bin/bash -c " |
|
set -euo pipefail |
|
echo '[CONTAINER] Finalizing build environment...' |
|
|
|
# Replace pacman config |
|
install -m644 /tmp/pacman.conf /etc/pacman.conf |
|
|
|
# Update and install build tools |
|
pacman -Syu --noconfirm --needed |
|
pacman -S --noconfirm --needed base-devel git |
|
|
|
# Install kernel headers |
|
if ! pacman -S --noconfirm --needed ${HEADERS_PKG}; then |
|
echo '[ERROR] Failed to install kernel headers' >&2 |
|
echo '[INFO] Available headers packages:' |
|
pacman -Ss 'headers' || true |
|
exit 1 |
|
fi |
|
|
|
# Always clean previous build |
|
rm -rf /tmp/anbox-modules 2>/dev/null || true |
|
|
|
# Clone and build |
|
echo '[CONTAINER] Building binder module...' |
|
if ! git clone --depth 1 ${MODULE_SOURCE} /tmp/anbox-modules; then |
|
echo '[ERROR] Failed to clone repository' >&2 |
|
exit 1 |
|
fi |
|
|
|
cd /tmp/anbox-modules/binder || exit 1 |
|
if ! make; then |
|
echo '[ERROR] Build failed - showing last 50 lines of build log:' |
|
tail -n 50 /tmp/anbox-modules/binder/build.log 2>/dev/null || true |
|
exit 1 |
|
fi |
|
|
|
# Verify and copy output |
|
if [[ -f binder_linux.ko ]]; then |
|
install -m644 binder_linux.ko /output/ |
|
echo '[CONTAINER] Module built successfully' |
|
else |
|
echo '[ERROR] Module file not found after build' >&2 |
|
exit 1 |
|
fi |
|
"; then |
|
echo "[ERROR] Module build failed in container" >&2 |
|
exit 1 |
|
fi |
|
|
|
# Verify output |
|
if [[ -f "${MODULE_PATH}" ]]; then |
|
chown "$(id -u):$(id -g)" "${MODULE_PATH}" |
|
echo "[SUCCESS] Module built at ${MODULE_PATH}" |
|
echo "[NOTE] Load with: sudo insmod ${MODULE_PATH}" |
|
else |
|
echo "[ERROR] Module was not created at ${MODULE_PATH}" >&2 |
|
exit 1 |
|
fi |