Skip to content

Commit

Permalink
add cargo ndk build script for uniffi (#980)
Browse files Browse the repository at this point in the history
Signed-off-by: Swapnil Tripathi <swapnil06.st@gmail.com>
Co-authored-by: George Mulhearn <57472912+gmulhearn@users.noreply.github.com>
  • Loading branch information
swaptr and gmulhearn authored Sep 24, 2023
1 parent 7e514fa commit adefa28
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 4 deletions.
41 changes: 37 additions & 4 deletions uniffi_aries_vcx/README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,57 @@
# UniFFI Aries VCX Proof Of Concept

This sub-directory contains the UniFFI wrappers and tools to generate Kotlin & Swift mobile wrappers over the `aries-vcx` crate.

## Core

Core contains a crate which wraps over the `aries-vcx` crate to provide a UniFFI-ready interface for wrapping. This crate's interface is what is used in `demos`.

## Demos

Coming soon..

## Building

This module is distributed in three directories.

1. `core`: The UniFFI bindings for Aries VCX.
2. `demo`: Demo application consuming the UniFFI wrapper code.
3. `scripts`: Contains helper sh scripts to ease the process of setting up, building and generating the UniFFI code.

To set up the Android SDK, NDK and bootstrap the demo application, you can simply run the following scripts in the order:
1. `android.prepare.sh`: This script will prepare the Android SDK and NDK for your system.
2. `android.toolchain.sh`: This script will prepare the required android toolchain.
3. `android.build.sh`: This script will build the UniFFI bindings and bootstrap the demo application for the target architecture.
To generate the UniFFI bindings, you need to set up [cargo-ndk](https://github.com/bbqsrc/cargo-ndk) on your system. Instructions to set up `cargo-ndk` are available [here](https://github.com/bbqsrc/cargo-ndk#installing), but can be summed up as:

1. Install `cargo-ndk`.

```bash
cargo install cargo-ndk
```

2. Add target architectures you want to use.

```bash
rustup target add <target>
```

eg. for Android ARM64 on host linux platform.

```bash
rustup target add aarch64-linux-android
```

More documentation can be found [here](https://rust-lang.github.io/rustup/cross-compilation.html). Information on supported platforms can be found [here](https://doc.rust-lang.org/nightly/rustc/platform-support.html).

3. `cargo-ndk` requires Android NDK to be set up on the host machine. The recommended way of doing this is using Android Studio as described [here](https://developer.android.com/studio/projects/install-ndk#default-version).

4. If `cargo-ndk` cannot find the installed NDK, you may have to configure the `ANDROID_NDK_HOME` environment variable as described [here](https://github.com/bbqsrc/cargo-ndk#usage).

5. Run the helper build script.

```bash
sh uniffi_aries_vcx/scripts/android.build.cargo.ndk.sh
```

NB: Before running the demo application you need to generate the language bindings.

## Support

Currently the builds have been tested for android `arm64 (aarch64)` on a physical device. In the future we plan to support other architectures.
82 changes: 82 additions & 0 deletions uniffi_aries_vcx/scripts/android.build.cargo.ndk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/bin/bash
set -ex

SCRIPT_DIR="$( cd "$(dirname "$0")" ; pwd -P )"

# Required env vars
ARIES_VCX_ROOT=$(dirname $(dirname $SCRIPT_DIR))
ANDROID_BUILD_DEPS_DIR=${ARIES_VCX_ROOT}/target/android_build_deps
LANGUAGE="kotlin"
TARGET="aarch64-linux-android"
TARGET_NICKNAME="arm64"
ABI="arm64-v8a"

generate_bindings() {
export UNIFFI_ROOT="${ARIES_VCX_ROOT}/uniffi_aries_vcx"
export ANDROID_DEMO_DIR="${UNIFFI_ROOT}/demo"

pushd "${UNIFFI_ROOT}/core"
cargo run --features=uniffi/cli --bin uniffi-bindgen generate src/vcx.udl --language ${LANGUAGE}
popd

cp -R ${UNIFFI_ROOT}/core/src/org/hyperledger/ariesvcx/vcx.kt ${ANDROID_DEMO_DIR}/app/src/main/java/org/hyperledger/ariesvcx
rm -R ${UNIFFI_ROOT}/core/src/org
}

download_and_unzip_if_missed() {
expected_directory="$1"
url="$2"
fname="tmp_$(date +%s)_$expected_directory.zip"
if [ ! -d "${expected_directory}" ] ; then
echo "Downloading ${GREEN}${url}${RESET} as ${GREEN}${fname}${RESET}"
wget -q -O ${fname} "${url}"
echo "Unzipping ${GREEN}${fname}${RESET}"
unzip -qqo "${fname}"
rm "${fname}"
echo "${GREEN}Done!${RESET}"
else
echo "${BLUE}Skipping download ${url}${RESET}. Expected directory ${expected_directory} was found"
fi
}

setup_linked_dependencies() {
mkdir -p $ANDROID_BUILD_DEPS_DIR
# download deps
pushd "${ANDROID_BUILD_DEPS_DIR}"
download_and_unzip_if_missed "openssl_$TARGET_NICKNAME" "https://repo.sovrin.org/android/libindy/deps/openssl/openssl_$TARGET_NICKNAME.zip"
download_and_unzip_if_missed "libsodium_$TARGET_NICKNAME" "https://repo.sovrin.org/android/libindy/deps/sodium/libsodium_$TARGET_NICKNAME.zip"
download_and_unzip_if_missed "libzmq_$TARGET_NICKNAME" "https://repo.sovrin.org/android/libindy/deps/zmq/libzmq_$TARGET_NICKNAME.zip"
popd

# main env vars that need to be set
export OPENSSL_DIR=${ANDROID_BUILD_DEPS_DIR}/openssl_${TARGET_NICKNAME}
export SODIUM_DIR=${ANDROID_BUILD_DEPS_DIR}/libsodium_${TARGET_NICKNAME}
export LIBZMQ_DIR=${ANDROID_BUILD_DEPS_DIR}/libzmq_${TARGET_NICKNAME}

# secondary env vars that need to be set
export SODIUM_LIB_DIR=${SODIUM_DIR}/lib
export SODIUM_INCLUDE_DIR=${SODIUM_DIR}/include
export SODIUM_STATIC=1
export LIBZMQ_LIB_DIR=${LIBZMQ_DIR}/lib
export LIBZMQ_INCLUDE_DIR=${LIBZMQ_DIR}/include
export LIBZMQ_PREFIX=${LIBZMQ_DIR}
export OPENSSL_LIB_DIR=${OPENSSL_DIR}/lib
export OPENSSL_STATIC=1
}

build_uniffi_for_demo() {
export UNIFFI_ROOT="${ARIES_VCX_ROOT}/uniffi_aries_vcx"
export ANDROID_DEMO_DIR="${UNIFFI_ROOT}/demo"
export ABI_PATH=${ANDROID_DEMO_DIR}/app/src/main/jniLibs/${ABI}
mkdir -p ${ABI_PATH}

pushd ${UNIFFI_ROOT}/core
cargo ndk -t ${ABI} build
cp ${ARIES_VCX_ROOT}/target/${TARGET}/debug/libuniffi_vcx.so ${ABI_PATH}/libuniffi_vcx.so
cp ${LIBZMQ_LIB_DIR}/libzmq.so ${ABI_PATH}/libzmq.so
popd
}

generate_bindings
setup_linked_dependencies
build_uniffi_for_demo

0 comments on commit adefa28

Please sign in to comment.