Files

130 lines
4.2 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ============================================================
# OpenDance Studio —— Android APK 打包(T-AND-009)
#
# 文档 §6.3 方式二:命令行 Gradle
#
# 前置:
# JAVA_HOME 指向 JDK 17(AGP 8.7 要求)
# ANDROID_HOME / ANDROID_SDK_ROOT 指向 Android SDK
# 需要 platforms;android-34 与 build-tools;34.0.0
#
# 用法:
# bash build/build-apk.sh # 同时产出 debug 与 release
# bash build/build-apk.sh debug
# bash build/build-apk.sh release
# ============================================================
set -euo pipefail
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
cd "$PROJECT_DIR"
TARGET="${1:-all}"
case "$TARGET" in
debug|release|all) ;;
*) echo "用法:bash build/build-apk.sh [debug|release|all]" >&2; exit 2 ;;
esac
log() { printf '\033[1;34m[apk]\033[0m %s\n' "$*"; }
die() { printf '\033[1;31m[error]\033[0m %s\n' "$*" >&2; exit 1; }
# ---- 环境检查 ----
# 优先使用 JAVA_HOME 指定的 JDK:PATH 上的 java 可能是更新的版本,
# AGP 8.7 需要 17~21,检测时必须与 Gradle 实际使用的 JVM 一致。
JAVA_BIN="java"
if [ -n "${JAVA_HOME:-}" ] && [ -x "$JAVA_HOME/bin/java" ]; then
JAVA_BIN="$JAVA_HOME/bin/java"
fi
command -v "$JAVA_BIN" >/dev/null 2>&1 || die "未找到 java,请安装 JDK 17 或设置 JAVA_HOME"
JAVA_MAJOR="$("$JAVA_BIN" -version 2>&1 | head -1 | sed -E 's/.*version "([0-9]+).*/\1/')"
log "Java:$JAVA_BIN (主版本 $JAVA_MAJOR,AGP 8.7 需要 17+)"
if [ "$JAVA_MAJOR" -lt 17 ] 2>/dev/null; then
die "JDK 版本过低:需要 17 或更高(当前 $JAVA_MAJOR)"
fi
SDK="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}"
if [ -z "$SDK" ]; then
for candidate in "$HOME/Android/Sdk" /opt/android-sdk /usr/lib/android-sdk; do
[ -d "$candidate" ] && SDK="$candidate" && break
done
fi
[ -n "$SDK" ] && [ -d "$SDK" ] || die "未找到 Android SDK,请设置 ANDROID_HOME"
log "Android SDK:$SDK"
if [ ! -f "$PROJECT_DIR/local.properties" ]; then
echo "sdk.dir=$SDK" > "$PROJECT_DIR/local.properties"
log "已写入 local.properties"
fi
[ -f "$PROJECT_DIR/gradlew" ] || die "缺少 gradlew(请先执行 gradle wrapper)"
# ---- 签名检查 ----
if [ "$TARGET" != "debug" ]; then
if [ -f "$PROJECT_DIR/keystore.properties" ]; then
log "使用 keystore.properties 中的发布签名"
else
log "提示:未找到 keystore.properties,release 将回退为 debug 签名"
log " 正式发布请先执行:bash build/gen-keystore.sh"
fi
fi
# ---- 构建 ----
if [ "$TARGET" = "debug" ] || [ "$TARGET" = "all" ]; then
log "构建 debug APK…"
./gradlew assembleDebug --console=plain
fi
if [ "$TARGET" = "release" ] || [ "$TARGET" = "all" ]; then
log "构建 release APK…"
./gradlew assembleRelease --console=plain
fi
# ---- 校验产物 ----
DEBUG_APK="app/build/outputs/apk/debug/app-debug.apk"
RELEASE_APK="app/build/outputs/apk/release/app-release.apk"
verify_apk() {
local apk="$1"
local label="$2"
[ -f "$apk" ] || { echo " ✗ 未生成 $label:$apk"; return 1; }
local size
size=$(stat -c%s "$apk")
# APK 是 zip,校验魔数 PK
local magic
magic=$(head -c 2 "$apk" | od -An -tx1 | tr -d ' \n')
[ "$magic" = "504b" ] || { echo " ✗ $label 不是合法 APK(魔数 $magic)"; return 1; }
# 校验是否已签名:APK v2 签名块附近含 "APK Sig Block 42"
local signed="未检出 v2 签名块"
if grep -qa "APK Sig Block 42" "$apk"; then
signed="已签名(APK Signature Scheme v2)"
elif unzip -l "$apk" 2>/dev/null | grep -q "META-INF/.*\.RSA"; then
signed="已签名(v1 JAR 签名)"
fi
echo " ✓ $label:$apk"
echo " 大小 $((size / 1024)) KiB | $signed"
return 0
}
echo ""
log "产物校验:"
FAILED=0
if [ "$TARGET" = "debug" ] || [ "$TARGET" = "all" ]; then
verify_apk "$DEBUG_APK" "Debug APK" || FAILED=1
fi
if [ "$TARGET" = "release" ] || [ "$TARGET" = "all" ]; then
verify_apk "$RELEASE_APK" "Release APK" || FAILED=1
fi
[ "$FAILED" -eq 0 ] || die "有产物未通过校验"
echo ""
log "安装到已连接设备:"
echo " adb install -r $DEBUG_APK"
echo " adb install -r $RELEASE_APK"
echo ""
log "查看签名信息:"
echo " \$ANDROID_HOME/build-tools/34.0.0/apksigner verify --print-certs $RELEASE_APK"