mirror of
https://github.com/cfal/shoes.git
synced 2026-11-06 08:14:11 +00:00
* Add mobile build artifacts for iOS and Android - Add GitHub Actions workflow to build XCFramework (iOS) and AAR (Android) and publish them to GitHub releases on tag pushes - Add scripts/build-ios.sh and scripts/build-android.sh for local builds - Add android/ project (Gradle library module with Kotlin JNI wrapper) - Add include/shoes.h C header for FFI consumers - Gitignore /output build directory Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * Fix Android JNI build: pin jni to 0.21, use --locked The committed Cargo.toml had `jni = "*"` which resolved to jni 0.22.4 in CI. jni 0.22 renamed JNIEnv to EnvUnowned, breaking the Android FFI code written for the 0.21 API. - Pin jni to "=0.21" (resolves to 0.21.1 via Cargo.lock) - Add --locked to cargo ndk to enforce the lock file in CI Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * Migrate Android JNI bindings to jni 0.22 jni 0.22 split JNIEnv into two types: - EnvUnowned<'local> — FFI-safe type for native method signatures - Env<'local> — high-level wrapper with get_string, new_string, etc. Changes: - Replace JNIEnv with EnvUnowned in all function signatures - Use EnvUnowned::with_env() to access the Env inside each function - Use Outcome enum (Ok/Err/Panic) from into_outcome() for error handling - Replace new_global_ref return type: GlobalRef -> Global<JObject<'static>> - Replace attach_current_thread() guard pattern with callback closure - Replace &str method names/sigs with jni_str!/jni_sig! compile-time macros Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * Auto-generate iOS C header with cbindgen Replace hand-written include/shoes.h with cbindgen-generated output. The header is now derived from doc comments on extern "C" functions in src/ffi/ios.rs, keeping it in sync with the Rust source. - Add cbindgen.toml (exports only ProtectSocketCallback + FFI functions) - build-ios.sh runs cbindgen before building the XCFramework - CI installs cbindgen in the iOS job Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix clippy and rustfmt CI failures - Reorder jni imports in ffi/android.rs to match rustfmt order - Remove unnecessary `as usize` cast in shadow_tls_server_handler.rs - Collapse match guard in config/validate.rs (clippy::collapsible_match) Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
99 lines
2.8 KiB
Bash
Executable File
99 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Build shoes as an Android AAR.
|
|
#
|
|
# Output: output/android/shoes-release.aar
|
|
#
|
|
# Requirements:
|
|
# - Android NDK: set ANDROID_NDK_HOME, or NDK_HOME, or have ANDROID_HOME with NDK installed
|
|
# - cargo-ndk: installed automatically if missing
|
|
# - Gradle 8.6+ available as `gradle` in PATH, or ./gradlew in android/
|
|
# - Java 17+
|
|
#
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
ANDROID_DIR="$ROOT_DIR/android"
|
|
OUTPUT_DIR="$ROOT_DIR/output/android"
|
|
JNI_LIBS_DIR="$ANDROID_DIR/src/main/jniLibs"
|
|
|
|
cd "$ROOT_DIR"
|
|
|
|
# Resolve NDK path
|
|
if [ -z "${ANDROID_NDK_HOME:-}" ]; then
|
|
if [ -n "${NDK_HOME:-}" ]; then
|
|
export ANDROID_NDK_HOME="$NDK_HOME"
|
|
elif [ -n "${ANDROID_HOME:-}" ] && [ -d "$ANDROID_HOME/ndk" ]; then
|
|
ANDROID_NDK_HOME="$(ls -d "$ANDROID_HOME/ndk/"*/ 2>/dev/null | sort -V | tail -1)"
|
|
ANDROID_NDK_HOME="${ANDROID_NDK_HOME%/}"
|
|
export ANDROID_NDK_HOME
|
|
else
|
|
echo "Error: ANDROID_NDK_HOME is not set."
|
|
echo " Set it to the NDK directory, e.g.:"
|
|
echo " export ANDROID_NDK_HOME=\$HOME/Library/Android/sdk/ndk/26.3.11579264"
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo "==> Using NDK: $ANDROID_NDK_HOME"
|
|
|
|
# Install cargo-ndk if needed
|
|
if ! command -v cargo-ndk &>/dev/null; then
|
|
echo "==> Installing cargo-ndk"
|
|
cargo install cargo-ndk
|
|
fi
|
|
|
|
echo "==> Adding Android Rust targets"
|
|
rustup target add \
|
|
aarch64-linux-android \
|
|
armv7-linux-androideabi
|
|
|
|
echo "==> Cleaning JNI libs directory"
|
|
rm -rf "$JNI_LIBS_DIR"
|
|
|
|
echo "==> Building native .so files for all ABIs"
|
|
cargo ndk \
|
|
-t arm64-v8a \
|
|
-t armeabi-v7a \
|
|
-P 21 \
|
|
-o "$JNI_LIBS_DIR" \
|
|
-- build --release --lib
|
|
|
|
echo "==> Built libraries:"
|
|
find "$JNI_LIBS_DIR" -name "*.so" | sort | sed 's|^| |'
|
|
|
|
echo "==> Building AAR with Gradle"
|
|
cd "$ANDROID_DIR"
|
|
|
|
# Ensure ANDROID_HOME is set so Gradle can find the SDK
|
|
if [ -z "${ANDROID_HOME:-}" ]; then
|
|
if [ -d "$HOME/Library/Android/sdk" ]; then
|
|
export ANDROID_HOME="$HOME/Library/Android/sdk"
|
|
elif [ -d "$HOME/Android/sdk" ]; then
|
|
export ANDROID_HOME="$HOME/Android/sdk"
|
|
fi
|
|
fi
|
|
|
|
if ! command -v gradle &>/dev/null; then
|
|
echo "Error: 'gradle' not found in PATH."
|
|
echo " Install Gradle: https://gradle.org/install/"
|
|
echo " Or run: sdk install gradle 8.6 (via SDKMAN)"
|
|
exit 1
|
|
fi
|
|
gradle assembleRelease --no-daemon
|
|
|
|
# Copy output
|
|
mkdir -p "$OUTPUT_DIR"
|
|
AAR="$(find "$ANDROID_DIR/build/outputs/aar" -name "*-release.aar" | head -1)"
|
|
if [ -z "$AAR" ]; then
|
|
echo "Error: AAR not found in android/build/outputs/aar/"
|
|
exit 1
|
|
fi
|
|
cp "$AAR" "$OUTPUT_DIR/shoes-release.aar"
|
|
|
|
echo ""
|
|
echo "Done: $OUTPUT_DIR/shoes-release.aar"
|
|
echo ""
|
|
echo "Gradle integration (app/build.gradle.kts):"
|
|
echo " implementation(files(\"libs/shoes-release.aar\"))"
|