66 lines
2.8 KiB
Bash
Executable file
66 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
|