From 5c332f28d91060db1b384d4f4d09c7ef09d3ec35 Mon Sep 17 00:00:00 2001 From: Pablo Guardiola Date: Sun, 18 Jan 2026 14:09:49 -0500 Subject: [PATCH] fix android binding generation and local build setup --- .gitignore | 8 +++++- Cargo.toml | 3 +- Cross.toml | 9 +++++- README.md | 40 +++++++++++++++++++++++++- build_android_local.sh | 35 ++++++++++++++++++++++ kotlin/.gitignore | 18 +++++++++--- kotlin/build.gradle.kts | 6 ++++ kotlin/build.sh | 38 ++++++++++++++++++++++++ kotlin/lib/.gitignore | 2 ++ kotlin/lib/build.gradle.kts | 5 +--- kotlin/lib/src/main/jniLibs/.gitignore | 2 ++ rust-toolchain.toml | 14 +++++++++ 12 files changed, 167 insertions(+), 13 deletions(-) create mode 100755 build_android_local.sh create mode 100644 kotlin/build.gradle.kts create mode 100755 kotlin/build.sh create mode 100644 kotlin/lib/.gitignore create mode 100644 kotlin/lib/src/main/jniLibs/.gitignore create mode 100644 rust-toolchain.toml diff --git a/.gitignore b/.gitignore index a6fe841b0..ba9a8a866 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,12 @@ target/ **/ios_build .swiftpm/ +# IDE +.idea +*.iml +.vscode +*/settings.json + # Swift build outputs are not committed to this repo. WalletKit.xcframework/ Sources/ @@ -13,4 +19,4 @@ Sources/ cache/ **/out/build-info -# NOTE: Cargo.lock is not ignored because it is used for FFI builds (Swift & Kotlin) \ No newline at end of file +# NOTE: Cargo.lock is not ignored because it is used for FFI builds (Swift & Kotlin) diff --git a/Cargo.toml b/Cargo.toml index 4748a6655..14b08591d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" authors = ["World Contributors"] readme = "./README.md" homepage = "https://docs.world.org" # TODO: Update to specific WalletKit page -rust-version = "1.86" # MSRV +rust-version = "1.91" # MSRV repository = "https://github.com/worldcoin/walletkit" exclude = ["tests/", "uniffi-bindgen/"] keywords = ["ZKP", "WorldID", "World", "Identity", "Semaphore"] @@ -26,6 +26,5 @@ world-id-core = { version = "0.3", default-features = false, features = ["authen [profile.release] opt-level = 'z' # Optimize for size. lto = true # Enable Link Time Optimization. -strip = true # Automatically strip symbols from the binary. panic = "abort" debug = false diff --git a/Cross.toml b/Cross.toml index 779abe3d7..1bc3e3439 100644 --- a/Cross.toml +++ b/Cross.toml @@ -1,3 +1,10 @@ +[build.env] +passthrough = [ + "CARGO_NET_GIT_FETCH_WITH_CLI=true", # to force cargo to use git cli with config --global in homedir + "HOME", # set $HOME to shared dir where we put .gitconfig + "RUSTUP_HOME", # override rustup home to prevent host permission issues + "CARGO_HOME", # override cargo home to prevent host permission issues +] # max-page-size=16384: # Android 15 (API 35) introduces support for 16KB page sizes to improve performance on devices with larger RAM. # Apps with native libraries MUST be compiled with 16KB ELF alignment or they will crash on startup @@ -11,4 +18,4 @@ pre-build = [ "apt-get update && apt-get --assume-yes install pkg-config:$CROSS_DEB_ARCH", "export PKG_CONFIG_ALLOW_CROSS=1", "export PKG_CONFIG_LIBDIR=/usr/lib/$CROSS_DEB_ARCH/pkgconfig:/usr/lib/$CROSS_DEB_ARCH/lib/pkgconfig:/usr/share/pkgconfig", -] \ No newline at end of file +] diff --git a/README.md b/README.md index 23eea537e..b137f4d6a 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ WalletKit's bindings for Kotlin are distributed through GitHub packages. ```kotlin dependencies { /// ... - implementation "org.world:walletkit:VERSION" + implementation "org.world:walletkit-android:VERSION" } ``` @@ -36,6 +36,44 @@ Replace `VERSION` with the desired WalletKit version. 2. Sync Gradle. +## Local development (Android/Kotlin) + +### Prerequisites + +1. **Docker Desktop**: Required for cross-compilation + - The build uses [`cross`](https://github.com/cross-rs/cross) which runs builds in Docker containers with all necessary toolchains + - Install via Homebrew: + ```bash + brew install --cask docker + ``` + - Launch Docker Desktop and ensure it's running before building + +2. **Android SDK + NDK**: Required for Gradle Android tasks + - Install via Android Studio > Settings > Android SDK (ensure the NDK is installed) + - Set `sdk.dir` (and `ndk.dir` if needed) in `kotlin/local.properties` + +3. **Protocol Buffers compiler**: + ```bash + brew install protobuf + ``` + +### Building and publishing + +To test local changes before publishing a release, use the build script to compile the Rust library, generate UniFFI bindings, and publish a SNAPSHOT to Maven Local: + +```bash +./build_android_local.sh 0.3.1-SNAPSHOT +``` + +> **Note**: The script sets `RUSTUP_HOME` and `CARGO_HOME` to `/tmp` by default to avoid Docker permission issues when using `cross`. You can override them by exporting your own values. + +This will: +1. Build the Rust library for all Android architectures (arm64-v8a, armeabi-v7a, x86_64, x86) +2. Generate Kotlin UniFFI bindings +3. Publish to `~/.m2/repository/org/world/walletkit-android/` + +In your consuming project, ensure `mavenLocal()` is included in your repositories and update your dependency version to the SNAPSHOT version (e.g., `0.3.1-SNAPSHOT`). + ## Overview WalletKit is broken down into separate crates, offering the following functionality. diff --git a/build_android_local.sh b/build_android_local.sh new file mode 100755 index 000000000..7398387fc --- /dev/null +++ b/build_android_local.sh @@ -0,0 +1,35 @@ +#!/bin/bash +set -e + +echo "Building WalletKit Android SDK for local development..." + +# Set rustup and cargo home to /tmp to prevent Docker permission issues +export RUSTUP_HOME="${RUSTUP_HOME:-/tmp/.rustup}" +export CARGO_HOME="${CARGO_HOME:-/tmp/.cargo}" + +# Version is required +if [ -z "$1" ]; then + echo "Error: Version parameter is required" + echo "Usage: ./build_android_local.sh " + echo "Example: ./build_android_local.sh 0.2.1-SNAPSHOT" + exit 1 +fi + +VERSION="$1" +echo "Using version: $VERSION" + +# Build using kotlin/build.sh +echo "Building WalletKit SDK..." +cd kotlin +./build.sh + +# Publish to Maven Local +echo "Publishing to Maven Local..." +./gradlew :lib:publishToMavenLocal -PversionName="$VERSION" + +echo "" +echo "✅ Successfully published $VERSION to Maven Local!" +echo "Published to: ~/.m2/repository/org/world/walletkit-android/$VERSION/" +echo "" +echo "To use in your project:" +echo " implementation 'org.world:walletkit-android:$VERSION'" diff --git a/kotlin/.gitignore b/kotlin/.gitignore index 1b6985c00..aa724b770 100644 --- a/kotlin/.gitignore +++ b/kotlin/.gitignore @@ -1,5 +1,15 @@ -# Ignore Gradle project-specific cache directory +*.iml .gradle - -# Ignore Gradle build output directory -build +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/kotlin/build.gradle.kts b/kotlin/build.gradle.kts new file mode 100644 index 000000000..36563fc43 --- /dev/null +++ b/kotlin/build.gradle.kts @@ -0,0 +1,6 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id("com.android.application") version "8.3.0" apply false + id("com.android.library") version "8.3.0" apply false + id("org.jetbrains.kotlin.android") version "1.9.22" apply false +} diff --git a/kotlin/build.sh b/kotlin/build.sh new file mode 100755 index 000000000..07c445523 --- /dev/null +++ b/kotlin/build.sh @@ -0,0 +1,38 @@ +#!/bin/bash +set -e + +echo "Building WalletKit Android SDK..." + +# Create jniLibs directories +mkdir -p ./lib/src/main/jniLibs/{arm64-v8a,armeabi-v7a,x86_64,x86} + +# Build for all Android architectures +echo "Building for aarch64-linux-android..." +cross build -p walletkit --release --target=aarch64-linux-android + +echo "Building for armv7-linux-androideabi..." +cross build -p walletkit --release --target=armv7-linux-androideabi + +echo "Building for x86_64-linux-android..." +cross build -p walletkit --release --target=x86_64-linux-android + +echo "Building for i686-linux-android..." +cross build -p walletkit --release --target=i686-linux-android + +# Move .so files to jniLibs +echo "Moving native libraries..." +mv ../target/aarch64-linux-android/release/libwalletkit.so ./lib/src/main/jniLibs/arm64-v8a/libwalletkit.so +mv ../target/armv7-linux-androideabi/release/libwalletkit.so ./lib/src/main/jniLibs/armeabi-v7a/libwalletkit.so +mv ../target/x86_64-linux-android/release/libwalletkit.so ./lib/src/main/jniLibs/x86_64/libwalletkit.so +mv ../target/i686-linux-android/release/libwalletkit.so ./lib/src/main/jniLibs/x86/libwalletkit.so + +# Generate Kotlin bindings +echo "Generating Kotlin bindings..." +cargo run -p uniffi-bindgen generate \ + ./lib/src/main/jniLibs/arm64-v8a/libwalletkit.so \ + --library \ + --language kotlin \ + --no-format \ + --out-dir lib/src/main/java + +echo "✅ Build complete!" diff --git a/kotlin/lib/.gitignore b/kotlin/lib/.gitignore new file mode 100644 index 000000000..dc7bdfe18 --- /dev/null +++ b/kotlin/lib/.gitignore @@ -0,0 +1,2 @@ +/build +/src/main/java/uniffi/ diff --git a/kotlin/lib/build.gradle.kts b/kotlin/lib/build.gradle.kts index fe872cbc7..eddfce6f9 100644 --- a/kotlin/lib/build.gradle.kts +++ b/kotlin/lib/build.gradle.kts @@ -8,14 +8,11 @@ plugins { android { namespace = "org.world.walletkit" - compileSdk = 33 + compileSdk = 35 defaultConfig { minSdk = 23 - @Suppress("deprecation") - targetSdk = 33 - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles("consumer-rules.pro") } diff --git a/kotlin/lib/src/main/jniLibs/.gitignore b/kotlin/lib/src/main/jniLibs/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/kotlin/lib/src/main/jniLibs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000..74379b068 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,14 @@ +[toolchain] +channel = "1.91.0" +profile = "default" +components = ["rustfmt", "clippy", "rust-analyzer"] +targets = [ + "aarch64-apple-ios-sim", + "aarch64-apple-ios", + "x86_64-apple-ios", + "x86_64-unknown-linux-gnu", + "aarch64-linux-android", + "armv7-linux-androideabi", + "x86_64-linux-android", + "i686-linux-android", +]