From a7de5b497dfb6815d1136291292bde7b98ad09b5 Mon Sep 17 00:00:00 2001 From: Voyager Date: Thu, 6 Aug 2026 10:11:42 -0400 Subject: [PATCH] Android build helper script --- scripts/setup_android_build.sh | 389 +++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100755 scripts/setup_android_build.sh diff --git a/scripts/setup_android_build.sh b/scripts/setup_android_build.sh new file mode 100755 index 0000000..3d187f7 --- /dev/null +++ b/scripts/setup_android_build.sh @@ -0,0 +1,389 @@ +#!/usr/bin/env bash +set -euo pipefail + +ANDROID_HOME="${ANDROID_HOME:-/home/sol6_vi/Android/Sdk}" +JAVA_HOME="${JAVA_HOME:-}" +INSTALL=0 +AUTO=0 +CMDLINE_TOOLS_ZIP="https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip" +SDK_VERSION="33" +BUILDTOOLS_VERSION="34.0.0" + +usage() { + cat <&2 + usage + exit 2 ;; + esac +done + +PROJECT_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" +GODOT="${GODOT_BIN:-godot}" +MISSING=0 + +print_status() { printf '%s %s\n' "[$1]" "$2"; } + +check_dir() { + local path="$1" label="$2" + if [[ -d "$path" ]]; then + print_status OK "${label}: ${path}" + else + print_status ERR "Missing ${label}: ${path}" + MISSING=$((MISSING+1)) + fi +} + +check_file() { + local path="$1" label="$2" + if [[ -x "$path" || -f "$path" ]]; then + print_status OK "${label}: ${path}" + else + print_status ERR "Missing ${label}: ${path}" + MISSING=$((MISSING+1)) + fi +} + +resolve_java_home() { + local candidate="" + if [[ -n "$JAVA_HOME" && -x "$JAVA_HOME/bin/java" ]]; then + return 0 + fi + + if command -v java >/dev/null 2>&1; then + candidate="$(readlink -f "$(command -v java)")" + candidate="$(dirname "$(dirname "$candidate")")" + if [[ -x "$candidate/bin/java" ]]; then + JAVA_HOME="$candidate" + return 0 + fi + fi + + # Common Ubuntu/Debian/JDK locations + for p in \ + /usr/lib/jvm/default-java \ + /usr/lib/jvm/java-17-openjdk-amd64 \ + /usr/lib/jvm/java-17-openjdk \ + /usr/lib/jvm/jdk-17* \ + /usr/lib/jvm/temurin-17*; + do + if [[ -e $p && -x "$p/bin/java" ]]; then + JAVA_HOME="$p" + return 0 + fi + done + return 1 +} + +check_java() { + if resolve_java_home && [[ -x "$JAVA_HOME/bin/java" ]]; then + print_status OK "Java binary: $JAVA_HOME/bin/java" + "$JAVA_HOME/bin/java" -version 2>&1 | sed -n '1,2p' + local java_ver + java_ver=$("$JAVA_HOME/bin/java" -version 2>&1 | sed -n '1p') + if [[ "$java_ver" =~ \"([0-9]+)\\. ]]; then + local java_major="${BASH_REMATCH[1]}" + if [[ "$java_major" != "17" ]]; then + print_status WARN "Detected Java $java_major. Godot Android export is commonly validated with JDK 17." + fi + fi + else + print_status ERR "Java not found. Set JAVA_HOME to a JDK 17+ home or install one." + MISSING=$((MISSING+1)) + JAVA_HOME="" + fi +} + +find_sdkmanager() { + if [[ -x "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]]; then + echo "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" + return + fi + if [[ -x "$ANDROID_HOME/cmdline-tools/bin/sdkmanager" ]]; then + echo "$ANDROID_HOME/cmdline-tools/bin/sdkmanager"; return + fi + if [[ -x "$ANDROID_HOME/tools/bin/sdkmanager" ]]; then + echo "$ANDROID_HOME/tools/bin/sdkmanager"; return + fi + if command -v sdkmanager >/dev/null 2>&1; then + command -v sdkmanager + return + fi + echo "" +} + +sdkmanager_path="$(find_sdkmanager)" +TMP_CMDLINE_TOOLS_DIR="" + +cleanup_tmpdir() { + [[ -n "${TMP_CMDLINE_TOOLS_DIR:-}" && -d "$TMP_CMDLINE_TOOLS_DIR" ]] && rm -rf "$TMP_CMDLINE_TOOLS_DIR" + TMP_CMDLINE_TOOLS_DIR="" +} + +check_sdk_paths() { + print_status INFO "ANDROID_HOME: ${ANDROID_HOME}" + check_dir "$ANDROID_HOME" "Android SDK root" + check_dir "$ANDROID_HOME/platform-tools" "platform-tools" + check_file "$ANDROID_HOME/platform-tools/adb" "adb binary" + + if [[ -d "$ANDROID_HOME/build-tools" ]]; then + local bt + bt="$(ls -1v "$ANDROID_HOME/build-tools" 2>/dev/null | tail -n 1 || true)" + if [[ -n "$bt" ]]; then + print_status OK "build-tools versions: $(ls -1 "$ANDROID_HOME/build-tools" | tr '\n' ' ')" + check_file "$ANDROID_HOME/build-tools/$bt/apksigner" "apksigner" + else + print_status ERR "build-tools directory exists but is empty" + MISSING=$((MISSING+1)) + fi + else + print_status ERR "Missing build-tools root: $ANDROID_HOME/build-tools" + MISSING=$((MISSING+1)) + fi + + if [[ -d "$ANDROID_HOME/platforms" ]]; then + if ls "$ANDROID_HOME/platforms/android-${SDK_VERSION}" >/dev/null 2>&1; then + print_status OK "platform ${SDK_VERSION}: present" + else + print_status ERR "Missing Android platform: android-${SDK_VERSION}" + MISSING=$((MISSING+1)) + fi + else + print_status ERR "Missing platforms directory: $ANDROID_HOME/platforms" + MISSING=$((MISSING+1)) + fi + + if [[ -x "$sdkmanager_path" ]]; then + print_status OK "sdkmanager: ${sdkmanager_path}" + else + print_status ERR "sdkmanager not found in SDK or PATH" + MISSING=$((MISSING+1)) + fi +} + +install_jdk_hint() { + local pm=0 + echo "Attempting automatic JDK install..." + if command -v apt-get >/dev/null 2>&1; then + pm="apt-get" + elif command -v dnf >/dev/null 2>&1; then + pm="dnf" + elif command -v pacman >/dev/null 2>&1; then + pm="pacman" + else + echo "No supported package manager found (apt-get/dnf/pacman)." + echo "Install JDK 17 manually, then rerun with --java-home set." + return 1 + fi + + if [[ $EUID -ne 0 ]]; then + local sudo_cmd=(sudo) + if ! command -v sudo >/dev/null 2>&1; then + echo "sudo not found; please run with root privileges for package install." + return 1 + fi + fi + + if [[ "$pm" == "apt-get" ]]; then + echo "apt-get install -y openjdk-17-jdk" + if [[ $AUTO -eq 1 ]]; then + if command -v sudo >/dev/null 2>&1; then + sudo apt-get update && sudo apt-get install -y openjdk-17-jdk + fi + else + echo "Run as manual step first: sudo apt-get update && sudo apt-get install -y openjdk-17-jdk" + return 1 + fi + elif [[ "$pm" == "dnf" ]]; then + echo "dnf install -y java-17-openjdk-devel" + if [[ $AUTO -eq 1 ]]; then + sudo dnf install -y java-17-openjdk-devel + else + return 1 + fi + else + echo "pacman -S --noconfirm jdk17-openjdk" + if [[ $AUTO -eq 1 ]]; then + sudo pacman -S --noconfirm jdk17-openjdk + else + return 1 + fi + fi +} + +install_cmdline_tools() { + if [[ -x "$sdkmanager_path" ]]; then + return 0 + fi + + echo "Downloading Android cmdline-tools to bootstrap sdkmanager..." + TMP_CMDLINE_TOOLS_DIR="" + TMP_CMDLINE_TOOLS_DIR="$(mktemp -d)" + if [[ -z "$TMP_CMDLINE_TOOLS_DIR" ]]; then + echo "Failed to create temporary directory." + return 1 + fi + trap cleanup_tmpdir RETURN + + if ! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1; then + echo "curl/wget required to download cmdline-tools. Install one and rerun." + return 1 + fi + + local zipfile="${TMP_CMDLINE_TOOLS_DIR}/cmdline-tools.zip" + if command -v curl >/dev/null 2>&1; then + if ! curl -fL "$CMDLINE_TOOLS_ZIP" -o "$zipfile"; then + echo "Failed to download cmdline-tools from $CMDLINE_TOOLS_ZIP" + return 1 + fi + else + if ! wget -q "$CMDLINE_TOOLS_ZIP" -O "$zipfile"; then + echo "Failed to download cmdline-tools from $CMDLINE_TOOLS_ZIP" + return 1 + fi + fi + + if [[ ! -s "$zipfile" ]]; then + echo "Downloaded cmdline-tools archive is empty." + return 1 + fi + unzip -q "$zipfile" -d "$TMP_CMDLINE_TOOLS_DIR" + if [[ ! -d "$TMP_CMDLINE_TOOLS_DIR/cmdline-tools" ]]; then + echo "Downloaded archive did not contain expected cmdline-tools payload." + return 1 + fi + mkdir -p "$ANDROID_HOME" || { + echo "Cannot create Android SDK root: $ANDROID_HOME" + return 1 + } + mkdir -p "$ANDROID_HOME/cmdline-tools" + rm -rf "$ANDROID_HOME/cmdline-tools/latest" + mkdir -p "$ANDROID_HOME/cmdline-tools/latest" + mv "$TMP_CMDLINE_TOOLS_DIR/cmdline-tools"/* "$ANDROID_HOME/cmdline-tools/latest/" + echo "Installed SDK cmdline-tools to $ANDROID_HOME/cmdline-tools/latest" + sdkmanager_path="$(find_sdkmanager)" + return 0 +} + +install_sdk_components() { + if [[ -z "$sdkmanager_path" ]]; then + echo "Cannot install SDK packages without sdkmanager." + return 1 + fi + "$sdkmanager_path" --sdk_root="${ANDROID_HOME}" --list | head -n 40 | sed -n '1,40p' + echo "Installing required SDK components: platform-tools, platform-android-${SDK_VERSION}, build-tools-${BUILDTOOLS_VERSION}" + if [[ $AUTO -eq 1 ]]; then + yes | "$sdkmanager_path" --sdk_root="${ANDROID_HOME}" --install "platform-tools" "platforms;android-${SDK_VERSION}" "build-tools;${BUILDTOOLS_VERSION}" + else + echo "Run this manually after accepting licenses:" + echo " yes | \"${sdkmanager_path}\" --sdk_root=\"${ANDROID_HOME}\" --install \"platform-tools\" \"platforms;android-${SDK_VERSION}\" \"build-tools;${BUILDTOOLS_VERSION}\"" + return 1 + fi +} + +check_editor_settings() { + local editor_settings="$HOME/.config/godot/editor_settings-4.7.tres" + print_status INFO "Checking editor settings: $editor_settings" + if [[ -f "$editor_settings" ]]; then + if rg -n 'export/android/android_sdk_path|export/android/java_sdk_path' "$editor_settings" >/dev/null 2>&1; then + rg -n 'export/android/android_sdk_path|export/android/java_sdk_path' "$editor_settings" + else + print_status WARN "Editor export settings entries are missing for Android in this file" + echo " Set in editor: Export > Presets > Android:" + echo " android_sdk_path = ${ANDROID_HOME}" + echo " java_sdk_path = ${JAVA_HOME}" + fi + else + print_status WARN "No editor settings file found at expected path: $editor_settings" + fi +} + +run_export_hint() { + echo + echo "Example export commands:" + echo " ${GODOT} --headless --path \"$PROJECT_ROOT\" --export-release \"Android\" builds/v0.5.1-prealpha/android/NETFISHING.apk" + echo " ${GODOT} --headless --path \"$PROJECT_ROOT\" --export-debug \"Android\" builds/android/NETfishing-debug.apk" +} + +print_status INFO "Starting Android dependency preflight..." +check_java +check_sdk_paths +check_editor_settings + +if [[ $MISSING -eq 0 ]]; then + print_status OK "Dependency check passed." + run_export_hint + exit 0 +fi + +if [[ $INSTALL -eq 1 ]]; then + echo + print_status INFO "Attempting dependency install path..." + if [[ -z "$JAVA_HOME" || ! -x "$JAVA_HOME/bin/java" ]]; then + install_jdk_hint || true + fi + + resolve_java_home || true + check_java + + install_cmdline_tools || true + sdkmanager_path="$(find_sdkmanager)" + install_sdk_components || true + + MISSING=0 + check_java + check_sdk_paths + if [[ $MISSING -eq 0 ]]; then + echo + print_status OK "Dependencies fixed." + run_export_hint + exit 0 + fi +fi + +print_status ERR "Dependency check failed with ${MISSING} issue(s)." +cat <<'TIPS' +Suggested manual recovery: +1) Install OpenJDK 17 JDK. +2) Install Android SDK command line tools and run: + sdkmanager --sdk_root="${ANDROID_HOME}" --install "platform-tools" "platforms;android-33" "build-tools;34.0.0" +3) Set JAVA_HOME and ANDROID_HOME in your shell and Godot Exporter settings. +4) Re-run this script without --install (verification), then re-run Godot Android export. +TIPS + +exit 3