130 lines
4.2 KiB
Bash
Executable File
130 lines
4.2 KiB
Bash
Executable File
#!/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"
|