Skip to content

Conversation

@Sqhh99
Copy link

@Sqhh99 Sqhh99 commented Dec 29, 2025

This PR adjusts the build configuration to handle platform-specific dependency management. #23

Initially, I tried using vcpkg for protobuf and abseil on all platforms. However, I encountered a few issues:

The SDK produces static libraries (livekit.lib and livekit_ffi.lib). When testing on WSL, I found that users need to link the exact protobuf and abseil versions used during build. On Windows, there's an additional complication: the webrtc-sys crate in client-sdk-rust uses pre-built static libraries with /MT runtime (see config.toml: target-feature=+crt-static). If livekit.lib also uses /MT, any application using /MD runtime will encounter linking conflicts. Since most Windows applications and frameworks use /MD by default, I changed livekit_ffi to a DLL to isolate the /MT dependency, allowing livekit.lib to use /MD safely.

Linux and macOS don't have the /MT vs /MD distinction. Also, vcpkg's library versions don't match what system package managers provide, making it impractical to bundle everything. It's much simpler for users to just install protobuf and abseil via apt or brew.

The current approach:

Platform Dependencies Distribution
Windows vcpkg Bundled DLLs
Linux apt Static lib only
macOS Homebrew Static lib only

Using the SDK:

  • Windows: Link livekit.lib and livekit_ffi.dll.lib, copy the DLLs to your executable directory
  • Linux: Install libprotobuf-dev and libabsl-dev via apt, then link liblivekit.a and liblivekit_ffi.a
  • macOS: Install protobuf and abseil via brew, then link liblivekit.a and liblivekit_ffi.a

I'm not sure if this is the best solution, but Windows lacks a system package manager, so bundling dependencies seems necessary for a usable distribution.

Windows output structure:

build/
├── include/livekit/          # Headers
├── lib/windows-x64/release/
│   ├── livekit.lib           # Main library
│   ├── livekit_ffi.dll       # FFI runtime
│   ├── libprotobuf.dll       # Protobuf runtime
│   └── abseil_dll.dll        # Abseil runtime
└── bin/release/              # Examples

The CI now builds and runs examples on all platforms to verify the libraries work correctly.

  livekit.vcxproj -> D:\workspace\lib-workspace\client-sdk-cpp\build\Release\livekit.lib
  SimpleDataStream.vcxproj -> D:\workspace\lib-workspace\client-sdk-cpp\build\examples\Release\SimpleDataStream.exe
  SimpleRoom.vcxproj -> D:\workspace\lib-workspace\client-sdk-cpp\build\examples\Release\SimpleRoom.exe
  SimpleRpc.vcxproj -> D:\workspace\lib-workspace\client-sdk-cpp\build\examples\Release\SimpleRpc.exe
Build Succeeded.
- Fix "file path too long" errors by switching from CMAKE_SOURCE_DIR
  to CMAKE_CURRENT_SOURCE_DIR for relative path resolution.
- Refactor CMakeLists.txt to support nested project usage via
  LIVEKIT_IS_TOPLEVEL check.
- Align MSVC runtime library with Rust static CRT (MultiThreaded)
  to prevent link-time conflicts.
- Implement unified binary output directory (bin/lib/include) with
  config-specific subfolders.
- Add robust cargo build integration using run_cargo.cmake script.
- Introduce install logic and full clean targets (clean_all).
- Added CMakePresets.json for unified cross-platform build configurations.
- Optimized Rust FFI build logic to prevent unnecessary recompilation when C++ code changes.
- Fixed MSVC runtime library (MT/MD) mismatch on Windows.
- Added automatic header aggregation to build/include directory.
- Refactored CMakeLists.txt to support both top-level and subdirectory integration.
…cies

- Add GitHub Actions workflow for Windows, Linux, and macOS
- Integrate vcpkg manifest mode with CMake Presets
- Fix missing Linux dependencies (libva, alsa, libclang, etc.)
- Add CXXFLAGS to ignore deprecated warnings from WebRTC on newer GCC
- Synchronize git submodules and fix protocol file paths
- Configure build.h template for build metadata injection
- Remove livekit_ffi.h inclusion from public participant.h
- Add livekit_ffi.h to room.cpp for internal access to INVALID_HANDLE
- Improve header encapsulation by hiding internal FFI definitions from SDK users
…T conflicts

Motivation:
The prebuilt libwebrtc library is strictly compiled with the /MT runtime,
causing severe symbol redefinition and runtime mismatch errors (LNK2038)
when linked against /MD-based Qt applications.

Changes:
1. Architecture Redesign: Refactored livekit-ffi to build as a shared library
   (cdylib/DLL) instead of a static library on Windows.
2. Binary Isolation: Leveraged the DLL boundary to encapsulate /MT dependencies,
   allowing the consumer layer (livekit.lib) to safely use /MD.
3. CMake Infrastructure Enhancements:
   - Explicitly set CMAKE_MSVC_RUNTIME_LIBRARY to MultiThreadedDLL for
     MSVC targets.
   - Automated the Rust build pipeline with PROTOC environment variable
     injection for protobuf generation.
   - Added POST_BUILD commands to automatically deploy livekit_ffi.dll and
     third-party dependencies (protobuf, abseil) to the output directory.
4. Platform Consistency: Maintained the original static linking logic for
   Linux and macOS to preserve performance and simplicity.

Verification:
Validated the generated livekit.lib using `dumpbin /DIRECTIVES`, confirming
the RuntimeLibrary is correctly set to MD_DynamicRelease.
- Automatically copy libprotobuf.lib and abseil_dll.lib to SDK lib
- Replace protobuf_generate with custom add_custom_command
- Use --proto_path to ensure correct symbol naming
- Linux/macOS use system protobuf (apt/brew)
- Windows uses vcpkg
- Update documentation for platform-specific dependencies
- Add include paths for all examples (src/, generated/, protobuf)
- Copy DLLs to examples output on Windows
- Use FetchContent for SDL3 on all platforms
- Remove sdl3 from vcpkg.json (not in baseline)
- Add debug-examples and release-examples commands
- Update usage help text
@Sqhh99 Sqhh99 changed the title Sqhh99/windows vcpkg support windows vcpkg support Dec 29, 2025
@xianshijing-lk
Copy link
Collaborator

Great work. I was also hit by the MT / MD issues, the problem seems to be some pre-built libs are using MT and it will cause symbol conflicts, I suspect it was libwebrtc but didn't get time to verify it.

I like your approach of workaround the problem:

I changed livekit_ffi to a DLL to isolate the /MT dependency, allowing livekit.lib to use /MD safely.

Copy link
Collaborator

@xianshijing-lk xianshijing-lk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from a quick look. Thanks, they are solid code.

run: |
[[ -x build.sh ]] && ./build.sh clean-all || true
if [[ "$RUNNER_OS" == "Windows" ]]; then
rm -rf build || true
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if it is enough to remove the build folder ? I think "./build.sh clean" also does the "cd client-sdk-rust; cargo clean;"

run: |
./build.sh release
- name: Configure CMake
run: cmake --preset ${{ matrix.preset }}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like adding the preset.

But I wonder if we should do build.sh on Unix and build.cmd on windows ? so that the CIs and developers are using the same development cmds. What do you think?

cmake_minimum_required(VERSION 3.20)

if(NOT DEFINED LIVEKIT_VERSION OR LIVEKIT_VERSION STREQUAL "")
set(LIVEKIT_VERSION "0.1.0")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, just use 0.0.0 as default. once your PR is landed, I would like to make the first release.

TARGET livekit_proto
PROTOC_OUT_DIR ${PROTO_BINARY_DIR}
IMPORT_DIRS ${FFI_PROTO_DIR}
# Manually generate protobuf files to avoid path prefix issues
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I am curious what path prefix issues you met. The protobuf worked out of box for me after I installed the protobuf via vcpkg, but likely my workspace wasn't cleaned at all.

add_custom_command(
TARGET build_rust_ffi
POST_BUILD
COMMAND ${CMAKE_AR} -dv "${RUST_LIB_RELEASE}" protozero_plugin.o
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you will need to rebase my latest change in #21, otherwise the debug build will fail on Linux as it is looking for ${RUST_LIB_RELEASE}

"displayName": "Windows x64 Debug",
"description": "Build for Windows x64 Debug (vcpkg)",
"inherits": "windows-base",
"binaryDir": "${sourceDir}/build"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should release and debug have different binaryDir ?
like ${sourceDir}/build-release
${sourceDir}/build-debug ?

"displayName": "Linux Release",
"description": "Build for Linux Release (system packages)",
"inherits": "linux-base",
"binaryDir": "${sourceDir}/build",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for Linux and Mac

}
},
{
"name": "windows-release",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it intentional to have windows-release and windows-debug to be the same ?

if they should be the same, should we just use one windows rather than 2 ?


:build_only
echo ==^> Building (%BUILD_TYPE%)...
cmake --build "%BUILD_DIR%" --config %BUILD_TYPE% -j %VERBOSE%
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need the -j on windows ?

if VERBOSE is empty, will it work ? I am not sure, but doubt if "cmake --build ... -j" is valid


if "%1"=="debug-examples" (
set "BUILD_TYPE=Debug"
set "PRESET=windows-debug-examples"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only see windows-release-examples, do we need windows-debug-examples here ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants