210 lines
8.3 KiB
CMake
210 lines
8.3 KiB
CMake
# LiveKitSDK.cmake
|
|||
|
|
#
|
||
|
|
# Downloads the prebuilt LiveKit C++ SDK (livekit/client-sdk-cpp) release
|
||
|
|
# asset for the host OS/arch, extracts it, and points
|
||
|
|
# `find_package(LiveKit CONFIG REQUIRED)` at it.
|
||
|
|
#
|
||
|
|
# Adapted from livekit-examples/cpp-example-collection's cmake/LiveKitSDK.cmake
|
||
|
|
# (fetched 2026-09-06). Deliberate changes from the upstream reference:
|
||
|
|
#
|
||
|
|
# 1. VERSION must be an exact release number. The upstream helper accepted
|
||
|
|
# VERSION "latest" and resolved it through the GitHub releases API at
|
||
|
|
# configure time. That is exactly what this project must not do: the
|
||
|
|
# design doc calls for a pinned release tag, treating version bumps as
|
||
|
|
# deliberate work (the SDK is young and ships roughly weekly). Dropping
|
||
|
|
# the "latest" path also removes a GitHub-API call -- and its rate
|
||
|
|
# limiting / GITHUB_TOKEN plumbing -- from every CI configure.
|
||
|
|
# 2. Exports LIVEKIT_SDK_RUNTIME_LIBS: the shared libraries that must be
|
||
|
|
# staged next to the built OBS plugin module for it to load at runtime
|
||
|
|
# (liblivekit + liblivekit_ffi). Upstream examples run out of the build
|
||
|
|
# tree and never needed this; a redistributable OBS plugin does.
|
||
|
|
# 3. Exports LIVEKIT_SDK_INCLUDE_DIR / _LIB_DIR / _BIN_DIR for packaging.
|
||
|
|
#
|
||
|
|
# Usage:
|
||
|
|
# list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||
|
|
# include(LiveKitSDK)
|
||
|
|
# livekit_sdk_setup(VERSION "1.10.1" SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk")
|
||
|
|
# find_package(LiveKit CONFIG REQUIRED)
|
||
|
|
|
||
|
|
include_guard(GLOBAL)
|
||
|
|
|
||
|
|
# -------------------- Host detection --------------------
|
||
|
|
function(_lk_detect_host out_os out_arch)
|
||
|
|
if(WIN32)
|
||
|
|
set(_os "windows")
|
||
|
|
elseif(APPLE)
|
||
|
|
set(_os "macos")
|
||
|
|
elseif(UNIX)
|
||
|
|
set(_os "linux")
|
||
|
|
else()
|
||
|
|
message(FATAL_ERROR "LiveKitSDK: unsupported host OS")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Prefer the *target* processor when cross-compiling is expressed through
|
||
|
|
# CMAKE_OSX_ARCHITECTURES (macOS CI runners are arm64 but may target x64).
|
||
|
|
set(_proc "${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||
|
|
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||
|
|
list(LENGTH CMAKE_OSX_ARCHITECTURES _n_arch)
|
||
|
|
if(_n_arch GREATER 1)
|
||
|
|
message(FATAL_ERROR
|
||
|
|
"LiveKitSDK: CMAKE_OSX_ARCHITECTURES lists ${_n_arch} architectures "
|
||
|
|
"(${CMAKE_OSX_ARCHITECTURES}). client-sdk-cpp ships single-arch "
|
||
|
|
"dylibs only, so universal binaries are not supported. Build one "
|
||
|
|
"architecture at a time.")
|
||
|
|
endif()
|
||
|
|
list(GET CMAKE_OSX_ARCHITECTURES 0 _proc)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
string(TOLOWER "${_proc}" _proc_l)
|
||
|
|
if(_proc_l MATCHES "^(x86_64|amd64)$")
|
||
|
|
set(_arch "x64")
|
||
|
|
elseif(_proc_l MATCHES "^(arm64|aarch64)$")
|
||
|
|
set(_arch "arm64")
|
||
|
|
else()
|
||
|
|
message(FATAL_ERROR "LiveKitSDK: unsupported host arch: ${_proc}")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
set(${out_os} "${_os}" PARENT_SCOPE)
|
||
|
|
set(${out_arch} "${_arch}" PARENT_SCOPE)
|
||
|
|
endfunction()
|
||
|
|
|
||
|
|
function(_lk_default_triple out_triple)
|
||
|
|
_lk_detect_host(_os _arch)
|
||
|
|
set(${out_triple} "${_os}-${_arch}" PARENT_SCOPE)
|
||
|
|
endfunction()
|
||
|
|
|
||
|
|
function(_lk_archive_ext out_ext)
|
||
|
|
if(WIN32)
|
||
|
|
set(${out_ext} "zip" PARENT_SCOPE)
|
||
|
|
else()
|
||
|
|
set(${out_ext} "tar.gz" PARENT_SCOPE)
|
||
|
|
endif()
|
||
|
|
endfunction()
|
||
|
|
|
||
|
|
# -------------------- Public entrypoint --------------------
|
||
|
|
# livekit_sdk_setup(
|
||
|
|
# VERSION <x.y.z> REQUIRED, exact -- "latest" is rejected
|
||
|
|
# SDK_DIR <dir> REQUIRED, where the archive is extracted
|
||
|
|
# [REPO <org/repo>] default: livekit/client-sdk-cpp
|
||
|
|
# [SHA256 <hash>] optional: verify the downloaded archive
|
||
|
|
# [TRIPLE <os-arch>] optional override (e.g. ubuntu-24.04-x64)
|
||
|
|
# [DOWNLOAD_DIR <dir>] default: <build>/_downloads
|
||
|
|
# [NO_DOWNLOAD] fail instead of downloading if absent
|
||
|
|
# )
|
||
|
|
function(livekit_sdk_setup)
|
||
|
|
set(options NO_DOWNLOAD)
|
||
|
|
set(oneValueArgs VERSION SDK_DIR REPO SHA256 TRIPLE DOWNLOAD_DIR)
|
||
|
|
cmake_parse_arguments(LK "${options}" "${oneValueArgs}" "" ${ARGN})
|
||
|
|
|
||
|
|
if(NOT LK_VERSION)
|
||
|
|
message(FATAL_ERROR "livekit_sdk_setup: VERSION is required")
|
||
|
|
endif()
|
||
|
|
if(LK_VERSION STREQUAL "latest")
|
||
|
|
message(FATAL_ERROR
|
||
|
|
"livekit_sdk_setup: VERSION=\"latest\" is deliberately not supported. "
|
||
|
|
"This project pins an exact client-sdk-cpp release; see the comment at "
|
||
|
|
"the top of cmake/LiveKitSDK.cmake.")
|
||
|
|
endif()
|
||
|
|
if(NOT LK_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+$")
|
||
|
|
message(FATAL_ERROR "livekit_sdk_setup: VERSION must be x.y.z, got '${LK_VERSION}'")
|
||
|
|
endif()
|
||
|
|
if(NOT LK_SDK_DIR)
|
||
|
|
message(FATAL_ERROR "livekit_sdk_setup: SDK_DIR is required")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
if(NOT LK_REPO)
|
||
|
|
set(LK_REPO "livekit/client-sdk-cpp")
|
||
|
|
endif()
|
||
|
|
if(NOT LK_DOWNLOAD_DIR)
|
||
|
|
set(LK_DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/_downloads")
|
||
|
|
endif()
|
||
|
|
if(NOT LK_TRIPLE)
|
||
|
|
_lk_default_triple(LK_TRIPLE)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
_lk_archive_ext(_ext)
|
||
|
|
set(_archive "livekit-sdk-${LK_TRIPLE}-${LK_VERSION}.${_ext}")
|
||
|
|
set(_url "https://github.com/${LK_REPO}/releases/download/v${LK_VERSION}/${_archive}")
|
||
|
|
set(_archive_path "${LK_DOWNLOAD_DIR}/${_archive}")
|
||
|
|
|
||
|
|
# The archive contains a single top-level folder named after the asset.
|
||
|
|
set(_extracted_root "${LK_SDK_DIR}/livekit-sdk-${LK_TRIPLE}-${LK_VERSION}")
|
||
|
|
|
||
|
|
file(MAKE_DIRECTORY "${LK_DOWNLOAD_DIR}")
|
||
|
|
file(MAKE_DIRECTORY "${LK_SDK_DIR}")
|
||
|
|
|
||
|
|
if(NOT EXISTS "${_extracted_root}/lib/cmake")
|
||
|
|
if(LK_NO_DOWNLOAD)
|
||
|
|
message(FATAL_ERROR
|
||
|
|
"LiveKitSDK: SDK not found at:\n ${_extracted_root}\nand NO_DOWNLOAD was set.")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
message(STATUS "LiveKitSDK: downloading ${_url}")
|
||
|
|
|
||
|
|
if(LK_SHA256)
|
||
|
|
file(DOWNLOAD "${_url}" "${_archive_path}"
|
||
|
|
SHOW_PROGRESS TLS_VERIFY ON
|
||
|
|
EXPECTED_HASH "SHA256=${LK_SHA256}"
|
||
|
|
STATUS _st LOG _log)
|
||
|
|
else()
|
||
|
|
file(DOWNLOAD "${_url}" "${_archive_path}"
|
||
|
|
SHOW_PROGRESS TLS_VERIFY ON
|
||
|
|
STATUS _st LOG _log)
|
||
|
|
endif()
|
||
|
|
|
||
|
|
list(GET _st 0 _code)
|
||
|
|
list(GET _st 1 _msg)
|
||
|
|
if(NOT _code EQUAL 0)
|
||
|
|
file(REMOVE "${_archive_path}")
|
||
|
|
message(STATUS "LiveKitSDK: download log:\n${_log}")
|
||
|
|
message(FATAL_ERROR
|
||
|
|
"LiveKitSDK: download failed\nURL: ${_url}\nStatus: ${_code}\nMessage: ${_msg}\n"
|
||
|
|
"If this triple has no release asset, pass TRIPLE explicitly.")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Remove any previous partial extraction.
|
||
|
|
file(REMOVE_RECURSE "${_extracted_root}")
|
||
|
|
|
||
|
|
message(STATUS "LiveKitSDK: extracting ${_archive_path}")
|
||
|
|
file(ARCHIVE_EXTRACT INPUT "${_archive_path}" DESTINATION "${LK_SDK_DIR}")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
if(NOT EXISTS "${_extracted_root}/lib/cmake/LiveKit/LiveKitConfig.cmake")
|
||
|
|
message(FATAL_ERROR
|
||
|
|
"LiveKitSDK: extracted SDK does not look valid (missing "
|
||
|
|
"lib/cmake/LiveKit/LiveKitConfig.cmake)\nExpected under: ${_extracted_root}")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
# Make find_package(LiveKit CONFIG REQUIRED) work in the caller's scope.
|
||
|
|
list(PREPEND CMAKE_PREFIX_PATH "${_extracted_root}")
|
||
|
|
set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}" PARENT_SCOPE)
|
||
|
|
set(LiveKit_DIR "${_extracted_root}/lib/cmake/LiveKit" PARENT_SCOPE)
|
||
|
|
|
||
|
|
# --- Runtime libraries, for staging next to the plugin module ------------
|
||
|
|
# Windows keeps the DLLs in bin/ and the import libs in lib/; the Unix
|
||
|
|
# platforms put the shared objects directly in lib/.
|
||
|
|
if(WIN32)
|
||
|
|
file(GLOB _runtime_libs "${_extracted_root}/bin/*.dll")
|
||
|
|
elseif(APPLE)
|
||
|
|
file(GLOB _runtime_libs "${_extracted_root}/lib/*.dylib")
|
||
|
|
else()
|
||
|
|
file(GLOB _runtime_libs "${_extracted_root}/lib/*.so" "${_extracted_root}/lib/*.so.*")
|
||
|
|
endif()
|
||
|
|
if(NOT _runtime_libs)
|
||
|
|
message(FATAL_ERROR
|
||
|
|
"LiveKitSDK: found no runtime shared libraries under ${_extracted_root}. "
|
||
|
|
"The release layout may have changed for version ${LK_VERSION}.")
|
||
|
|
endif()
|
||
|
|
|
||
|
|
set(LIVEKIT_SDK_EXTRACTED_ROOT "${_extracted_root}" CACHE PATH "LiveKit SDK extracted root" FORCE)
|
||
|
|
set(LIVEKIT_SDK_INCLUDE_DIR "${_extracted_root}/include" CACHE PATH "LiveKit SDK include dir" FORCE)
|
||
|
|
set(LIVEKIT_SDK_LIB_DIR "${_extracted_root}/lib" CACHE PATH "LiveKit SDK lib dir" FORCE)
|
||
|
|
set(LIVEKIT_SDK_BIN_DIR "${_extracted_root}/bin" CACHE PATH "LiveKit SDK bin dir" FORCE)
|
||
|
|
set(LIVEKIT_SDK_RUNTIME_LIBS "${_runtime_libs}" CACHE STRING "LiveKit SDK runtime shared libraries" FORCE)
|
||
|
|
set(LIVEKIT_SDK_URL_USED "${_url}" CACHE STRING "LiveKit SDK URL used" FORCE)
|
||
|
|
set(LIVEKIT_SDK_VERSION_RESOLVED "${LK_VERSION}" CACHE STRING "LiveKit SDK version" FORCE)
|
||
|
|
set(LIVEKIT_SDK_TRIPLE_USED "${LK_TRIPLE}" CACHE STRING "LiveKit SDK triple" FORCE)
|
||
|
|
|
||
|
|
message(STATUS "LiveKitSDK: using SDK ${LK_VERSION} (${LK_TRIPLE}) at ${_extracted_root}")
|
||
|
|
endfunction()
|