diff --git a/uniffi_aries_vcx/README.md b/uniffi_aries_vcx/README.md index f9a63bc379..3d0d15cf37 100644 --- a/uniffi_aries_vcx/README.md +++ b/uniffi_aries_vcx/README.md @@ -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 +``` + +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. diff --git a/uniffi_aries_vcx/scripts/android.build.cargo.ndk.sh b/uniffi_aries_vcx/scripts/android.build.cargo.ndk.sh new file mode 100644 index 0000000000..cf40bcf995 --- /dev/null +++ b/uniffi_aries_vcx/scripts/android.build.cargo.ndk.sh @@ -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