Skip to content

Commit 3ac04c8

Browse files
refactor: fold RAG backend into rac_commons, remove separate RAG binary
- Changed rac_backend_rag from SHARED/STATIC to OBJECT library (CMake) - RAG objects folded into rac_commons at compile time - Moved ONNX embedding provider to rac_backend_onnx to break shared-lib cycle - ONNX backend now registers embeddings provider during rac_backend_onnx_register() - Removed RAG as separate backend from all build scripts and SDK configs - Updated Android, Kotlin, Flutter, React Native build/distribution pipelines - RAG JNI bridge (librac_backend_rag_jni.so) remains as thin wrapper linking rac_commons
1 parent 2f9423b commit 3ac04c8

17 files changed

Lines changed: 119 additions & 348 deletions

File tree

sdk/runanywhere-commons/CMakeLists.txt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,23 @@ if(RAC_BUILD_BACKENDS)
412412
endif()
413413

414414
if(RAC_BACKEND_RAG AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/features/rag/CMakeLists.txt")
415-
message(STATUS " - RAG pipeline (USearch)")
415+
message(STATUS " - RAG pipeline (USearch) — folded into rac_commons")
416416
add_subdirectory(src/features/rag)
417+
418+
# RAG is an OBJECT library. Fold its compiled objects into rac_commons
419+
# so there is no separate librac_backend_rag binary to distribute.
420+
target_sources(rac_commons PRIVATE $<TARGET_OBJECTS:rac_backend_rag>)
421+
422+
# Propagate RAG's non-cyclic dependencies manually.
423+
# We intentionally do NOT use target_link_libraries(rac_commons PRIVATE rac_backend_rag)
424+
# because that would transitively pull in rac_backend_onnx (via the ONNX embedding
425+
# provider) and create a shared-library cycle:
426+
# rac_commons -> rac_backend_rag -> rac_backend_onnx -> rac_commons
427+
# nlohmann_json is already linked project-wide (line 116).
428+
# Apple frameworks used by RAG (Accelerate) need explicit propagation.
429+
if(APPLE)
430+
target_link_libraries(rac_commons PUBLIC "-framework Accelerate")
431+
endif()
417432
endif()
418433
endif()
419434

@@ -480,7 +495,10 @@ if(APPLE AND RAC_BUILD_PLATFORM)
480495
message(STATUS " Platform: Apple Foundation Models, System TTS")
481496
endif()
482497
if(RAC_BUILD_BACKENDS)
483-
message(STATUS " Backends: LlamaCPP=${RAC_BACKEND_LLAMACPP}, ONNX=${RAC_BACKEND_ONNX}, WhisperCPP=${RAC_BACKEND_WHISPERCPP}, WhisperKitCoreML=${RAC_BACKEND_WHISPERKIT_COREML}, RAG=${RAC_BACKEND_RAG}")
498+
message(STATUS " Backends: LlamaCPP=${RAC_BACKEND_LLAMACPP}, ONNX=${RAC_BACKEND_ONNX}, WhisperCPP=${RAC_BACKEND_WHISPERCPP}, WhisperKitCoreML=${RAC_BACKEND_WHISPERKIT_COREML}")
499+
if(RAC_BACKEND_RAG)
500+
message(STATUS " RAG pipeline: Enabled (folded into rac_commons)")
501+
endif()
484502
endif()
485503
if(RAC_BUILD_SERVER)
486504
message(STATUS " Server: OpenAI-compatible HTTP server (runanywhere-server)")

sdk/runanywhere-commons/scripts/build-android.sh

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Unified Android build script - builds JNI bridge + selected backends
66
#
77
# Usage: ./build-android.sh [options] [backends] [abis]
8-
# backends: onnx | llamacpp | whispercpp | tflite | rag | all (default: all)
8+
# backends: onnx | llamacpp | whispercpp | tflite | all (default: all)
99
# - onnx: STT/TTS/VAD (Sherpa-ONNX models)
1010
# - llamacpp: LLM text generation (GGUF models)
1111
# - all: onnx + llamacpp (default)
@@ -210,16 +210,13 @@ BUILD_ONNX=OFF
210210
BUILD_LLAMACPP=OFF
211211
BUILD_WHISPERCPP=OFF
212212
BUILD_TFLITE=OFF
213-
BUILD_RAG=OFF
214-
215-
VALID_BACKENDS="onnx llamacpp whispercpp tflite rag all"
213+
VALID_BACKENDS="onnx llamacpp whispercpp tflite all"
216214

217215
if [[ "$BACKENDS" == "all" ]]; then
218216
# NOTE: WhisperCPP is deprecated - use ONNX for STT instead
219217
# WhisperCPP has build issues with newer ggml versions (GGML_KQ_MASK_PAD)
220218
BUILD_ONNX=ON
221219
BUILD_LLAMACPP=ON
222-
BUILD_RAG=ON
223220
BUILD_WHISPERCPP=OFF
224221
else
225222
# Parse comma-separated backends list
@@ -230,11 +227,10 @@ else
230227
llamacpp) BUILD_LLAMACPP=ON ;;
231228
whispercpp) BUILD_WHISPERCPP=ON ;;
232229
tflite) BUILD_TFLITE=ON ;;
233-
rag) BUILD_RAG=ON ;;
234230
*)
235231
print_error "Unknown backend: $backend"
236232
echo "Usage: $0 [backends] [abis]"
237-
echo " backends: onnx | llamacpp | whispercpp | tflite | rag | all"
233+
echo " backends: onnx | llamacpp | whispercpp | tflite | all"
238234
echo " abis: comma-separated list (default: arm64-v8a)"
239235
exit 1
240236
;;
@@ -249,7 +245,6 @@ SINGLE_BACKEND=""
249245
[[ "$BUILD_LLAMACPP" == "ON" ]] && ((ENABLED_COUNT++)) && SINGLE_BACKEND="llamacpp"
250246
[[ "$BUILD_WHISPERCPP" == "ON" ]] && ((ENABLED_COUNT++)) && SINGLE_BACKEND="whispercpp"
251247
[[ "$BUILD_TFLITE" == "ON" ]] && ((ENABLED_COUNT++)) && SINGLE_BACKEND="tflite"
252-
[[ "$BUILD_RAG" == "ON" ]] && ((ENABLED_COUNT++)) && SINGLE_BACKEND="rag"
253248

254249
if [[ "$ENABLED_COUNT" -eq 1 ]]; then
255250
DIST_SUBDIR="$SINGLE_BACKEND"
@@ -258,7 +253,7 @@ else
258253
fi
259254

260255
print_header "RunAnywhere Android Build (Unified)"
261-
echo "Backends: ONNX=$BUILD_ONNX, LlamaCPP=$BUILD_LLAMACPP, WhisperCPP=$BUILD_WHISPERCPP, TFLite=$BUILD_TFLITE, RAG=$BUILD_RAG"
256+
echo "Backends: ONNX=$BUILD_ONNX, LlamaCPP=$BUILD_LLAMACPP, WhisperCPP=$BUILD_WHISPERCPP, TFLite=$BUILD_TFLITE"
262257
echo "ABIs: ${ABIS}"
263258
echo "Android API Level: ${ANDROID_API_LEVEL}"
264259
echo "Output: dist/android/${DIST_SUBDIR}/"
@@ -360,7 +355,7 @@ for ABI in "${ABI_ARRAY[@]}"; do
360355
-DRAC_BACKEND_ONNX=${BUILD_ONNX} \
361356
-DRAC_BACKEND_LLAMACPP=${BUILD_LLAMACPP} \
362357
-DRAC_BACKEND_WHISPERCPP=${BUILD_WHISPERCPP} \
363-
-DRAC_BACKEND_RAG=${BUILD_RAG} \
358+
-DRAC_BACKEND_RAG=ON \
364359
-DRAC_BUILD_TESTS=OFF \
365360
-DRAC_BUILD_SHARED=ON \
366361
-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON \
@@ -590,19 +585,11 @@ for ABI in "${ABI_ARRAY[@]}"; do
590585
fi
591586
fi
592587

593-
# RAG pipeline
594-
mkdir -p "${DIST_DIR}/rag/${ABI}"
595-
if [ -f "${ABI_BUILD_DIR}/src/features/rag/librac_backend_rag.so" ]; then
596-
cp "${ABI_BUILD_DIR}/src/features/rag/librac_backend_rag.so" "${DIST_DIR}/rag/${ABI}/"
597-
echo " Copied: librac_backend_rag.so -> rag/${ABI}/"
598-
fi
599-
600-
# Copy JNI bridge library for RAG
588+
# RAG JNI bridge (RAG pipeline is compiled into librac_commons.so;
589+
# the JNI bridge is still a thin separate .so that links against rac_commons)
601590
if [ -f "${ABI_BUILD_DIR}/src/features/rag/librac_backend_rag_jni.so" ]; then
602-
cp "${ABI_BUILD_DIR}/src/features/rag/librac_backend_rag_jni.so" "${DIST_DIR}/rag/${ABI}/"
603-
echo " Copied: librac_backend_rag_jni.so -> rag/${ABI}/"
604-
else
605-
print_warning "librac_backend_rag_jni.so not found - JNI bridge not built by CMake"
591+
cp "${ABI_BUILD_DIR}/src/features/rag/librac_backend_rag_jni.so" "${JNI_DIST_DIR}/${ABI}/"
592+
echo " Copied: librac_backend_rag_jni.so -> jni/${ABI}/"
606593
fi
607594

608595
# TFLite backend
@@ -712,13 +699,6 @@ if [ "$BUILD_WHISPERCPP" = "ON" ]; then
712699
done
713700
fi
714701

715-
echo "├── rag/ # RAG pipeline libraries"
716-
for ABI in "${ABI_ARRAY[@]}"; do
717-
echo "│ └── ${ABI}/"
718-
echo "│ ├── librac_backend_rag.so"
719-
echo "│ └── librac_backend_rag_jni.so"
720-
done
721-
722702
if [ "$BUILD_TFLITE" = "ON" ]; then
723703
echo "└── tflite/ # TFLite backend libraries"
724704
for ABI in "${ABI_ARRAY[@]}"; do
@@ -747,9 +727,6 @@ if [ "$BUILD_WHISPERCPP" = "ON" ]; then
747727
ls -lh "${DIST_DIR}/whispercpp"/*/*.so 2>/dev/null | awk '{print " " $NF ": " $5}' || echo " (no files)"
748728
fi
749729

750-
echo " RAG:"
751-
ls -lh "${DIST_DIR}/rag"/*/*.so 2>/dev/null | awk '{print " " $NF ": " $5}' || echo " (no files)"
752-
753730
echo ""
754731
echo -e "${GREEN}Build complete!${NC}"
755732

sdk/runanywhere-commons/scripts/build-ios.sh

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -729,43 +729,11 @@ main() {
729729
build_macos
730730
fi
731731

732-
# Step 3: Merge RAG pipeline into rac_commons (RAG is a feature, not a separate backend)
733-
if [[ "$SKIP_BACKENDS" != true ]]; then
734-
log_step "Merging RAG pipeline into rac_commons..."
735-
local MERGE_PLATFORMS="OS SIMULATORARM64 SIMULATOR"
736-
if [[ "$INCLUDE_MACOS" == true ]]; then
737-
MERGE_PLATFORMS="$MERGE_PLATFORMS MACOS"
738-
fi
739-
for PLATFORM in $MERGE_PLATFORMS; do
740-
local PLATFORM_DIR="${BUILD_DIR}/${PLATFORM}"
741-
local COMMONS_LIB="${PLATFORM_DIR}/librac_commons.a"
742-
local RAG_LIB=""
743-
744-
for possible_path in \
745-
"${PLATFORM_DIR}/src/features/rag/librac_backend_rag.a" \
746-
"${PLATFORM_DIR}/src/backends/rag/librac_backend_rag.a" \
747-
"${PLATFORM_DIR}/librac_backend_rag.a"; do
748-
if [[ -f "$possible_path" ]]; then
749-
RAG_LIB="$possible_path"
750-
break
751-
fi
752-
done
753-
754-
if [[ -n "$RAG_LIB" && -f "$COMMONS_LIB" ]]; then
755-
libtool -static -o "${COMMONS_LIB}.merged" "$COMMONS_LIB" "$RAG_LIB"
756-
mv "${COMMONS_LIB}.merged" "$COMMONS_LIB"
757-
log_info " ${PLATFORM}: Merged librac_backend_rag.a into librac_commons.a"
758-
elif [[ -f "$COMMONS_LIB" ]]; then
759-
log_warn " ${PLATFORM}: librac_backend_rag.a not found — RAG not merged"
760-
fi
761-
done
762-
fi
763-
764-
# Step 4: Create RACommons.xcframework (now includes RAG pipeline)
732+
# Step 3: Create RACommons.xcframework (includes RAG pipeline via CMake OBJECT library)
765733
log_header "Creating XCFrameworks"
766734
create_xcframework "rac_commons" "RACommons"
767735

768-
# Step 5: Create backend XCFrameworks
736+
# Step 4: Create backend XCFrameworks
769737
if [[ "$SKIP_BACKENDS" != true ]]; then
770738
if [[ "$BUILD_BACKEND" == "all" || "$BUILD_BACKEND" == "llamacpp" ]]; then
771739
create_backend_xcframework "llamacpp" "RABackendLLAMACPP"

sdk/runanywhere-commons/src/backends/onnx/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,17 @@ set(ONNX_BACKEND_SOURCES
180180
wakeword_onnx.cpp
181181
)
182182

183+
# ONNX embedding provider lives in src/features/rag/ but is compiled here
184+
# to avoid a shared-library cycle: rac_commons -> rac_backend_rag -> rac_backend_onnx -> rac_commons.
185+
set(RAG_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../features/rag")
186+
if(RAC_BACKEND_RAG AND EXISTS "${RAG_DIR}/onnx_embedding_provider.cpp")
187+
list(APPEND ONNX_BACKEND_SOURCES
188+
${RAG_DIR}/onnx_embedding_provider.cpp
189+
${RAG_DIR}/rac_onnx_embeddings_register.cpp
190+
)
191+
message(STATUS " ONNX embedding provider: Compiled into rac_backend_onnx (from RAG dir)")
192+
endif()
193+
183194
set(ONNX_BACKEND_HEADERS
184195
onnx_backend.h
185196
)
@@ -199,6 +210,11 @@ target_include_directories(rac_backend_onnx PUBLIC
199210
${RAC_COMMONS_ROOT_DIR}/include/rac/backends
200211
)
201212

213+
# RAG embedding provider headers (onnx_embedding_provider.h lives in features/rag/)
214+
if(RAC_BACKEND_RAG AND EXISTS "${RAG_DIR}/onnx_embedding_provider.h")
215+
target_include_directories(rac_backend_onnx PRIVATE ${RAG_DIR})
216+
endif()
217+
202218
# Define RAC_ONNX_BUILDING to export symbols with visibility("default")
203219
# Define RAC_HAS_ONNX to enable ONNX Runtime code paths
204220
target_compile_definitions(rac_backend_onnx PRIVATE RAC_ONNX_BUILDING RAC_HAS_ONNX)

sdk/runanywhere-commons/src/backends/onnx/rac_backend_onnx_register.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "rac_stt_onnx.h"
1010
#include "rac_tts_onnx.h"
1111
#include "rac_vad_onnx.h"
12+
#include "rac/backends/rac_embeddings_onnx.h"
1213

1314
#include <cstdint>
1415
#include <cstdlib>
@@ -553,8 +554,14 @@ rac_result_t rac_backend_onnx_register(void) {
553554
return result;
554555
}
555556

557+
// Register ONNX embeddings provider (for RAG pipeline).
558+
// The provider code is compiled into this backend; registration was
559+
// previously done by rac_backend_rag_register() when the sources lived
560+
// in the RAG OBJECT library.
561+
rac_backend_onnx_embeddings_register();
562+
556563
g_registered = true;
557-
RAC_LOG_INFO(LOG_CAT, "ONNX backend registered (STT + TTS + VAD)");
564+
RAC_LOG_INFO(LOG_CAT, "ONNX backend registered (STT + TTS + VAD + Embeddings)");
558565
return RAC_SUCCESS;
559566
}
560567

@@ -563,6 +570,7 @@ rac_result_t rac_backend_onnx_unregister(void) {
563570
return RAC_ERROR_MODULE_NOT_FOUND;
564571
}
565572

573+
rac_backend_onnx_embeddings_unregister();
566574
rac_model_strategy_unregister(RAC_FRAMEWORK_ONNX);
567575
rac_service_unregister_provider(VAD_PROVIDER_NAME, RAC_CAPABILITY_VAD);
568576
rac_service_unregister_provider(TTS_PROVIDER_NAME, RAC_CAPABILITY_TTS);

sdk/runanywhere-commons/src/features/rag/CMakeLists.txt

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ if(NOT TARGET nlohmann_json::nlohmann_json)
5050
endif()
5151

5252
# =============================================================================
53-
# RAG Pipeline Library (no direct backend dependencies)
53+
# RAG Pipeline Library (OBJECT — folded into rac_commons at link time)
54+
#
55+
# Built as OBJECT so all RAG symbols end up inside librac_commons.{a,so}.
56+
# There is no separate librac_backend_rag binary to distribute.
5457
# =============================================================================
5558

5659
set(RAG_PIPELINE_SOURCES
@@ -62,13 +65,10 @@ set(RAG_PIPELINE_SOURCES
6265
rac_rag_pipeline.cpp
6366
)
6467

65-
# ONNX embedding provider — wraps as a proper embeddings service backend
66-
if(TARGET rac_backend_onnx)
67-
list(APPEND RAG_PIPELINE_SOURCES
68-
onnx_embedding_provider.cpp
69-
rac_onnx_embeddings_register.cpp
70-
)
71-
endif()
68+
# ONNX embedding provider (onnx_embedding_provider.cpp, rac_onnx_embeddings_register.cpp)
69+
# is compiled into rac_backend_onnx instead of this OBJECT library to avoid a
70+
# shared-library cycle: rac_commons -> rac_backend_rag -> rac_backend_onnx -> rac_commons.
71+
# See src/backends/onnx/CMakeLists.txt for where these sources are compiled.
7272

7373
set(RAG_PIPELINE_HEADERS
7474
rag_backend.h
@@ -77,11 +77,7 @@ set(RAG_PIPELINE_HEADERS
7777
bm25_index.h
7878
)
7979

80-
if(RAC_BUILD_SHARED)
81-
add_library(rac_backend_rag SHARED ${RAG_PIPELINE_SOURCES} ${RAG_PIPELINE_HEADERS})
82-
else()
83-
add_library(rac_backend_rag STATIC ${RAG_PIPELINE_SOURCES} ${RAG_PIPELINE_HEADERS})
84-
endif()
80+
add_library(rac_backend_rag OBJECT ${RAG_PIPELINE_SOURCES} ${RAG_PIPELINE_HEADERS})
8581

8682
target_include_directories(rac_backend_rag PUBLIC
8783
${CMAKE_CURRENT_SOURCE_DIR}
@@ -90,18 +86,12 @@ target_include_directories(rac_backend_rag PUBLIC
9086
${usearch_SOURCE_DIR}/include
9187
)
9288

93-
# RAG links against rac_commons for vtable dispatch — NOT against backend libraries
89+
# nlohmann_json is used by RAG for config parsing.
90+
# It's header-only (INTERFACE lib) so no link-time cost.
9491
target_link_libraries(rac_backend_rag PUBLIC
95-
rac_commons
9692
nlohmann_json::nlohmann_json
9793
)
9894

99-
# ONNX embedding provider needs ONNX Runtime headers for inference
100-
if(TARGET rac_backend_onnx)
101-
target_link_libraries(rac_backend_rag PUBLIC rac_backend_onnx)
102-
target_compile_definitions(rac_backend_rag PRIVATE RAG_HAS_ONNX_PROVIDER=1)
103-
endif()
104-
10595
target_compile_definitions(rac_backend_rag PRIVATE RAC_RAG_BUILDING)
10696

10797
set_target_properties(rac_backend_rag PROPERTIES
@@ -133,10 +123,8 @@ if(RAC_PLATFORM_IOS)
133123

134124
elseif(RAC_PLATFORM_ANDROID)
135125
message(STATUS "Configuring RAG pipeline for Android")
136-
target_link_libraries(rac_backend_rag PRIVATE log)
137126
target_compile_definitions(rac_backend_rag PRIVATE ORT_API_VERSION=17)
138127
target_compile_options(rac_backend_rag PRIVATE -O3 -ffunction-sections -fdata-sections)
139-
target_link_options(rac_backend_rag PRIVATE -Wl,--gc-sections -Wl,-z,max-page-size=16384)
140128

141129
elseif(RAC_PLATFORM_MACOS)
142130
message(STATUS "Configuring RAG pipeline for macOS")
@@ -172,8 +160,9 @@ if(RAC_PLATFORM_ANDROID AND RAC_BUILD_SHARED)
172160
${RAC_COMMONS_ROOT_DIR}/include
173161
)
174162

163+
# RAG symbols live in rac_commons (the OBJECT lib was folded in)
175164
target_link_libraries(rac_backend_rag_jni PRIVATE
176-
rac_backend_rag
165+
rac_commons
177166
log
178167
)
179168

sdk/runanywhere-commons/tests/CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ endif()
113113
# RAG Pipeline Tests (GoogleTest)
114114
# =============================================================================
115115

116-
if(RAC_BACKEND_RAG AND TARGET rac_backend_rag)
116+
if(RAC_BACKEND_RAG)
117117
include(FetchContent)
118118
find_package(Threads REQUIRED)
119119

@@ -133,7 +133,7 @@ if(RAC_BACKEND_RAG AND TARGET rac_backend_rag)
133133
)
134134
target_link_libraries(rac_rag_backend_thread_safety_test
135135
PRIVATE
136-
rac_backend_rag
136+
rac_commons
137137
Threads::Threads
138138
GTest::gtest_main
139139
)
@@ -153,7 +153,7 @@ if(RAC_BACKEND_RAG AND TARGET rac_backend_rag)
153153
)
154154
target_link_libraries(rac_chunker_test
155155
PRIVATE
156-
rac_backend_rag
156+
rac_commons
157157
Threads::Threads
158158
GTest::gtest_main
159159
)
@@ -172,7 +172,7 @@ if(RAC_BACKEND_RAG AND TARGET rac_backend_rag)
172172
)
173173
target_link_libraries(rac_simple_tokenizer_test
174174
PRIVATE
175-
rac_backend_rag
175+
rac_commons
176176
Threads::Threads
177177
GTest::gtest_main
178178
)

0 commit comments

Comments
 (0)