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. This code is provided for demonstration purposes.
Prior to building for any platform, download and install Rust - we recommend at least rustc 1.89.0 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 dateWith the pre-requisites installed, run cargo build in --release mode:
➜ cargo build --target aarch64-apple-ios --releaseLibrary 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 --releaseAs 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 androidTo 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-androideabiThis 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 --releaseTo 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-optimizedFor 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.