vpn/scripts/build-android.sh

67 lines
2.8 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
command -v uv >/dev/null || { echo "uv is required" >&2; exit 1; }
BRIDGE_ANDROID_DIR="native/android/flet_vpn_bridge/src/flutter/vpn_native_bridge/android"
# setuptools otherwise reuses a half-populated wheel tree after a failed/aborted
# native build and can fail with a misleading dist-info "File exists" error.
rm -rf native/android/flet_vpn_bridge/build native/android/flet_vpn_bridge/src/vpn_native_bridge.egg-info
mkdir -p "$BRIDGE_ANDROID_DIR/libs"
# Remove artifacts from older builds that used the unsupported direct-AAR
# dependency path. The reviewed source artifacts remain under native/android.
rm -f "$BRIDGE_ANDROID_DIR/libs/freeturn.aar" "$BRIDGE_ANDROID_DIR/libs/libbox.aar"
JNI_DIR="$BRIDGE_ANDROID_DIR/src/main/jniLibs"
rm -rf "$JNI_DIR"
mkdir -p "$JNI_DIR"
# A Flutter/Flet extension is itself built as an Android AAR. Gradle rejects
# direct local .aar dependencies in that situation, so unpack only the AAR's
# classes.jar and native libraries into the extension. The resulting plugin
# AAR carries the same reviewed engine payload into the final APK.
prepare_engine_artifact() {
local artifact="$1"
local stem="${artifact%.aar}"
local source="native/android/libs/$artifact"
local jar_target="$BRIDGE_ANDROID_DIR/libs/${stem}-classes.jar"
rm -f "$jar_target"
if [[ -f "$source" ]]; then
unzip -p "$source" classes.jar > "$jar_target"
local unpack_dir
unpack_dir="$(mktemp -d)"
unzip -q "$source" 'jni/*' -d "$unpack_dir"
if [[ -d "$unpack_dir/jni" ]]; then
cp -R "$unpack_dir/jni/." "$JNI_DIR/"
fi
rm -rf "$unpack_dir"
fi
}
# Two independently generated gomobile AARs both own incompatible global
# go.Seq/go.Universe classes. D8 cannot package them in one APK and choosing one
# runtime for both can crash JNI. The current MVP is deliberately libbox-first;
# FreeTurn remains a separately pinned artifact until its binding is namespaced.
if [[ -f native/android/libs/libbox.aar ]]; then
prepare_engine_artifact libbox.aar
rm -f "$BRIDGE_ANDROID_DIR/libs/freeturn-classes.jar"
echo "Note: FreeTurn Android binding excluded: gomobile runtime namespace conflicts with libbox.aar."
elif [[ -f native/android/libs/freeturn.aar ]]; then
prepare_engine_artifact freeturn.aar
fi
if [[ ! -f native/android/libs/libbox.aar ]]; then
cat >&2 <<'EOF'
Warning: the primary Android native engine artifact is missing.
The APK will build, but SignBox reports UNSUPPORTED and cannot connect.
For a release build set REQUIRE_NATIVE_ARTIFACTS=1 after placing the reviewed, pinned file at:
native/android/libs/libbox.aar
EOF
if [[ "${REQUIRE_NATIVE_ARTIFACTS:-0}" == "1" ]]; then
exit 2
fi
fi
uv run flet build apk --project vpn-app --org su.snw --artifact vpn-app-arm64 --arch arm64-v8a
./scripts/verify-android-apk.sh build/apk/vpn-app-arm64.apk 2 0.1.1