sdk/runanywhere-commons/README.md
runanywhere-commons is a unified C/C++ library that serves as the foundation for the RunAnywhere SDK ecosystem. It provides the core infrastructure, service abstraction layer, and ML backend integrations that power on-device AI capabilities across iOS, Android, macOS, and Linux platforms.
RunAnywhere Commons is the shared C++ layer that sits between platform SDKs (Swift, Kotlin, Flutter) and ML inference backends (LlamaCPP, ONNX/Sherpa-ONNX, WhisperCPP). It provides:
rac_ prefix and follow a consistent vtable-based abstraction patternServiceRegistry patternRAC_LOG_INFO, RAC_LOG_ERROR)rac_alloc, rac_free)┌─────────────────────────────────────────────────────────────┐
│ Swift/Kotlin SDKs │
│ (RunAnywhere, RunAnywhereKotlin) │
└────────────────────────────┬────────────────────────────────┘
│ C API (rac_*)
┌────────────────────────────▼────────────────────────────────┐
│ RAC Public C API (rac_*) │
│ rac_llm_service.h, rac_stt_service.h, rac_tts_service.h │
│ rac_vad_service.h, rac_voice_agent.h │
└────────────────────────────┬────────────────────────────────┘
│ vtable dispatch
┌────────────────────────────▼────────────────────────────────┐
│ Service & Module Registry │
│ - Priority-based provider selection │
│ - canHandle pattern for capability matching │
│ - Lazy service instantiation │
└────────────────────────────┬────────────────────────────────┘
│
┌────────────────────────────▼────────────────────────────────┐
│ Backends (src/backends/) │
│ ┌─────────────┐ ┌─────────────────┐ ┌───────────────┐ │
│ │ llamacpp/ │ │ onnx/ │ │ whispercpp/ │ │
│ │ LLM (GGUF) │ │ STT/TTS/VAD │ │ STT (GGML) │ │
│ │ Metal GPU │ │ (Sherpa-ONNX) │ │ Whisper.cpp │ │
│ └─────────────┘ └─────────────────┘ └───────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ platform/ │ │
│ │ Apple Foundation Models (LLM) + System TTS │ │
│ │ (Swift callbacks, iOS/macOS only) │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
| Capability | Description | Backends |
|---|---|---|
| TEXT_GENERATION | LLM text generation with streaming | LlamaCPP, Platform (Apple FM) |
| STT | Speech-to-text transcription | ONNX (Sherpa), WhisperCPP |
| TTS | Text-to-speech synthesis | ONNX (Sherpa), Platform (System TTS) |
| VAD | Voice activity detection | ONNX (Silero), Built-in (Energy-based) |
| VOICE_AGENT | Full voice pipeline orchestration | Composite (STT+LLM+TTS+VAD) |
include/rac/backends/rac_llm_llamacpp.h// Create and load a GGUF model
rac_handle_t handle;
rac_llm_llamacpp_create("/path/to/model.gguf", NULL, &handle);
// Generate text with streaming
rac_llm_options_t options = RAC_LLM_OPTIONS_DEFAULT;
options.max_tokens = 256;
options.temperature = 0.7f;
rac_llm_llamacpp_generate_stream(handle, "Hello, world!", &options,
token_callback, user_data);
rac_stt_onnx.h, rac_tts_onnx.h, rac_vad_onnx.h// Create STT service
rac_handle_t stt;
rac_stt_onnx_create("/path/to/whisper", NULL, &stt);
// Transcribe audio
rac_stt_result_t result;
rac_stt_onnx_transcribe(stt, audio_samples, num_samples, NULL, &result);
printf("Transcription: %s\n", result.text);
include/rac/backends/rac_stt_whispercpp.hrac_llm_platform.h, rac_tts_platform.h# Clone the repository
cd runanywhere-all/sdks/sdk/runanywhere-commons
# Configure and build (macOS/Linux)
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
# Build with backends
cmake -B build -DRAC_BUILD_BACKENDS=ON
cmake --build build
#include "rac/core/rac_core.h"
#include "rac/features/llm/rac_llm_service.h"
// Initialize the library
rac_config_t config = {
.platform_adapter = &my_platform_adapter,
.log_level = RAC_LOG_INFO,
.log_tag = "MyApp"
};
rac_init(&config);
// Register backends
rac_backend_llamacpp_register();
rac_backend_onnx_register();
// Create an LLM service
rac_handle_t llm;
rac_llm_create("my-model-id", &llm);
// Generate text
rac_llm_result_t result;
rac_llm_generate(llm, "Hello!", NULL, &result);
printf("Response: %s\n", result.text);
// Cleanup
rac_llm_result_free(&result);
rac_llm_destroy(llm);
rac_shutdown();
| Option | Default | Description |
|---|---|---|
RAC_BUILD_JNI | OFF | Build JNI bridge for Android/JVM |
RAC_BUILD_TESTS | OFF | Build unit tests |
RAC_BUILD_SHARED | OFF | Build shared libraries (default: static) |
RAC_BUILD_PLATFORM | ON | Build platform backend (Apple FM, System TTS) |
RAC_BUILD_BACKENDS | OFF | Build ML backends |
RAC_BACKEND_LLAMACPP | ON | Build LlamaCPP backend (when BACKENDS=ON) |
RAC_BACKEND_ONNX | ON | Build ONNX backend (when BACKENDS=ON) |
RAC_BACKEND_WHISPERCPP | OFF | Build WhisperCPP backend (when BACKENDS=ON) |
./scripts/build-ios.sh # Full build
./scripts/build-ios.sh --skip-download # Use cached dependencies
./scripts/build-ios.sh --backend llamacpp # Specific backend only
./scripts/build-ios.sh --package # Create XCFramework ZIPs
./scripts/build-android.sh # All backends, all ABIs
./scripts/build-android.sh llamacpp # LlamaCPP only
./scripts/build-android.sh onnx arm64-v8a # Specific backend + ABI
./scripts/build-android.sh --check # Verify 16KB alignment
dist/
├── RACommons.xcframework # Core library
├── RABackendLLAMACPP.xcframework # LLM backend
└── RABackendONNX.xcframework # STT/TTS/VAD backend
dist/android/
├── jni/{abi}/ # JNI libraries
│ ├── librac_commons_jni.so
│ ├── librac_backend_llamacpp_jni.so
│ └── librac_backend_onnx_jni.so
└── onnx/{abi}/ # ONNX runtime
└── libonnxruntime.so
// Initialization
rac_result_t rac_init(const rac_config_t* config);
void rac_shutdown(void);
rac_bool_t rac_is_initialized(void);
rac_version_t rac_get_version(void);
// Module Registration
rac_result_t rac_module_register(const rac_module_info_t* info);
rac_result_t rac_module_unregister(const char* module_id);
rac_result_t rac_module_list(const rac_module_info_t** out_modules, size_t* out_count);
// Service Creation
rac_result_t rac_service_register_provider(const rac_service_provider_t* provider);
rac_result_t rac_service_create(rac_capability_t capability,
const rac_service_request_t* request,
rac_handle_t* out_handle);
rac_result_t rac_llm_create(const char* model_id, rac_handle_t* out_handle);
rac_result_t rac_llm_generate(rac_handle_t handle, const char* prompt,
const rac_llm_options_t* options, rac_llm_result_t* out_result);
rac_result_t rac_llm_generate_stream(rac_handle_t handle, const char* prompt,
const rac_llm_options_t* options,
rac_llm_stream_callback_fn callback, void* user_data);
rac_result_t rac_llm_cancel(rac_handle_t handle);
void rac_llm_destroy(rac_handle_t handle);
rac_result_t rac_stt_create(const char* model_path, rac_handle_t* out_handle);
rac_result_t rac_stt_transcribe(rac_handle_t handle, const void* audio_data, size_t audio_size,
const rac_stt_options_t* options, rac_stt_result_t* out_result);
rac_result_t rac_stt_transcribe_stream(rac_handle_t handle, const void* audio_data,
size_t audio_size, const rac_stt_options_t* options,
rac_stt_stream_callback_t callback, void* user_data);
void rac_stt_destroy(rac_handle_t handle);
rac_result_t rac_tts_create(const char* voice_id, rac_handle_t* out_handle);
rac_result_t rac_tts_synthesize(rac_handle_t handle, const char* text,
const rac_tts_options_t* options, rac_tts_result_t* out_result);
rac_result_t rac_tts_stop(rac_handle_t handle);
void rac_tts_destroy(rac_handle_t handle);
rac_result_t rac_vad_create(rac_handle_t* out_handle);
rac_result_t rac_vad_start(rac_handle_t handle);
rac_result_t rac_vad_stop(rac_handle_t handle);
rac_result_t rac_vad_process_samples(rac_handle_t handle, const float* samples,
size_t num_samples, rac_bool_t* out_is_speech);
void rac_vad_destroy(rac_handle_t handle);
rac_result_t rac_voice_agent_create_standalone(rac_voice_agent_handle_t* out_handle);
rac_result_t rac_voice_agent_load_stt_model(rac_voice_agent_handle_t handle,
const char* model_path, const char* model_id,
const char* model_name);
rac_result_t rac_voice_agent_load_llm_model(rac_voice_agent_handle_t handle,
const char* model_path, const char* model_id,
const char* model_name);
rac_result_t rac_voice_agent_load_tts_voice(rac_voice_agent_handle_t handle,
const char* voice_path, const char* voice_id,
const char* voice_name);
rac_result_t rac_voice_agent_process_voice_turn(rac_voice_agent_handle_t handle,
const void* audio_data, size_t audio_size,
rac_voice_agent_result_t* out_result);
void rac_voice_agent_destroy(rac_voice_agent_handle_t handle);
The Swift SDK (runanywhere-swift) integrates via the CRACommons module:
SwiftPlatformAdapter provides platform callbacks (storage, logging)CommonsErrorMapping converts rac_result_t to Swift SDKErrorEventBridge subscribes to C++ events, republishes to Swift EventBusThe Kotlin SDK (runanywhere-kotlin) integrates via JNI:
librac_*_jni.soPlatform SDKs must provide a rac_platform_adapter_t with callbacks for:
typedef struct rac_platform_adapter {
// File operations
rac_bool_t (*file_exists)(const char* path, void* user_data);
rac_result_t (*file_read)(const char* path, void** out_data, size_t* out_size, void* user_data);
rac_result_t (*file_write)(const char* path, const void* data, size_t size, void* user_data);
// Secure storage
rac_result_t (*secure_get)(const char* key, char** out_value, void* user_data);
rac_result_t (*secure_set)(const char* key, const char* value, void* user_data);
// Logging
void (*log)(rac_log_level_t level, const char* category, const char* message, void* user_data);
// Time
int64_t (*now_ms)(void* user_data);
// Optional: HTTP download, archive extraction
// ...
void* user_data;
} rac_platform_adapter_t;
| Dependency | Version | Purpose |
|---|---|---|
| llama.cpp | b7650 | LLM inference engine |
| Sherpa-ONNX | 1.12.18+ | STT/TTS/VAD via ONNX Runtime |
| ONNX Runtime | 1.17.1+ | Neural network inference |
| nlohmann/json | 3.11.3 | JSON parsing |
| Framework | Size | Provides |
|---|---|---|
RACommons.xcframework | ~2MB | Core infrastructure, registries, events |
RABackendLLAMACPP.xcframework | ~15-25MB | LLM capability (GGUF models) |
RABackendONNX.xcframework | ~50-70MB | STT, TTS, VAD (ONNX models) |
All versions are centralized in the VERSIONS file:
PROJECT_VERSION=1.0.0
IOS_DEPLOYMENT_TARGET=13.0
ANDROID_MIN_SDK=24
ONNX_VERSION_IOS=1.17.1
SHERPA_ONNX_VERSION_IOS=1.12.18
LLAMACPP_VERSION=b7650
Load versions in scripts:
source scripts/load-versions.sh
echo "Using llama.cpp version: $LLAMACPP_VERSION"
Load versions in CMake:
include(LoadVersions)
message(STATUS "ONNX Runtime version: ${ONNX_VERSION_IOS}")
Error codes are organized by range:
| Range | Category |
|---|---|
| 0 | Success |
| -100 to -109 | Initialization errors |
| -110 to -129 | Model errors |
| -130 to -149 | Generation errors |
| -150 to -179 | Network errors |
| -180 to -219 | Storage errors |
| -220 to -229 | Hardware errors |
| -230 to -249 | Component state errors |
| -250 to -279 | Validation errors |
| -280 to -299 | Audio errors |
| -300 to -319 | Language/Voice errors |
| -400 to -499 | Module/Service errors |
| -600 to -699 | Backend errors |
| -700 to -799 | Event errors |
See the main repository CONTRIBUTING.md for guidelines.
./scripts/lint-cpp.sh --fix before committingrac_ prefixSee LICENSE for details.