Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ jobs:
$examples = @('SimpleRoom', 'SimpleRpc', 'SimpleDataStream')
$failed = $false
foreach ($exe in $examples) {
$exePath = "${{ matrix.build_dir }}/bin/Release/${exe}.exe"
$exePath = "${{ matrix.build_dir }}/bin/${exe}.exe"
if (Test-Path $exePath) {
Write-Host "Testing ${exe}..."
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
Expand Down
107 changes: 67 additions & 40 deletions .github/workflows/make-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ jobs:
- os: macos-latest
name: macos-arm64
generator: Ninja
macos_arch: arm64
- os: macos-latest
name: macos-x64
generator: Ninja
macos_arch: x86_64
- os: windows-latest
name: windows-x64
generator: "Visual Studio 17 2022"
Expand Down Expand Up @@ -85,9 +80,14 @@ jobs:
sudo apt-get install -y \
build-essential cmake ninja-build pkg-config \
llvm-dev libclang-dev clang \
libva-dev libdrm-dev libgbm-dev libx11-dev libgl1-mesa-dev \
libxext-dev libxcomposite-dev libxdamage-dev libxfixes-dev \
libxrandr-dev libxi-dev libxkbcommon-dev \
libasound2-dev libpulse-dev \
libssl-dev \
libprotobuf-dev protobuf-compiler \
libabsl-dev
libabsl-dev \
libwayland-dev libdecor-0-dev

- name: Install deps (macOS)
if: runner.os == 'macOS'
Expand Down Expand Up @@ -125,55 +125,49 @@ jobs:
shell: bash
run: |
chmod +x build.sh
args=(release -G "${{ matrix.generator }}" \
--version "${{ steps.version.outputs.version }}" \
--bundle --prefix "sdk-out/livekit-sdk-${{ matrix.name }}")
if [[ "${{ runner.os }}" == "macOS" && -n "${{ matrix.macos_arch }}" ]]; then
args+=(--macos-arch "${{ matrix.macos_arch }}")
fi
./build.sh "${args[@]}"
./build.sh release-examples

# Create bundle directory with version in name
bundleDir="sdk-out/livekit-sdk-${{ matrix.name }}-${{ steps.version.outputs.version }}"
mkdir -p "$bundleDir/lib"
mkdir -p "$bundleDir/include"
mkdir -p "$bundleDir/bin"

# Copy files
cp -r build-release/lib/* "$bundleDir/lib/" 2>/dev/null || true
cp -r build-release/include/* "$bundleDir/include/" 2>/dev/null || true
cp -r build-release/bin/* "$bundleDir/bin/" 2>/dev/null || true

# List bundle contents
echo "Bundle contents:"
find "$bundleDir" -type f | head -50

# ---------- Build + Bundle (Windows) ----------
- name: Build and Bundle (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
# Build release
.\build.cmd release
# Build release with examples
.\build.cmd release-examples

# Create bundle directory
$bundleDir = "sdk-out/livekit-sdk-${{ matrix.name }}"
# Create bundle directory with version in name
$bundleDir = "sdk-out/livekit-sdk-${{ matrix.name }}-${{ steps.version.outputs.version }}"
New-Item -ItemType Directory -Force -Path $bundleDir
New-Item -ItemType Directory -Force -Path "$bundleDir/lib"
New-Item -ItemType Directory -Force -Path "$bundleDir/include"
New-Item -ItemType Directory -Force -Path "$bundleDir/bin"

# Copy files
Copy-Item -Recurse -Force "build-release/lib/*" "$bundleDir/lib/"
Copy-Item -Recurse -Force "build-release/include/*" "$bundleDir/include/"
Copy-Item -Recurse -Force "build-release/bin/*" "$bundleDir/bin/"

# ---------- Create archive ----------
- name: Archive (Unix)
if: runner.os != 'Windows'
shell: bash
run: |
cd sdk-out
tar -czf "../livekit-sdk-${{ matrix.name }}-${{ steps.version.outputs.version }}.tar.gz" "livekit-sdk-${{ matrix.name }}"

- name: Archive (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Compress-Archive -Path "sdk-out/livekit-sdk-${{ matrix.name }}/*" `
-DestinationPath "livekit-sdk-${{ matrix.name }}-${{ steps.version.outputs.version }}.zip"

# ---------- Upload artifact ----------
# ---------- Upload artifact (raw directory, no pre-compression) ----------
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: sdk-${{ matrix.name }}
path: |
livekit-sdk-${{ matrix.name }}-*.tar.gz
livekit-sdk-${{ matrix.name }}-*.zip
name: livekit-sdk-${{ matrix.name }}-${{ steps.version.outputs.version }}
path: sdk-out/livekit-sdk-${{ matrix.name }}-${{ steps.version.outputs.version }}

# ---------- Release Job ----------
release:
Expand Down Expand Up @@ -204,9 +198,42 @@ jobs:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
pattern: sdk-*
merge-multiple: true
path: ${{ github.workspace }}/release-assets
path: ${{ github.workspace }}/artifacts

- name: List downloaded artifacts
run: |
echo "Downloaded artifacts structure:"
find ${{ github.workspace }}/artifacts -type f | head -100

# ---------- Create archives in release job ----------
- name: Create release archives
shell: bash
run: |
mkdir -p release-assets
VERSION="${{ steps.version.outputs.version }}"
cd ${{ github.workspace }}/artifacts

# List what we have
echo "Artifacts downloaded:"
ls -la

# Create tar.gz for Linux and macOS
for platform in linux-x64 macos-arm64; do
dirName="livekit-sdk-${platform}-${VERSION}"
if [[ -d "${dirName}" ]]; then
echo "Creating archive for ${platform}..."
tar -czf "${{ github.workspace }}/release-assets/${dirName}.tar.gz" "${dirName}"
echo "Created: ${dirName}.tar.gz"
fi
done

# Create zip for Windows
dirName="livekit-sdk-windows-x64-${VERSION}"
if [[ -d "${dirName}" ]]; then
echo "Creating archive for windows-x64..."
zip -r "${{ github.workspace }}/release-assets/${dirName}.zip" "${dirName}"
echo "Created: ${dirName}.zip"
fi

- name: List release assets
run: ls -la ${{ github.workspace }}/release-assets/
Expand Down
106 changes: 65 additions & 41 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,43 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Set RPATH for Unix systems to find shared libraries in executable directory
if(UNIX)
# Use $ORIGIN on Linux, @executable_path on macOS
if(APPLE)
set(CMAKE_BUILD_RPATH "@executable_path")
set(CMAKE_INSTALL_RPATH "@executable_path")
else()
set(CMAKE_BUILD_RPATH "$ORIGIN")
set(CMAKE_INSTALL_RPATH "$ORIGIN")
endif()
set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
endif()

if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(LIVEKIT_IS_TOPLEVEL TRUE)
else()
set(LIVEKIT_IS_TOPLEVEL FALSE)
endif()

if(LIVEKIT_IS_TOPLEVEL)
if(WIN32)
set(PLATFORM_DIR "windows-x64")
elseif(APPLE)
set(PLATFORM_DIR "macos-universal")
elseif(UNIX)
set(PLATFORM_DIR "linux-x64")
else()
set(PLATFORM_DIR "unknown")
endif()

if(WIN32)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${PLATFORM_DIR}/$<LOWER_CASE:$<CONFIG>>)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${PLATFORM_DIR}/$<LOWER_CASE:$<CONFIG>>)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/$<LOWER_CASE:$<CONFIG>>)
else()
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${PLATFORM_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${PLATFORM_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
endif()
# Since we use separate build directories (build-debug/build-release),
# we don't need additional platform/config subdirectories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

# For multi-config generators (Visual Studio), override per-config directories
# to prevent adding Debug/Release subdirectories
foreach(CONFIG_TYPE Debug Release RelWithDebInfo MinSizeRel)
string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE_UPPER)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${CMAKE_BINARY_DIR}/bin)
endforeach()
endif()


if(MSVC)
# Use dynamic CRT (/MD) for compatibility with Qt and other /MD libraries.
# The livekit_ffi.dll isolates the /MT libwebrtc dependency, so livekit.lib
Expand Down Expand Up @@ -202,18 +211,34 @@ if(WIN32)
IMPORTED_IMPLIB_MINSIZEREL "${RUST_IMPLIB_RELEASE}"
INTERFACE_INCLUDE_DIRECTORIES "${RUST_ROOT}/livekit-ffi/include"
)
elseif(APPLE)
# macOS: use dynamic library (.dylib) to isolate Debug/Release ABI differences
add_library(livekit_ffi SHARED IMPORTED GLOBAL)
set(RUST_LIB_DEBUG "${RUST_ROOT}/target/debug/liblivekit_ffi.dylib")
set(RUST_LIB_RELEASE "${RUST_ROOT}/target/release/liblivekit_ffi.dylib")

set_target_properties(livekit_ffi PROPERTIES
IMPORTED_CONFIGURATIONS "Debug;Release;RelWithDebInfo;MinSizeRel"
IMPORTED_LOCATION_DEBUG "${RUST_LIB_DEBUG}"
IMPORTED_LOCATION_RELEASE "${RUST_LIB_RELEASE}"
IMPORTED_LOCATION_RELWITHDEBINFO "${RUST_LIB_RELEASE}"
IMPORTED_LOCATION_MINSIZEREL "${RUST_LIB_RELEASE}"
IMPORTED_NO_SONAME TRUE
INTERFACE_INCLUDE_DIRECTORIES "${RUST_ROOT}/livekit-ffi/include"
)
else()
# Non-Windows: use static library as before
add_library(livekit_ffi STATIC IMPORTED GLOBAL)
set(RUST_LIB_DEBUG "${RUST_ROOT}/target/debug/liblivekit_ffi.a")
set(RUST_LIB_RELEASE "${RUST_ROOT}/target/release/liblivekit_ffi.a")
# Linux: use dynamic library (.so) to isolate Debug/Release ABI differences
add_library(livekit_ffi SHARED IMPORTED GLOBAL)
set(RUST_LIB_DEBUG "${RUST_ROOT}/target/debug/liblivekit_ffi.so")
set(RUST_LIB_RELEASE "${RUST_ROOT}/target/release/liblivekit_ffi.so")

set_target_properties(livekit_ffi PROPERTIES
IMPORTED_CONFIGURATIONS "Debug;Release;RelWithDebInfo;MinSizeRel"
IMPORTED_LOCATION_DEBUG "${RUST_LIB_DEBUG}"
IMPORTED_LOCATION_RELEASE "${RUST_LIB_RELEASE}"
IMPORTED_LOCATION_RELWITHDEBINFO "${RUST_LIB_RELEASE}"
IMPORTED_LOCATION_MINSIZEREL "${RUST_LIB_RELEASE}"
IMPORTED_NO_SONAME TRUE
INTERFACE_INCLUDE_DIRECTORIES "${RUST_ROOT}/livekit-ffi/include"
)
endif()
Expand Down Expand Up @@ -241,20 +266,7 @@ add_custom_target(build_rust_ffi
DEPENDS "${RUST_LIB_DEBUG}" "${RUST_LIB_RELEASE}"
)

if(UNIX AND NOT APPLE)
if(NOT CMAKE_AR)
find_program(CMAKE_AR ar REQUIRED)
endif()
# Remove protozero_plugin.o from static library to avoid duplicate symbols
# The file may not exist in all builds, so we use '|| true' to ignore errors
add_custom_command(
TARGET build_rust_ffi
POST_BUILD
COMMAND ${CMAKE_AR} -dv "${RUST_LIB_RELEASE}" protozero_plugin.o || true
COMMAND ${CMAKE_AR} -dv "${RUST_LIB_DEBUG}" protozero_plugin.o || true
COMMENT "Removing protozero_plugin.o from liblivekit_ffi.a (if present)"
)
endif()
# Note: protozero_plugin.o removal is no longer needed since we use dynamic libraries on Unix

add_library(livekit STATIC
src/audio_frame.cpp
Expand Down Expand Up @@ -350,15 +362,27 @@ if(LIVEKIT_IS_TOPLEVEL)
"$<TARGET_FILE_DIR:livekit>/livekit_ffi.dll.lib"
COMMENT "Copying livekit_ffi.dll.lib to output directory"
)
elseif(APPLE)
# macOS: copy .dylib
set(FFI_LIB_DEBUG "${RUST_ROOT}/target/debug/liblivekit_ffi.dylib")
set(FFI_LIB_RELEASE "${RUST_ROOT}/target/release/liblivekit_ffi.dylib")
add_custom_command(
TARGET livekit POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"$<IF:$<CONFIG:Debug>,${FFI_LIB_DEBUG},${FFI_LIB_RELEASE}>"
"$<TARGET_FILE_DIR:livekit>/liblivekit_ffi.dylib"
COMMENT "Copying liblivekit_ffi.dylib to output directory"
)
else()
set(FFI_LIB_DEBUG "${RUST_ROOT}/target/debug/liblivekit_ffi.a")
set(FFI_LIB_RELEASE "${RUST_ROOT}/target/release/liblivekit_ffi.a")
# Linux: copy .so
set(FFI_LIB_DEBUG "${RUST_ROOT}/target/debug/liblivekit_ffi.so")
set(FFI_LIB_RELEASE "${RUST_ROOT}/target/release/liblivekit_ffi.so")
add_custom_command(
TARGET livekit POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"$<IF:$<CONFIG:Debug>,${FFI_LIB_DEBUG},${FFI_LIB_RELEASE}>"
"$<TARGET_FILE_DIR:livekit>/liblivekit_ffi.a"
COMMENT "Copying liblivekit_ffi.a to output directory"
"$<TARGET_FILE_DIR:livekit>/liblivekit_ffi.so"
COMMENT "Copying liblivekit_ffi.so to output directory"
)
endif()

Expand Down
18 changes: 9 additions & 9 deletions DEPENDENCIES.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# LiveKit C++ SDK - System Dependencies

This file lists all system-level dependencies required to link against the LiveKit C++ SDK static libraries.
This file lists all system-level dependencies required to link against the LiveKit C++ SDK libraries.

## Overview

The LiveKit SDK consists of two static libraries:
- `livekit.lib` (or `liblivekit.a` on Unix)
- `livekit_ffi.lib` (or `liblivekit_ffi.a` on Unix)
The LiveKit SDK consists of two libraries:
- `livekit.lib` / `liblivekit.a` - Main SDK static library
- `livekit_ffi.dll` / `liblivekit_ffi.so` / `liblivekit_ffi.dylib` - Rust FFI dynamic library

## Distribution Model

Expand All @@ -15,7 +15,7 @@ The SDK uses different distribution strategies per platform:
### Windows (Complete Package)
✅ **Ready to use** - All dependencies included:
- `livekit.lib` - Main SDK static library
- `livekit_ffi.dll` + `livekit_ffi.dll.lib` - Rust FFI layer
- `livekit_ffi.dll` + `livekit_ffi.dll.lib` - Rust FFI dynamic library
- `libprotobuf.dll` + `libprotobuf.lib` - Protocol Buffers runtime
- `abseil_dll.dll` + `abseil_dll.lib` - Abseil C++ library

Expand All @@ -24,21 +24,21 @@ The SDK uses different distribution strategies per platform:
### Linux (Minimal Package)
⚠️ **Requires system dependencies**:
- `liblivekit.a` - Main SDK static library (included)
- `liblivekit_ffi.a` - Rust FFI layer (included)
- `liblivekit_ffi.so` - Rust FFI dynamic library (included, **must be placed alongside your executable**)
- `libprotobuf` - Must install via `apt install libprotobuf-dev`
- `libssl` - Must install via `apt install libssl-dev`
- `libabsl` - Only if built with Protobuf 6.0+: `apt install libabsl-dev`

**User action**: Install required packages on target system before linking.
**User action**: Install required packages and copy `liblivekit_ffi.so` to your executable directory.

### macOS (Minimal Package)
⚠️ **Requires system dependencies**:
- `liblivekit.a` - Main SDK static library (included)
- `liblivekit_ffi.a` - Rust FFI layer (included)
- `liblivekit_ffi.dylib` - Rust FFI dynamic library (included, **must be placed alongside your executable**)
- `protobuf` - Must install via `brew install protobuf`
- `abseil` - Only if built with Protobuf 6.0+: `brew install abseil`

**User action**: Install required packages on target system before linking.
**User action**: Install required packages and copy `liblivekit_ffi.dylib` to your executable directory.

---

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ This SDK enables native C++ applications to connect to LiveKit servers for real-

### For Using the Pre-built SDK:
- **Windows:** ✅ All dependencies included (DLLs bundled) - ready to use
- **Linux:** ⚠️ Requires `libprotobuf` and `libssl-dev` installed on target system
- **macOS:** ⚠️ Requires `protobuf` installed via Homebrew on target system
- **Linux:** ⚠️ Requires `libprotobuf` and `libssl-dev`; deploy `liblivekit_ffi.so` with your executable
- **macOS:** ⚠️ Requires `protobuf`; deploy `liblivekit_ffi.dylib` with your executable

> **Note**: If the SDK was built with Protobuf 6.0+, you also need `libabsl-dev` (Linux) or `abseil` (macOS).

Expand Down
Loading
Loading