This project contains a sample library that exposes OHTTP client-side interfaces for iOS and macOS. It is compatible with the sample relay and corresponding server.
Prior to building for any platform, download and install Rust - we recommend at least rustc 1.56.0 (09c42c458 2021-10-18)
or greater.
Running cargo build --release
will build the library for the current platform, and library files will appear in ./target/release/
New versions and their corresponding artifacts are done by creating a new release with version number starting from letter v
ie v1.0.0
. A GitHub action will upload relevant release artifacts to release page.
To build the library for iOS:
# Ensure you have the XCode SDK installed and available on your PATH:
➜ xcrun --show-sdk-build-version
21A344
# Install the iOS and macOS cross-compilation targets in your Rust toolchain
➜ rustup target add aarch64-apple-ios
info: component 'rust-std' for target 'aarch64-apple-ios' is up to date
# Install the iOS and macOS cross-compilation targets in your Rust toolchain
➜ rustup target add x86_64-apple-darwin
info: component 'rust-std' for target 'x86_64-apple-darwin' is up to date
With the pre-requisites installed, run cargo build
in --release
mode:
➜ cargo build --target aarch64-apple-ios --release
Library files will appear in ./target/aarch64-apple-ios/release
. SystemConfiguration.framework (part of the XCode SDK) is required for iOS and macOS apps.
To build for macOS, run the following:
➜ cargo build --target x86_64-apple-darwin --release
As with iOS, link with SystemConfiguration.framework when building your macOS app.
To build for android devices you must first download the appropriate binary distribution of standard library for valid target platform. This can be done using rustup:
➜ rustup target add armv7-linux-androideabi
# there are other targets that might be appropriate
➜ rustup show | grep android
To setup compilation for android you will also need to tell cargo about other compilation tools especialy linker. Follow NDK installation instructions. Then configure cargo with linker and archiver:
# set valid paths!
➜ export ANDROID_HOME=/Users/$USER/Library/Android/sdk
➜ export NDK_HOME=$ANDROID_HOME/ndk/25.0.8775105
➜ mkdir ~/.cargo
➜ cat << EOF > ~/.cargo/config
[target.armv7-linux-androideabi]
ar = "$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-ar"
linker = "$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi24-clang++"
EOF
➜ cargo build --target armv7-linux-androideabi
This should work but currently ends with error due to bug:
= note: ld: error: unable to find library -lgcc
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
Ndk project has a workaround applied so should work out of the box:
➜ cargo install cargo-ndk
➜ rustup target add \
aarch64-linux-android \
armv7-linux-androideabi \
➜ cargo ndk \
-t armeabi-v7a \
-t arm64-v8a \
-o ./target/jniLibs build --release
To use from java create 'OHttpNativeWrapper.java' with contents (the class name and the package are important because of JNI conventions)
package org.platform;
class OHttpNativeWrapper {
static {
System.loadLibrary("apprelay");
}
private static native long encapsulateRequest(byte[] config, byte[] msg);
private static native byte[] getEncapsulatedRequest(long ctx_ptr);
private static native void dropRequestContext(long ctx_ptr);
private static native byte[] decapsulateResponse(long ctx_ptr, byte[] encapsulated_response);
public static native String lastErrorMessage();
public static native void init();
public static native void drop(long ctx_ptr);
}
And pass library using VM arguments:
# lib directory should contain libapprelay.so
-Djava.library.path="lib/"
To build binaries with a smaller disk footprint you can use the release-space-optimized
profile:
# for iOS
➜ cargo build \
--target aarch64-apple-ios \
--no-default-features \
--profile release-space-optimized
# for Android this will fail using ndk but the binaries will be located
# in different directory. See https://github.com/bbqsrc/cargo-ndk/issues/73
➜ cargo ndk \
-t armeabi-v7a \
-t arm64-v8a \
-o ./target/jniLibs build --profile release-space-optimized
For more background about the parameters set for this profile read this repo.
The library uses crate env_logger
configured to log to stdout. To enable logging set environment variable:
RUST_LOG=debug
And in your application be sure to call function initialize_logging
for C API or init
for JNI.
Initialization function can be called only once.