From b9b1c3127caabcd9e21e88c23099b0e9326085c7 Mon Sep 17 00:00:00 2001 From: Ibrahim Mubarak <47777720+ibrahim-mubarak@users.noreply.github.com> Date: Sat, 4 Jul 2026 16:05:14 +0530 Subject: [PATCH] feat: support cross-compilation (tested for 32-bit ARM Linux) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three changes needed to build the SDK with a CMake toolchain file for a foreign target (verified with armv7-unknown-linux-gnueabihf against an embedded armv8 AArch32 / Cortex-A32 sysroot): - CMakeLists.txt: honor a RUST_TARGET_TRIPLE already set in the cache (e.g. by a cross toolchain file) instead of deriving it only for macOS; cargo then builds livekit-ffi with --target and the imported liblivekit_ffi.so location follows target//. - CMakeLists.txt: scope the cargo invocation to -p livekit-ffi. The workspace has no default-members, so a bare 'cargo build' also builds every example (including GPU-dependent ones) which is wasted work natively and fails when cross-compiling. - cmake/protobuf.cmake: when CMAKE_CROSSCOMPILING, don't force protobuf_BUILD_PROTOC_BINARIES=ON — a cross-compiled protoc cannot run on the build host. Require a host protoc (matching the vendored protobuf version) via -DProtobuf_PROTOC_EXECUTABLE instead; it is also forwarded to the Rust build through ENV{PROTOC}. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01L4fDRyTiTphQnidL2Myptq --- CMakeLists.txt | 7 +++++-- cmake/protobuf.cmake | 30 +++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e4aeaeb1..6364d559 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,7 +215,10 @@ configure_file( find_program(CARGO_EXECUTABLE NAMES cargo REQUIRED) # Determine Rust target triple for cross-compilation on macOS -set(RUST_TARGET_TRIPLE "") +# (may also be pre-set by a cross toolchain file, e.g. cross/toolchain-ameba-armv7.cmake) +if(NOT DEFINED RUST_TARGET_TRIPLE) + set(RUST_TARGET_TRIPLE "") +endif() if(APPLE AND CMAKE_OSX_ARCHITECTURES) if(CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64") set(RUST_TARGET_TRIPLE "x86_64-apple-darwin") @@ -256,7 +259,7 @@ if(NOT DEFINED CARGO) message(FATAL_ERROR \"CARGO not set\") endif() -set(ARGS build) +set(ARGS build -p livekit-ffi) if(NOT CFG STREQUAL \"Debug\") list(APPEND ARGS --release) endif() diff --git a/cmake/protobuf.cmake b/cmake/protobuf.cmake index 3e0fa33c..5eda24a1 100644 --- a/cmake/protobuf.cmake +++ b/cmake/protobuf.cmake @@ -149,7 +149,19 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "" FORCE) set(protobuf_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(protobuf_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(protobuf_BUILD_CONFORMANCE OFF CACHE BOOL "" FORCE) -set(protobuf_BUILD_PROTOC_BINARIES ON CACHE BOOL "" FORCE) +if(CMAKE_CROSSCOMPILING) + # protoc must run on the build host, so don't cross-compile it; a host + # protoc matching LIVEKIT_PROTOBUF_VERSION must be provided instead via + # -DProtobuf_PROTOC_EXECUTABLE. + set(protobuf_BUILD_PROTOC_BINARIES OFF CACHE BOOL "" FORCE) + if(NOT Protobuf_PROTOC_EXECUTABLE) + message(FATAL_ERROR + "Cross-compiling: pass -DProtobuf_PROTOC_EXECUTABLE=") + endif() +else() + set(protobuf_BUILD_PROTOC_BINARIES ON CACHE BOOL "" FORCE) +endif() set(protobuf_WITH_ZLIB OFF CACHE BOOL "" FORCE) set(protobuf_ABSL_PROVIDER "package" CACHE STRING "" FORCE) @@ -198,12 +210,16 @@ foreach(_livekit_protobuf_target IN LISTS _livekit_protobuf_targets) endforeach() # Protobuf targets: modern protobuf exports protobuf::protoc etc. -if(TARGET protobuf::protoc) - set(Protobuf_PROTOC_EXECUTABLE "$" CACHE STRING "protoc (vendored)" FORCE) -elseif(TARGET protoc) - set(Protobuf_PROTOC_EXECUTABLE "$" CACHE STRING "protoc (vendored)" FORCE) -else() - message(FATAL_ERROR "Vendored protobuf did not create a protoc target") +# When cross-compiling, protoc binaries are not built; the host protoc +# supplied via Protobuf_PROTOC_EXECUTABLE is used as-is. +if(NOT CMAKE_CROSSCOMPILING) + if(TARGET protobuf::protoc) + set(Protobuf_PROTOC_EXECUTABLE "$" CACHE STRING "protoc (vendored)" FORCE) + elseif(TARGET protoc) + set(Protobuf_PROTOC_EXECUTABLE "$" CACHE STRING "protoc (vendored)" FORCE) + else() + message(FATAL_ERROR "Vendored protobuf did not create a protoc target") + endif() endif() # Prefer protobuf-lite (optional; keep libprotobuf around too)