#!/usr/bin/env bash # Build the OffTail Tailscale core into an Android .aar via gomobile, from the Go shim in ../gocore. # Output: modules/officer-net/android/libs/tailcore.aar (gitignored; consumed by android/build.gradle). # Requires: Go + gomobile + gobind on PATH, Android SDK + NDK. Proven pair with the iOS build (v1.102.0). set -euo pipefail TAILSCALE_REF="${TAILSCALE_REF:-v1.102.0}" export ANDROID_HOME="${ANDROID_HOME:-/opt/homebrew/share/android-commandlinetools}" export ANDROID_NDK_HOME="${ANDROID_NDK_HOME:-$ANDROID_HOME/ndk/26.3.11579264}" export PATH="$(go env GOPATH)/bin:$PATH" HERE="$(cd "$(dirname "$0")/.." && pwd)" GOCORE="$HERE/gocore"; OUT="$HERE/android/libs/tailcore.aar" cd "$GOCORE" [ -f go.mod ] || go mod init officer.dev/tailcore go get "tailscale.com@${TAILSCALE_REF}"; go get -tool golang.org/x/mobile/cmd/gobind; go get golang.org/x/mobile/bind mkdir -p "$HERE/android/libs" echo "→ gomobile bind -target=android/arm64 (compiles the core for Android)" gomobile bind -target=android/arm64 -androidapi 24 -o "$OUT" ./ [ -f "$OUT" ] || { echo "✗ no aar produced" >&2; exit 1; } # Gradle does NOT consume the .aar — build.gradle has `api files('libs/tailcore.jar')`, and the native # code ships from src/main/jniLibs. Producing the .aar alone therefore has NO EFFECT on the app, and # the failure is silent: everything builds, installs and runs the PREVIOUS core. That cost two hours # on 2026-08-02, with a jar three days older than the .aar beside it. echo "→ refreshing libs/tailcore.jar + jniLibs/libgojni.so from the .aar (what Gradle actually uses)" LIBS="$HERE/android/libs" JNI="$HERE/android/src/main/jniLibs/arm64-v8a" mkdir -p "$JNI" unzip -o -q "$OUT" classes.jar -d "$LIBS" && mv -f "$LIBS/classes.jar" "$LIBS/tailcore.jar" unzip -o -q -j "$OUT" "jni/arm64-v8a/libgojni.so" -d "$JNI" echo "✔ built $OUT"; ls -la "$OUT" "$LIBS/tailcore.jar" "$JNI/libgojni.so"