#!/usr/bin/env bash # Wardrobe Android APK 本地打包脚本 (WSL 内运行) # 用法: bash scripts/build-apk.sh [debug|release] # 参考: D:\workbench\iboard\scripts\wsl\build-apk.sh # 尽量复用本机已装的 Android SDK / NDK, 不重复下载 set -euo pipefail WIN_PROJECT='/mnt/d/workbench/Wardrobe' cd "$WIN_PROJECT" VARIANT="${1:-debug}" echo "构建变体: $VARIANT" # ---- 复用已有 Android SDK / NDK (不重复安装) ---- # 优先用 ANDROID_HOME 环境变量, 找不到再探测常见路径 if [ -z "${ANDROID_HOME:-}" ] || [ ! -d "$ANDROID_HOME/platforms" ]; then for cand in "$HOME/android-sdk" "/opt/android-sdk" "/usr/lib/android-sdk"; do if [ -d "$cand/platforms" ]; then export ANDROID_HOME="$cand" break fi done fi if [ -z "${ANDROID_HOME:-}" ] || [ ! -d "$ANDROID_HOME/platforms" ]; then echo "ERROR: 未找到可复用的 Android SDK (ANDROID_HOME)" >&2 exit 1 fi echo "复用 SDK: $ANDROID_HOME" # NDK: 复用已装的 27.2.x, 找不到报错 export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/27.2.12479018}" NDK_TOOLCHAIN_BIN="$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin" if [ ! -d "$NDK_TOOLCHAIN_BIN" ]; then echo "ERROR: NDK toolchain 不存在: $NDK_TOOLCHAIN_BIN, 请确认已安装 NDK 27.2.x" >&2 exit 1 fi echo "复用 NDK: $ANDROID_NDK_HOME" export PATH="$NDK_TOOLCHAIN_BIN:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools:$PATH" # ---- 0. 首次需要 android 工程 ---- cd src-tauri if [ ! -d "gen/android" ]; then echo "=== 0. 初始化 Android 工程 (一次性) ===" npx tauri android init --ci fi cd "$WIN_PROJECT" # ---- 1. 构建前端 ---- echo "=== 1. 构建前端 ===" npm run build # ---- 1.5 拷贝 dist/ 到 Android 工程 assets/ ---- ANDROID_ASSETS="$WIN_PROJECT/src-tauri/gen/android/app/src/main/assets" mkdir -p "$ANDROID_ASSETS" find "$ANDROID_ASSETS" -mindepth 1 -maxdepth 1 ! -name dexopt ! -name tauri.conf.json -exec rm -rf {} + cp -r dist/. "$ANDROID_ASSETS/" echo "前端 bundle 已拷贝到 $ANDROID_ASSETS" # ---- 2. 构建 ---- cd src-tauri if [ "$VARIANT" = "release" ]; then # release: 手工 cargo 编 4 ABI, gradle 只跑打包 RUST_BUILD_TASKS=( ":app:rustBuildArm64Release" ":app:rustBuildArmRelease" ":app:rustBuildX86_64Release" ":app:rustBuildX86Release" ) SKIP_ARGS=() for t in "${RUST_BUILD_TASKS[@]}"; do SKIP_ARGS+=(-x "${t#:}"); done ANDROID_TARGETS=( "aarch64-linux-android" "armv7-linux-androideabi" "x86_64-linux-android" "i686-linux-android" ) echo "[release] 手工 cargo 编 lib (4 个 ABI)..." for target in "${ANDROID_TARGETS[@]}"; do echo " [cargo] build lib release for $target ..." cargo build \ --target "$target" \ --features custom-protocol \ --lib \ --release done echo " [gradle] assembleRelease -x rustBuild* ..." cd gen/android ./gradlew --no-daemon assembleRelease "${SKIP_ARGS[@]}" APK_DIR="$WIN_PROJECT/src-tauri/gen/android/app/build/outputs/apk/universal/release" SIGNED_APK="$APK_DIR/app-universal-release.apk" UNSIGNED_APK="$APK_DIR/app-universal-release-unsigned.apk" if [ -f "$SIGNED_APK" ]; then APK_PATH="$SIGNED_APK" APK_STATUS="已签名" elif [ -f "$UNSIGNED_APK" ]; then APK_PATH="$UNSIGNED_APK" APK_STATUS="未签名" else APK_PATH="" APK_STATUS="未找到" fi echo echo "=== 产物 ($APK_STATUS) ===" if [ -n "$APK_PATH" ]; then ls -lh "$APK_PATH" else ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)" fi if [ "$APK_STATUS" = "已签名" ]; then echo echo "安装: adb install -r $APK_PATH" fi else echo "[debug] 直接走 Tauri CLI" npx tauri android build --apk APK_DIR="$WIN_PROJECT/src-tauri/target/debug/bundle/android/app/build/outputs/apk/debug" echo echo "=== 产物 ===" ls -lh "$APK_DIR"/*.apk 2>/dev/null || echo "(未找到 APK)" fi