diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 2b95e6d..43013f5 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -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 diff --git a/.github/workflows/make-release.yml b/.github/workflows/make-release.yml index c47f529..c8de4f8 100644 --- a/.github/workflows/make-release.yml +++ b/.github/workflows/make-release.yml @@ -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" @@ -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' @@ -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: @@ -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/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 4882325..2d02bda 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,19 @@ 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() @@ -29,27 +42,23 @@ else() 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}/$>) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/${PLATFORM_DIR}/$>) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/$>) - 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 @@ -202,11 +211,26 @@ 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" @@ -214,6 +238,7 @@ else() 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() @@ -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 @@ -350,15 +362,27 @@ if(LIVEKIT_IS_TOPLEVEL) "$/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 + "$,${FFI_LIB_DEBUG},${FFI_LIB_RELEASE}>" + "$/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 "$,${FFI_LIB_DEBUG},${FFI_LIB_RELEASE}>" - "$/liblivekit_ffi.a" - COMMENT "Copying liblivekit_ffi.a to output directory" + "$/liblivekit_ffi.so" + COMMENT "Copying liblivekit_ffi.so to output directory" ) endif() diff --git a/DEPENDENCIES.md b/DEPENDENCIES.md index 265f7a7..5de560a 100644 --- a/DEPENDENCIES.md +++ b/DEPENDENCIES.md @@ -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 @@ -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 @@ -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. --- diff --git a/README.md b/README.md index ff8c344..0cc98c1 100644 --- a/README.md +++ b/README.md @@ -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). diff --git a/README_BUILD.md b/README_BUILD.md index a79a65e..1c6b060 100644 --- a/README_BUILD.md +++ b/README_BUILD.md @@ -207,22 +207,16 @@ After a successful build, you will find the following in the build directories: ``` build-release/ # Release build output ├── lib/ -│ ├── windows-x64/ # Windows libraries -│ │ └── release/ -│ ├── linux-x64/ # Linux libraries -│ └── macos-universal/ # macOS libraries +│ ├── livekit.lib / liblivekit.a # Main SDK static library +│ ├── livekit_ffi.dll / .so / .dylib # Rust FFI dynamic library +│ └── (Windows only: protobuf, abseil DLLs) ├── include/ # Public headers (auto-synced) │ └── livekit/ -└── bin/ # Executable files - -build-debug/ # Debug build output -├── lib/ -│ ├── windows-x64/ -│ │ └── debug/ -│ ├── linux-x64/ -│ └── macos-universal/ -├── include/ -└── bin/ +└── bin/ # Example executables (with examples enabled) + ├── SimpleRoom + ├── SimpleRpc + ├── SimpleDataStream + └── liblivekit_ffi.so / .dylib # (Linux/macOS: copied for runtime) ``` ## Integrating into Your Project @@ -243,14 +237,17 @@ target_link_libraries(your_target PRIVATE livekit) 1. Add include path: `build/include` 2. Link static library: - - Windows: `build/lib/windows-x64/release/livekit.lib` - - Linux: `build/lib/linux-x64/liblivekit.a` - - macOS: `build/lib/macos-universal/liblivekit.a` -3. Link Rust FFI library: - - Windows: `client-sdk-rust/target/release/livekit_ffi.lib` - - Linux/macOS: `client-sdk-rust/target/release/liblivekit_ffi.a` + - Windows: `build/lib/livekit.lib` + - Linux: `build/lib/liblivekit.a` + - macOS: `build/lib/liblivekit.a` +3. Link/Deploy Rust FFI dynamic library: + - Windows: Link `livekit_ffi.dll.lib`, deploy `livekit_ffi.dll` with your exe + - Linux: Deploy `liblivekit_ffi.so` in same directory as your executable + - macOS: Deploy `liblivekit_ffi.dylib` in same directory as your executable 4. Link platform-specific system libraries +> **Important**: On Linux/macOS, the `.so`/`.dylib` must be in the same directory as your executable (RPATH is set to `$ORIGIN` / `@executable_path`). + **Windows system libraries:** ``` ntdll userenv winmm iphlpapi msdmo dmoguids wmcodecdspuuid diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d383c8f..082aba1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -4,6 +4,22 @@ project(livekit-examples) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +# Set RPATH for examples to find shared libraries in executable directory +# This ensures SDL3 and other shared libs are loaded from bin/ not _deps/ +if(UNIX) + 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) + # Disable using the default RPATH from linked libraries + set(CMAKE_SKIP_BUILD_RPATH FALSE) + set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +endif() + # Always use FetchContent for SDL3 (vcpkg doesn't have it in stable baseline) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(sdl3) @@ -46,6 +62,31 @@ add_custom_command(TARGET SimpleRoom POST_BUILD ${CMAKE_CURRENT_BINARY_DIR}/data ) +# Copy SDL3 shared library to SimpleRoom output directory +# On Linux, we also need to create the SONAME symlink (libSDL3.so.0 -> libSDL3.so.0.x.x) +# macOS doesn't need SONAME symlink (dylib versioning works differently) +if(UNIX AND NOT APPLE) + add_custom_command(TARGET SimpleRoom POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "$" + COMMAND ${CMAKE_COMMAND} -E create_symlink + "$" + "$/$" + COMMENT "Copying SDL3 shared library and SONAME symlink to SimpleRoom output directory" + VERBATIM + ) +else() + # Windows and macOS: just copy the library file + add_custom_command(TARGET SimpleRoom POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "$" + "$" + COMMENT "Copying SDL3 shared library to SimpleRoom output directory" + VERBATIM + ) +endif() + find_package(nlohmann_json CONFIG QUIET) if(NOT nlohmann_json_FOUND) include(FetchContent) @@ -94,10 +135,13 @@ if(WIN32) # Get the livekit library output directory (where DLLs are copied during main build) set(LIVEKIT_LIB_DIR $) - # List of DLLs to copy + # Protobuf DLL name depends on configuration (libprotobufd.dll for Debug, libprotobuf.dll for Release) + set(PROTOBUF_DLL_NAME $,libprotobufd.dll,libprotobuf.dll>) + + # List of DLLs to copy (using generator expressions for config-dependent names) set(REQUIRED_DLLS "livekit_ffi.dll" - "libprotobuf.dll" + "${PROTOBUF_DLL_NAME}" "abseil_dll.dll" ) @@ -113,4 +157,26 @@ if(WIN32) ) endforeach() endforeach() +endif() + +# Linux/macOS: Copy shared library to examples output directory +if(UNIX) + set(LIVEKIT_LIB_DIR $) + + if(APPLE) + set(FFI_SHARED_LIB "liblivekit_ffi.dylib") + else() + set(FFI_SHARED_LIB "liblivekit_ffi.so") + endif() + + # Copy shared library to each example's output directory + foreach(EXAMPLE SimpleRoom SimpleRpc SimpleDataStream) + add_custom_command(TARGET ${EXAMPLE} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + "${LIVEKIT_LIB_DIR}/${FFI_SHARED_LIB}" + "$/${FFI_SHARED_LIB}" + COMMENT "Copying ${FFI_SHARED_LIB} to ${EXAMPLE} output directory" + VERBATIM + ) + endforeach() endif() \ No newline at end of file diff --git a/examples/cmake/sdl3.cmake b/examples/cmake/sdl3.cmake index 8a1899e..1ba2ccb 100644 --- a/examples/cmake/sdl3.cmake +++ b/examples/cmake/sdl3.cmake @@ -3,6 +3,33 @@ include(FetchContent) # Only fetch/build SDL3 once, even if this file is included multiple times if (NOT TARGET SDL3::SDL3) + # Prevent SDL3 from polluting our lib directory + set(SDL_INSTALL OFF CACHE BOOL "Disable SDL3 install" FORCE) + set(SDL_SHARED ON CACHE BOOL "Build shared SDL3" FORCE) + + # Save current output directories + set(_SAVE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) + set(_SAVE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + set(_SAVE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + + # Set SDL3 to build into its own subdirectory + set(SDL3_OUTPUT_DIR ${CMAKE_BINARY_DIR}/_deps/sdl3-build) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${SDL3_OUTPUT_DIR}) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${SDL3_OUTPUT_DIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${SDL3_OUTPUT_DIR}) + + # For multi-config generators (Visual Studio), also set per-config directories + foreach(CONFIG_TYPE Debug Release RelWithDebInfo MinSizeRel) + string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE_UPPER) + set(_SAVE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER}}) + set(_SAVE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER}}) + set(_SAVE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER}}) + + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${SDL3_OUTPUT_DIR}) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${SDL3_OUTPUT_DIR}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${SDL3_OUTPUT_DIR}) + endforeach() + FetchContent_Declare( SDL3 GIT_REPOSITORY https://github.com/libsdl-org/SDL.git @@ -10,5 +37,16 @@ if (NOT TARGET SDL3::SDL3) ) FetchContent_MakeAvailable(SDL3) + + # Restore output directories + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${_SAVE_ARCHIVE_OUTPUT_DIRECTORY}) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${_SAVE_LIBRARY_OUTPUT_DIRECTORY}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${_SAVE_RUNTIME_OUTPUT_DIRECTORY}) + + foreach(CONFIG_TYPE Debug Release RelWithDebInfo MinSizeRel) + string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE_UPPER) + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${_SAVE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER}}) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${_SAVE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER}}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER} ${_SAVE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_TYPE_UPPER}}) + endforeach() endif() -