From fc289a11f53b4e8e201750ac0bf094443eea8d51 Mon Sep 17 00:00:00 2001 From: Alan George Date: Tue, 26 May 2026 10:47:50 -0600 Subject: [PATCH 1/2] Updated to latest method signatures --- CMakeLists.txt | 34 ++- basic_room/capture_utils.cpp | 4 +- basic_room/main.cpp | 2 +- cmake/LiveKitSDK.cmake | 352 ++++++++++++++++++++++- hello_livekit/receiver/main.cpp | 4 +- hello_livekit/sender/main.cpp | 4 +- ping_pong/ping/main.cpp | 4 +- ping_pong/pong/main.cpp | 4 +- simple_data_stream/main.cpp | 4 +- simple_joystick/receiver/main.cpp | 4 +- simple_joystick/sender/main.cpp | 4 +- simple_room/fallback_capture.cpp | 4 +- simple_room/main.cpp | 4 +- simple_room/sdl_media_manager.cpp | 8 +- simple_room/wav_audio_source.cpp | 2 +- simple_rpc/main.cpp | 6 +- user_timestamped_video/consumer/main.cpp | 4 +- user_timestamped_video/producer/main.cpp | 4 +- 18 files changed, 406 insertions(+), 46 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6d382af..c516153 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,13 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Make "include(LiveKitSDK)" search in ./cmake list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -set(LIVEKIT_SDK_VERSION "latest" CACHE STRING "LiveKit C++ SDK version (e.g. 0.2.0 or latest)") +set(LIVEKIT_SDK_VERSION "" CACHE STRING + "LiveKit C++ SDK release version (e.g. 0.3.4 or latest). Empty when LIVEKIT_SDK_COMMIT is used.") +# Temporary pin: tracks an unreleased commit on `livekit/client-sdk-cpp@main` +# that contains the unified-method-style guide changes (PR #127). Switch back +# to LIVEKIT_SDK_VERSION once a tagged release ships those changes. +set(LIVEKIT_SDK_COMMIT "f7a8df1b72207d0a81390e64e73f4eb5a4811c56" CACHE STRING + "LiveKit C++ SDK commit hash on main (uses Builds workflow artifacts; ~7d retention).") set(LIVEKIT_LOCAL_SDK_DIR "" CACHE PATH "Path to a local LiveKit SDK install prefix (skips download)") if(LIVEKIT_LOCAL_SDK_DIR) @@ -29,11 +35,27 @@ if(LIVEKIT_LOCAL_SDK_DIR) list(PREPEND CMAKE_PREFIX_PATH "${LIVEKIT_LOCAL_SDK_DIR}") else() include(LiveKitSDK) - livekit_sdk_setup( - VERSION "${LIVEKIT_SDK_VERSION}" - SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk" - GITHUB_TOKEN "$ENV{GITHUB_TOKEN}" - ) + if(LIVEKIT_SDK_COMMIT AND LIVEKIT_SDK_VERSION) + message(FATAL_ERROR + "Set either LIVEKIT_SDK_COMMIT or LIVEKIT_SDK_VERSION, not both.\n" + "Got LIVEKIT_SDK_COMMIT='${LIVEKIT_SDK_COMMIT}' and LIVEKIT_SDK_VERSION='${LIVEKIT_SDK_VERSION}'.") + endif() + if(LIVEKIT_SDK_COMMIT) + livekit_sdk_setup( + COMMIT "${LIVEKIT_SDK_COMMIT}" + SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk" + GITHUB_TOKEN "$ENV{GITHUB_TOKEN}" + ) + else() + if(NOT LIVEKIT_SDK_VERSION) + set(LIVEKIT_SDK_VERSION "latest") + endif() + livekit_sdk_setup( + VERSION "${LIVEKIT_SDK_VERSION}" + SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk" + GITHUB_TOKEN "$ENV{GITHUB_TOKEN}" + ) + endif() endif() find_package(LiveKit CONFIG REQUIRED) diff --git a/basic_room/capture_utils.cpp b/basic_room/capture_utils.cpp index 0a13925..54dda95 100644 --- a/basic_room/capture_utils.cpp +++ b/basic_room/capture_utils.cpp @@ -30,8 +30,8 @@ using namespace livekit; // Test utils to run a capture loop to publish noisy audio frames to the room void runNoiseCaptureLoop(const std::shared_ptr& source, std::atomic& running_flag) { - const int sample_rate = source->sample_rate(); - const int num_channels = source->num_channels(); + const int sample_rate = source->sampleRate(); + const int num_channels = source->numChannels(); const int frame_ms = 10; const int samples_per_channel = sample_rate * frame_ms / 1000; diff --git a/basic_room/main.cpp b/basic_room/main.cpp index 8db1acb..59893bc 100644 --- a/basic_room/main.cpp +++ b/basic_room/main.cpp @@ -112,7 +112,7 @@ int main(int argc, char* argv[]) { options.dynacast = false; std::cout << "Connecting to: " << url << "\n"; - if (!room->Connect(url, token, options)) { + if (!room->connect(url, token, options)) { std::cerr << "Failed to connect\n"; livekit::shutdown(); return 1; diff --git a/cmake/LiveKitSDK.cmake b/cmake/LiveKitSDK.cmake index 02d36fa..0c73df2 100644 --- a/cmake/LiveKitSDK.cmake +++ b/cmake/LiveKitSDK.cmake @@ -1,17 +1,25 @@ # LiveKitSDK.cmake # # Helper for example repos: -# - Downloads the appropriate prebuilt LiveKit C++ SDK release asset for the host OS/arch +# - Downloads the appropriate prebuilt LiveKit C++ SDK asset for the host OS/arch +# * From a tagged GitHub Release (VERSION mode), or +# * From a per-commit "Builds" workflow artifact (COMMIT mode) # - Extracts it into a local directory (default: /_deps/livekit-sdk) # - Prepends the extracted prefix to CMAKE_PREFIX_PATH so: # find_package(LiveKit CONFIG REQUIRED) # works out of the box. # -# Usage: +# Usage (release): # list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # include(LiveKitSDK) # livekit_sdk_setup(VERSION "latest" SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk") # +# Usage (pin to an upstream commit on main): +# livekit_sdk_setup( +# COMMIT "f7a8df1b72207d0a81390e64e73f4eb5a4811c56" +# SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk" +# GITHUB_TOKEN "$ENV{GITHUB_TOKEN}") +# # Optional: # livekit_sdk_setup(VERSION "latest" REPO "livekit/client-sdk-cpp" GITHUB_TOKEN "$ENV{GITHUB_TOKEN}") @@ -59,6 +67,239 @@ function(_lk_archive_ext out_ext) endif() endfunction() +# -------------------- Commit-mode helpers -------------------- +# Build a list of curl-style HTTPHEADER args for the GitHub REST API. +# Always sets a User-Agent and (when token is non-empty) Authorization. +function(_lk_github_headers out_headers github_token) + set(_headers + "User-Agent: cmake-livekit-sdk/1.0" + "Accept: application/vnd.github+json" + "X-GitHub-Api-Version: 2022-11-28" + ) + if(NOT "${github_token}" STREQUAL "") + string(STRIP "${github_token}" github_token) + endif() + if(NOT "${github_token}" STREQUAL "") + list(APPEND _headers "Authorization: Bearer ${github_token}") + endif() + set(${out_headers} "${_headers}" PARENT_SCOPE) +endfunction() + +# Find the most recent successful "Builds" workflow run for the given commit +# on main, and return its artifact id matching `livekit-sdk-`. +function(_lk_resolve_commit_artifact + out_artifact_id + out_resolved_sha + repo + commit + triple + download_dir + github_token) + if(NOT download_dir) + set(download_dir "${CMAKE_BINARY_DIR}/_downloads") + endif() + file(MAKE_DIRECTORY "${download_dir}") + + _lk_github_headers(_headers "${github_token}") + if("${github_token}" STREQUAL "") + message(STATUS "LiveKitSDK: no GITHUB_TOKEN provided; " + "GitHub API may rate-limit and artifact downloads will fail.") + endif() + + # GitHub API requires the full 40-char SHA for the head_sha filter to work, + # so resolve any prefix to a full SHA via the commits endpoint first. + string(LENGTH "${commit}" _commit_len) + set(_full_sha "${commit}") + if(NOT _commit_len EQUAL 40) + set(_commit_url "https://api.github.com/repos/${repo}/commits/${commit}") + set(_commit_json "${download_dir}/livekit_commit_${commit}.json") + set(_dl_args TLS_VERIFY ON STATUS _st) + foreach(_h IN LISTS _headers) + list(APPEND _dl_args HTTPHEADER "${_h}") + endforeach() + file(DOWNLOAD "${_commit_url}" "${_commit_json}" ${_dl_args}) + list(GET _st 0 _code) + list(GET _st 1 _msg) + if(NOT _code EQUAL 0) + message(FATAL_ERROR + "LiveKitSDK: failed to resolve commit ${commit} via GitHub API\n" + "URL: ${_commit_url}\nStatus: ${_code}\nMessage: ${_msg}") + endif() + file(READ "${_commit_json}" _commit_body) + string(JSON _full_sha GET "${_commit_body}" sha) + endif() + + # Find a successful run of the "Builds" workflow for this exact commit. + set(_runs_url + "https://api.github.com/repos/${repo}/actions/workflows/builds.yml/runs?head_sha=${_full_sha}&status=success&per_page=20") + set(_runs_json "${download_dir}/livekit_runs_${_full_sha}.json") + set(_dl_args TLS_VERIFY ON STATUS _st LOG _log) + foreach(_h IN LISTS _headers) + list(APPEND _dl_args HTTPHEADER "${_h}") + endforeach() + file(DOWNLOAD "${_runs_url}" "${_runs_json}" ${_dl_args}) + list(GET _st 0 _code) + list(GET _st 1 _msg) + if(NOT _code EQUAL 0) + message(STATUS "LiveKitSDK: GitHub API log:\n${_log}") + message(FATAL_ERROR + "LiveKitSDK: failed to query Builds runs for ${_full_sha}\n" + "URL: ${_runs_url}\nStatus: ${_code}\nMessage: ${_msg}") + endif() + file(READ "${_runs_json}" _runs_body) + string(JSON _total_count ERROR_VARIABLE _err GET "${_runs_body}" total_count) + if(NOT _err STREQUAL "NOTFOUND" OR _total_count LESS_EQUAL 0) + if(_err STREQUAL "NOTFOUND") + # _total_count is set to the value + else() + message(FATAL_ERROR + "LiveKitSDK: GitHub API response missing total_count: ${_runs_body}") + endif() + endif() + if(_total_count LESS_EQUAL 0) + message(FATAL_ERROR + "LiveKitSDK: No successful Builds runs found for commit ${_full_sha} on ${repo}.\n" + "Either the commit is too old (artifacts expire after ~7 days), the build hasn't " + "completed yet, or the commit isn't on a branch CI runs against.") + endif() + + # Pick the newest run (the API returns newest first by default). + string(JSON _run_id GET "${_runs_body}" workflow_runs 0 id) + + # List artifacts for that run. + set(_artifacts_url "https://api.github.com/repos/${repo}/actions/runs/${_run_id}/artifacts?per_page=100") + set(_artifacts_json "${download_dir}/livekit_artifacts_${_run_id}.json") + set(_dl_args TLS_VERIFY ON STATUS _st LOG _log) + foreach(_h IN LISTS _headers) + list(APPEND _dl_args HTTPHEADER "${_h}") + endforeach() + file(DOWNLOAD "${_artifacts_url}" "${_artifacts_json}" ${_dl_args}) + list(GET _st 0 _code) + list(GET _st 1 _msg) + if(NOT _code EQUAL 0) + message(STATUS "LiveKitSDK: GitHub API log:\n${_log}") + message(FATAL_ERROR + "LiveKitSDK: failed to list artifacts for run ${_run_id}\n" + "URL: ${_artifacts_url}\nStatus: ${_code}\nMessage: ${_msg}") + endif() + file(READ "${_artifacts_json}" _artifacts_body) + + set(_target_name "livekit-sdk-${triple}") + string(JSON _artifact_count GET "${_artifacts_body}" total_count) + set(_found_id "") + set(_found_expired TRUE) + if(_artifact_count GREATER 0) + math(EXPR _last "${_artifact_count} - 1") + foreach(_i RANGE 0 ${_last}) + string(JSON _name GET "${_artifacts_body}" artifacts ${_i} name) + if(_name STREQUAL "${_target_name}") + string(JSON _id GET "${_artifacts_body}" artifacts ${_i} id) + string(JSON _expired GET "${_artifacts_body}" artifacts ${_i} expired) + set(_found_id "${_id}") + if(_expired) + set(_found_expired TRUE) + else() + set(_found_expired FALSE) + endif() + break() + endif() + endforeach() + endif() + + if(_found_id STREQUAL "") + message(FATAL_ERROR + "LiveKitSDK: artifact '${_target_name}' not found in Builds run ${_run_id} for ${_full_sha}.\n" + "Available artifacts may have expired (~7 day retention).") + endif() + if(_found_expired) + message(FATAL_ERROR + "LiveKitSDK: artifact '${_target_name}' for ${_full_sha} has expired.\n" + "Pin to a more recent commit, or use a tagged VERSION instead.") + endif() + + set(${out_artifact_id} "${_found_id}" PARENT_SCOPE) + set(${out_resolved_sha} "${_full_sha}" PARENT_SCOPE) +endfunction() + +# Synthesize the LiveKit CMake package config files inside an extracted +# per-commit artifact (which lacks the lib/cmake/LiveKit/ tree the tagged +# release tarballs ship with). +function(_lk_write_cmake_config extracted_root) + _lk_detect_host(_os _arch) + if(_os STREQUAL "windows") + set(_lib_name "livekit.lib") + set(_runtime_name "livekit.dll") + set(_imp_kind "SHARED") + elseif(_os STREQUAL "macos") + set(_lib_name "liblivekit.dylib") + set(_runtime_name "${_lib_name}") + set(_imp_kind "SHARED") + else() + set(_lib_name "liblivekit.so") + set(_runtime_name "${_lib_name}") + set(_imp_kind "SHARED") + endif() + + set(_cmake_dir "${extracted_root}/lib/cmake/LiveKit") + file(MAKE_DIRECTORY "${_cmake_dir}") + + file(WRITE "${_cmake_dir}/LiveKitConfig.cmake" +"# Auto-generated by LiveKitSDK.cmake for per-commit artifact builds. +get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/../../../\" ABSOLUTE) +include(\"\${CMAKE_CURRENT_LIST_DIR}/LiveKitTargets.cmake\") +") + + if(_os STREQUAL "windows") + set(_lib_path "\${_IMPORT_PREFIX}/lib/${_lib_name}") + set(_imploc_lines +" IMPORTED_IMPLIB_RELEASE \"\${_IMPORT_PREFIX}/lib/${_lib_name}\" + IMPORTED_LOCATION_RELEASE \"\${_IMPORT_PREFIX}/bin/${_runtime_name}\"") + else() + set(_imploc_lines +" IMPORTED_LOCATION_RELEASE \"\${_IMPORT_PREFIX}/lib/${_runtime_name}\"") + endif() + + file(WRITE "${_cmake_dir}/LiveKitTargets.cmake" +"# Auto-generated by LiveKitSDK.cmake. +if(TARGET LiveKit::livekit) + return() +endif() + +get_filename_component(_IMPORT_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH) +get_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH) +get_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH) +get_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH) + +add_library(LiveKit::livekit ${_imp_kind} IMPORTED) +set_target_properties(LiveKit::livekit PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES \"\${_IMPORT_PREFIX}/include\" +) + +file(GLOB _cmake_config_files \"\${CMAKE_CURRENT_LIST_DIR}/LiveKitTargets-*.cmake\") +foreach(_cmake_config_file IN LISTS _cmake_config_files) + include(\"\${_cmake_config_file}\") +endforeach() +unset(_cmake_config_file) +unset(_cmake_config_files) +unset(_IMPORT_PREFIX) +") + + file(WRITE "${_cmake_dir}/LiveKitTargets-release.cmake" +"# Auto-generated by LiveKitSDK.cmake. +set_property(TARGET LiveKit::livekit APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) +set_target_properties(LiveKit::livekit PROPERTIES +${_imploc_lines} +) +") + + file(WRITE "${_cmake_dir}/LiveKitConfigVersion.cmake" +"# Auto-generated stub. Per-commit artifact builds report version 0.0.0. +set(PACKAGE_VERSION \"0.0.0\") +set(PACKAGE_VERSION_COMPATIBLE TRUE) +set(PACKAGE_VERSION_EXACT FALSE) +") +endfunction() + # -------------------- GitHub API helpers -------------------- # Resolve VERSION="latest" via GitHub API, returning version without leading "v". function(_lk_resolve_latest_version out_version repo download_dir github_token) @@ -136,22 +377,36 @@ endfunction() # -------------------- Public entrypoint -------------------- # livekit_sdk_setup( -# VERSION +# [VERSION ] tagged release (e.g. "0.3.4" or "latest") +# [COMMIT ] OR pin to per-commit Builds artifact # SDK_DIR # [REPO ] default: livekit/client-sdk-cpp # [SHA256 ] optional: verify download (only works for fixed VERSION) # [TRIPLE ] optional override # [DOWNLOAD_DIR ] default: /_downloads -# [GITHUB_TOKEN ] optional: auth for GitHub API when VERSION=latest +# [GITHUB_TOKEN ] optional/required: auth for GitHub API +# - VERSION=latest: optional, avoids rate limits +# - COMMIT mode: required (artifact downloads need auth) # [NO_DOWNLOAD] error if not already present # ) +# +# Exactly one of VERSION or COMMIT must be provided. COMMIT mode downloads the +# `livekit-sdk-` artifact uploaded by the upstream "Builds" workflow +# for that commit on `main`. Note: GitHub Actions artifacts have a 7-day +# retention by default; pinning to old commits will fail. function(livekit_sdk_setup) set(options NO_DOWNLOAD) - set(oneValueArgs VERSION SDK_DIR REPO SHA256 TRIPLE DOWNLOAD_DIR GITHUB_TOKEN) + set(oneValueArgs VERSION COMMIT SDK_DIR REPO SHA256 TRIPLE DOWNLOAD_DIR GITHUB_TOKEN) cmake_parse_arguments(LK "${options}" "${oneValueArgs}" "" ${ARGN}) - if(NOT LK_VERSION) - message(FATAL_ERROR "livekit_sdk_setup: VERSION is required (use \"latest\" if desired)") + if(LK_VERSION AND LK_COMMIT) + message(FATAL_ERROR + "livekit_sdk_setup: pass either VERSION or COMMIT, not both") + endif() + if(NOT LK_VERSION AND NOT LK_COMMIT) + message(FATAL_ERROR + "livekit_sdk_setup: VERSION or COMMIT is required " + "(VERSION=\"latest\" picks the newest release)") endif() if(NOT LK_SDK_DIR) message(FATAL_ERROR "livekit_sdk_setup: SDK_DIR is required") @@ -167,6 +422,89 @@ function(livekit_sdk_setup) _lk_default_triple(LK_TRIPLE) endif() + # -------------------- COMMIT mode -------------------- + if(LK_COMMIT) + if(NOT LK_GITHUB_TOKEN) + set(LK_GITHUB_TOKEN "$ENV{GITHUB_TOKEN}") + endif() + if("${LK_GITHUB_TOKEN}" STREQUAL "") + message(FATAL_ERROR + "LiveKitSDK: COMMIT mode requires GITHUB_TOKEN (artifact API needs auth).\n" + "Provide it via livekit_sdk_setup(... GITHUB_TOKEN ...) or env var GITHUB_TOKEN.") + endif() + if(LK_SHA256) + message(WARNING "LiveKitSDK: SHA256 ignored when COMMIT is set " + "(per-commit artifact contents change with each rebuild).") + endif() + + string(SUBSTRING "${LK_COMMIT}" 0 12 _short_sha) + set(_extracted_root "${LK_SDK_DIR}/livekit-sdk-${LK_TRIPLE}-commit-${_short_sha}") + set(_archive_path "${LK_DOWNLOAD_DIR}/livekit-sdk-${LK_TRIPLE}-commit-${_short_sha}.zip") + + file(MAKE_DIRECTORY "${LK_DOWNLOAD_DIR}") + file(MAKE_DIRECTORY "${LK_SDK_DIR}") + + if(NOT EXISTS "${_extracted_root}/lib/cmake/LiveKit/LiveKitConfig.cmake") + if(LK_NO_DOWNLOAD) + message(FATAL_ERROR + "LiveKitSDK: SDK not found at:\n ${_extracted_root}\n" + "and NO_DOWNLOAD was set.") + endif() + + _lk_resolve_commit_artifact(_artifact_id _full_sha + "${LK_REPO}" "${LK_COMMIT}" "${LK_TRIPLE}" + "${LK_DOWNLOAD_DIR}" "${LK_GITHUB_TOKEN}") + message(STATUS "LiveKitSDK: pinning to commit ${_full_sha}") + message(STATUS "LiveKitSDK: artifact id = ${_artifact_id}") + + _lk_github_headers(_headers "${LK_GITHUB_TOKEN}") + set(_artifact_url + "https://api.github.com/repos/${LK_REPO}/actions/artifacts/${_artifact_id}/zip") + set(_dl_args SHOW_PROGRESS TLS_VERIFY ON STATUS _st LOG _log) + foreach(_h IN LISTS _headers) + list(APPEND _dl_args HTTPHEADER "${_h}") + endforeach() + message(STATUS "LiveKitSDK: downloading ${_artifact_url}") + file(DOWNLOAD "${_artifact_url}" "${_archive_path}" ${_dl_args}) + list(GET _st 0 _code) + list(GET _st 1 _msg) + if(NOT _code EQUAL 0) + message(STATUS "LiveKitSDK: artifact download log:\n${_log}") + message(FATAL_ERROR + "LiveKitSDK: failed to download artifact ${_artifact_id}\n" + "URL: ${_artifact_url}\nStatus: ${_code}\nMessage: ${_msg}") + endif() + + file(REMOVE_RECURSE "${_extracted_root}") + file(MAKE_DIRECTORY "${_extracted_root}") + message(STATUS "LiveKitSDK: extracting ${_archive_path}") + file(ARCHIVE_EXTRACT + INPUT "${_archive_path}" + DESTINATION "${_extracted_root}") + + _lk_write_cmake_config("${_extracted_root}") + endif() + + if(NOT EXISTS "${_extracted_root}/include/livekit/livekit.h") + message(FATAL_ERROR + "LiveKitSDK: extracted artifact looks invalid (missing include/livekit/livekit.h)\n" + "Path: ${_extracted_root}") + endif() + + 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) + + set(LIVEKIT_SDK_EXTRACTED_ROOT "${_extracted_root}" CACHE PATH "LiveKit SDK extracted root" FORCE) + set(LIVEKIT_SDK_URL_USED "${_artifact_url}" CACHE STRING "LiveKit SDK URL used" FORCE) + set(LIVEKIT_SDK_VERSION_RESOLVED "commit-${_short_sha}" CACHE STRING "LiveKit SDK resolved version" FORCE) + set(LIVEKIT_SDK_TRIPLE_USED "${LK_TRIPLE}" CACHE STRING "LiveKit SDK triple used" FORCE) + set(LIVEKIT_SDK_COMMIT_RESOLVED "${LK_COMMIT}" CACHE STRING "LiveKit SDK commit resolved" FORCE) + + message(STATUS "LiveKitSDK: using SDK at ${_extracted_root}") + return() + endif() + # Resolve latest tag if requested set(_resolved_version "${LK_VERSION}") if(LK_VERSION STREQUAL "latest") diff --git a/hello_livekit/receiver/main.cpp b/hello_livekit/receiver/main.cpp index 413a845..7e877a5 100644 --- a/hello_livekit/receiver/main.cpp +++ b/hello_livekit/receiver/main.cpp @@ -77,7 +77,7 @@ int main(int argc, char* argv[]) { options.auto_subscribe = true; options.dynacast = false; - if (!room->Connect(url, receiver_token, options)) { + if (!room->connect(url, receiver_token, options)) { std::cerr << "[error] [receiver] Failed to connect\n"; livekit::shutdown(); return 1; @@ -86,7 +86,7 @@ int main(int argc, char* argv[]) { LocalParticipant* lp = room->localParticipant(); assert(lp); - std::cout << "[info] [receiver] Connected as identity='" << lp->identity() << "' room='" << room->room_info().name + std::cout << "[info] [receiver] Connected as identity='" << lp->identity() << "' room='" << room->roomInfo().name << "'; subscribing to sender identity='" << sender_identity << "'\n"; int video_frame_count = 0; diff --git a/hello_livekit/sender/main.cpp b/hello_livekit/sender/main.cpp index 780d2d8..d388f84 100644 --- a/hello_livekit/sender/main.cpp +++ b/hello_livekit/sender/main.cpp @@ -78,7 +78,7 @@ int main(int argc, char* argv[]) { options.auto_subscribe = true; options.dynacast = false; - if (!room->Connect(url, sender_token, options)) { + if (!room->connect(url, sender_token, options)) { std::cerr << "[error] [sender] Failed to connect\n"; livekit::shutdown(); return 1; @@ -87,7 +87,7 @@ int main(int argc, char* argv[]) { LocalParticipant* lp = room->localParticipant(); assert(lp); - std::cout << "[info] [sender] Connected as identity='" << lp->identity() << "' room='" << room->room_info().name + std::cout << "[info] [sender] Connected as identity='" << lp->identity() << "' room='" << room->roomInfo().name << "' — pass this identity to HelloLivekitReceiver\n"; auto video_source = std::make_shared(kWidth, kHeight); diff --git a/ping_pong/ping/main.cpp b/ping_pong/ping/main.cpp index c2f6e62..b21c125 100644 --- a/ping_pong/ping/main.cpp +++ b/ping_pong/ping/main.cpp @@ -92,7 +92,7 @@ int main(int argc, char* argv[]) { options.auto_subscribe = true; options.dynacast = false; - if (!room->Connect(url, token, options)) { + if (!room->connect(url, token, options)) { std::cerr << "[error] Failed to connect to room\n"; livekit::shutdown(); return 1; @@ -102,7 +102,7 @@ int main(int argc, char* argv[]) { assert(local_participant); std::cout << "[info] ping connected as identity='" << local_participant->identity() << "' room='" - << room->room_info().name << "'\n"; + << room->roomInfo().name << "'\n"; auto publish_result = local_participant->publishDataTrack(ping_pong::kPingTrackName); if (!publish_result) { diff --git a/ping_pong/pong/main.cpp b/ping_pong/pong/main.cpp index 6e1fea4..3421779 100644 --- a/ping_pong/pong/main.cpp +++ b/ping_pong/pong/main.cpp @@ -71,7 +71,7 @@ int main(int argc, char* argv[]) { options.auto_subscribe = true; options.dynacast = false; - if (!room->Connect(url, token, options)) { + if (!room->connect(url, token, options)) { std::cerr << "[error] Failed to connect to room\n"; livekit::shutdown(); return 1; @@ -81,7 +81,7 @@ int main(int argc, char* argv[]) { assert(local_participant); std::cout << "[info] pong connected as identity='" << local_participant->identity() << "' room='" - << room->room_info().name << "'\n"; + << room->roomInfo().name << "'\n"; auto publish_result = local_participant->publishDataTrack(ping_pong::kPongTrackName); if (!publish_result) { diff --git a/simple_data_stream/main.cpp b/simple_data_stream/main.cpp index e3f63e3..1edb2f7 100644 --- a/simple_data_stream/main.cpp +++ b/simple_data_stream/main.cpp @@ -213,7 +213,7 @@ int main(int argc, char* argv[]) { options.auto_subscribe = true; options.dynacast = false; - bool ok = room->Connect(url, token, options); + bool ok = room->connect(url, token, options); std::cout << "[DataStream] Connect result: " << std::boolalpha << ok << "\n"; if (!ok) { std::cerr << "[DataStream] Failed to connect to room\n"; @@ -221,7 +221,7 @@ int main(int argc, char* argv[]) { return 1; } - auto info = room->room_info(); + auto info = room->roomInfo(); std::cout << "[DataStream] Connected to room '" << info.name << "', participants: " << info.num_participants << "\n"; // Register stream handlers diff --git a/simple_joystick/receiver/main.cpp b/simple_joystick/receiver/main.cpp index 5f835ba..f227606 100644 --- a/simple_joystick/receiver/main.cpp +++ b/simple_joystick/receiver/main.cpp @@ -65,7 +65,7 @@ int main(int argc, char* argv[]) { options.auto_subscribe = true; options.dynacast = false; - bool res = room->Connect(url, token, options); + bool res = room->connect(url, token, options); std::cout << "[Receiver] Connect result: " << std::boolalpha << res << "\n"; if (!res) { std::cerr << "[Receiver] Failed to connect to room\n"; @@ -73,7 +73,7 @@ int main(int argc, char* argv[]) { return 1; } - auto info = room->room_info(); + auto info = room->roomInfo(); std::cout << "[Receiver] Connected to room: " << info.name << "\n"; std::cout << "[Receiver] Waiting for sender peer (up to 2 minutes)...\n"; diff --git a/simple_joystick/sender/main.cpp b/simple_joystick/sender/main.cpp index 2d1b749..128c662 100644 --- a/simple_joystick/sender/main.cpp +++ b/simple_joystick/sender/main.cpp @@ -133,7 +133,7 @@ int main(int argc, char* argv[]) { options.auto_subscribe = true; options.dynacast = false; - bool res = room->Connect(url, token, options); + bool res = room->connect(url, token, options); std::cout << "[Sender] Connect result: " << std::boolalpha << res << "\n"; if (!res) { std::cerr << "[Sender] Failed to connect to room\n"; @@ -141,7 +141,7 @@ int main(int argc, char* argv[]) { return 1; } - auto info = room->room_info(); + auto info = room->roomInfo(); std::cout << "[Sender] Connected to room: " << info.name << "\n"; // Enable raw terminal mode for immediate keypress detection diff --git a/simple_room/fallback_capture.cpp b/simple_room/fallback_capture.cpp index 9fa080e..2a3f977 100644 --- a/simple_room/fallback_capture.cpp +++ b/simple_room/fallback_capture.cpp @@ -30,8 +30,8 @@ using namespace livekit; // Test utils to run a capture loop to publish noisy audio frames to the room void runNoiseCaptureLoop(const std::shared_ptr& source, std::atomic& running_flag) { - const int sample_rate = source->sample_rate(); - const int num_channels = source->num_channels(); + const int sample_rate = source->sampleRate(); + const int num_channels = source->numChannels(); const int frame_ms = 10; const int samples_per_channel = sample_rate * frame_ms / 1000; diff --git a/simple_room/main.cpp b/simple_room/main.cpp index 8b9367f..1ae15cb 100644 --- a/simple_room/main.cpp +++ b/simple_room/main.cpp @@ -272,7 +272,7 @@ int main(int argc, char* argv[]) { } } - bool res = room->Connect(url, token, options); + bool res = room->connect(url, token, options); std::cout << "Connect result is " << std::boolalpha << res << std::endl; if (!res) { std::cerr << "[error] Failed to connect to room\n"; @@ -280,7 +280,7 @@ int main(int argc, char* argv[]) { return 1; } - auto info = room->room_info(); + auto info = room->roomInfo(); std::cout << "Connected to room:\n" << " SID: " << (info.sid ? *info.sid : "(none)") << "\n" << " Name: " << info.name << "\n" diff --git a/simple_room/sdl_media_manager.cpp b/simple_room/sdl_media_manager.cpp index b0be500..ea955d5 100644 --- a/simple_room/sdl_media_manager.cpp +++ b/simple_room/sdl_media_manager.cpp @@ -82,8 +82,8 @@ bool SDLMediaManager::startMic(const std::shared_ptr& audio_source) mic_using_sdl_ = true; mic_sdl_ = std::make_unique( - mic_source_->sample_rate(), mic_source_->num_channels(), - mic_source_->sample_rate() / 100, // ~10ms + mic_source_->sampleRate(), mic_source_->numChannels(), + mic_source_->sampleRate() / 100, // ~10ms [src = mic_source_](const int16_t* samples, int num_samples_per_channel, int sample_rate, int num_channels) { AudioFrame frame = AudioFrame::create(sample_rate, num_channels, num_samples_per_channel); std::memcpy(frame.data().data(), samples, num_samples_per_channel * num_channels * sizeof(int16_t)); @@ -263,8 +263,8 @@ void SDLMediaManager::speakerLoopSDL() { if (!localStream) { SDL_AudioSpec want{}; want.format = SDL_AUDIO_S16; - want.channels = static_cast(frame.num_channels()); - want.freq = frame.sample_rate(); + want.channels = static_cast(frame.numChannels()); + want.freq = frame.sampleRate(); localStream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &want, /*callback=*/nullptr, diff --git a/simple_room/wav_audio_source.cpp b/simple_room/wav_audio_source.cpp index 62a430b..c08c636 100644 --- a/simple_room/wav_audio_source.cpp +++ b/simple_room/wav_audio_source.cpp @@ -136,7 +136,7 @@ WavAudioSource::WavAudioSource(const std::string& path, int expected_sample_rate void WavAudioSource::fillFrame(AudioFrame& frame) { const std::size_t frame_samples = - static_cast(frame.num_channels()) * static_cast(frame.samples_per_channel()); + static_cast(frame.numChannels()) * static_cast(frame.samplesPerChannel()); int16_t* dst = frame.data().data(); const std::size_t total_wav_samples = wav_.samples.size(); diff --git a/simple_rpc/main.cpp b/simple_rpc/main.cpp index 9ecdf74..2e22989 100644 --- a/simple_rpc/main.cpp +++ b/simple_rpc/main.cpp @@ -86,7 +86,7 @@ bool ensurePeerPresent(Room* room, const std::string& identity, const std::strin return true; } // Timed out - auto info = room->room_info(); + auto info = room->roomInfo(); const std::string room_name = info.name; std::cout << "[Caller] Timed out after " << timeout.count() << "s waiting for " << friendly_role << " (identity=\"" << identity << "\").\n"; @@ -408,7 +408,7 @@ int main(int argc, char* argv[]) { options.auto_subscribe = true; options.dynacast = false; - bool res = room->Connect(url, token, options); + bool res = room->connect(url, token, options); std::cout << "Connect result is " << std::boolalpha << res << "\n"; if (!res) { std::cerr << "Failed to connect to room\n"; @@ -416,7 +416,7 @@ int main(int argc, char* argv[]) { return 1; } - auto info = room->room_info(); + auto info = room->roomInfo(); std::cout << "Connected to room:\n" << " Name: " << info.name << "\n" << " Metadata: " << info.metadata << "\n" diff --git a/user_timestamped_video/consumer/main.cpp b/user_timestamped_video/consumer/main.cpp index 904b37c..291f646 100644 --- a/user_timestamped_video/consumer/main.cpp +++ b/user_timestamped_video/consumer/main.cpp @@ -159,12 +159,12 @@ int main(int argc, char* argv[]) { room.setDelegate(&delegate); std::cout << "[consumer] connecting to " << cli_options.url << "\n"; - if (!room.Connect(cli_options.url, cli_options.token, options)) { + if (!room.connect(cli_options.url, cli_options.token, options)) { std::cerr << "[consumer] failed to connect\n"; exit_code = 1; } else { std::cout << "[consumer] connected as " << room.localParticipant()->identity() << " to room '" - << room.room_info().name << "' with user timestamp " + << room.roomInfo().name << "' with user timestamp " << (cli_options.use_user_timestamp ? "enabled" : "ignored") << "\n"; delegate.registerExistingParticipants(); diff --git a/user_timestamped_video/producer/main.cpp b/user_timestamped_video/producer/main.cpp index 73cd608..13830a0 100644 --- a/user_timestamped_video/producer/main.cpp +++ b/user_timestamped_video/producer/main.cpp @@ -89,12 +89,12 @@ int main(int argc, char* argv[]) { options.dynacast = false; std::cout << "[producer] connecting to " << cli_options.url << "\n"; - if (!room.Connect(cli_options.url, cli_options.token, options)) { + if (!room.connect(cli_options.url, cli_options.token, options)) { std::cerr << "[producer] failed to connect\n"; exit_code = 1; } else { std::cout << "[producer] connected as " << room.localParticipant()->identity() << " to room '" - << room.room_info().name << "'\n"; + << room.roomInfo().name << "'\n"; auto source = std::make_shared(kFrameWidth, kFrameHeight); auto track = LocalVideoTrack::createLocalVideoTrack("timestamped-camera", source); From ddcee863e089d7c7512c453bd0d9a7b559a7e18c Mon Sep 17 00:00:00 2001 From: Alan George Date: Wed, 27 May 2026 14:14:21 -0600 Subject: [PATCH 2/2] Try latest build --- CMakeLists.txt | 34 +--- cmake/LiveKitSDK.cmake | 352 +---------------------------------------- 2 files changed, 13 insertions(+), 373 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c516153..6d382af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,13 +21,7 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON) # Make "include(LiveKitSDK)" search in ./cmake list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -set(LIVEKIT_SDK_VERSION "" CACHE STRING - "LiveKit C++ SDK release version (e.g. 0.3.4 or latest). Empty when LIVEKIT_SDK_COMMIT is used.") -# Temporary pin: tracks an unreleased commit on `livekit/client-sdk-cpp@main` -# that contains the unified-method-style guide changes (PR #127). Switch back -# to LIVEKIT_SDK_VERSION once a tagged release ships those changes. -set(LIVEKIT_SDK_COMMIT "f7a8df1b72207d0a81390e64e73f4eb5a4811c56" CACHE STRING - "LiveKit C++ SDK commit hash on main (uses Builds workflow artifacts; ~7d retention).") +set(LIVEKIT_SDK_VERSION "latest" CACHE STRING "LiveKit C++ SDK version (e.g. 0.2.0 or latest)") set(LIVEKIT_LOCAL_SDK_DIR "" CACHE PATH "Path to a local LiveKit SDK install prefix (skips download)") if(LIVEKIT_LOCAL_SDK_DIR) @@ -35,27 +29,11 @@ if(LIVEKIT_LOCAL_SDK_DIR) list(PREPEND CMAKE_PREFIX_PATH "${LIVEKIT_LOCAL_SDK_DIR}") else() include(LiveKitSDK) - if(LIVEKIT_SDK_COMMIT AND LIVEKIT_SDK_VERSION) - message(FATAL_ERROR - "Set either LIVEKIT_SDK_COMMIT or LIVEKIT_SDK_VERSION, not both.\n" - "Got LIVEKIT_SDK_COMMIT='${LIVEKIT_SDK_COMMIT}' and LIVEKIT_SDK_VERSION='${LIVEKIT_SDK_VERSION}'.") - endif() - if(LIVEKIT_SDK_COMMIT) - livekit_sdk_setup( - COMMIT "${LIVEKIT_SDK_COMMIT}" - SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk" - GITHUB_TOKEN "$ENV{GITHUB_TOKEN}" - ) - else() - if(NOT LIVEKIT_SDK_VERSION) - set(LIVEKIT_SDK_VERSION "latest") - endif() - livekit_sdk_setup( - VERSION "${LIVEKIT_SDK_VERSION}" - SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk" - GITHUB_TOKEN "$ENV{GITHUB_TOKEN}" - ) - endif() + livekit_sdk_setup( + VERSION "${LIVEKIT_SDK_VERSION}" + SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk" + GITHUB_TOKEN "$ENV{GITHUB_TOKEN}" + ) endif() find_package(LiveKit CONFIG REQUIRED) diff --git a/cmake/LiveKitSDK.cmake b/cmake/LiveKitSDK.cmake index 0c73df2..02d36fa 100644 --- a/cmake/LiveKitSDK.cmake +++ b/cmake/LiveKitSDK.cmake @@ -1,25 +1,17 @@ # LiveKitSDK.cmake # # Helper for example repos: -# - Downloads the appropriate prebuilt LiveKit C++ SDK asset for the host OS/arch -# * From a tagged GitHub Release (VERSION mode), or -# * From a per-commit "Builds" workflow artifact (COMMIT mode) +# - Downloads the appropriate prebuilt LiveKit C++ SDK release asset for the host OS/arch # - Extracts it into a local directory (default: /_deps/livekit-sdk) # - Prepends the extracted prefix to CMAKE_PREFIX_PATH so: # find_package(LiveKit CONFIG REQUIRED) # works out of the box. # -# Usage (release): +# Usage: # list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # include(LiveKitSDK) # livekit_sdk_setup(VERSION "latest" SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk") # -# Usage (pin to an upstream commit on main): -# livekit_sdk_setup( -# COMMIT "f7a8df1b72207d0a81390e64e73f4eb5a4811c56" -# SDK_DIR "${CMAKE_BINARY_DIR}/_deps/livekit-sdk" -# GITHUB_TOKEN "$ENV{GITHUB_TOKEN}") -# # Optional: # livekit_sdk_setup(VERSION "latest" REPO "livekit/client-sdk-cpp" GITHUB_TOKEN "$ENV{GITHUB_TOKEN}") @@ -67,239 +59,6 @@ function(_lk_archive_ext out_ext) endif() endfunction() -# -------------------- Commit-mode helpers -------------------- -# Build a list of curl-style HTTPHEADER args for the GitHub REST API. -# Always sets a User-Agent and (when token is non-empty) Authorization. -function(_lk_github_headers out_headers github_token) - set(_headers - "User-Agent: cmake-livekit-sdk/1.0" - "Accept: application/vnd.github+json" - "X-GitHub-Api-Version: 2022-11-28" - ) - if(NOT "${github_token}" STREQUAL "") - string(STRIP "${github_token}" github_token) - endif() - if(NOT "${github_token}" STREQUAL "") - list(APPEND _headers "Authorization: Bearer ${github_token}") - endif() - set(${out_headers} "${_headers}" PARENT_SCOPE) -endfunction() - -# Find the most recent successful "Builds" workflow run for the given commit -# on main, and return its artifact id matching `livekit-sdk-`. -function(_lk_resolve_commit_artifact - out_artifact_id - out_resolved_sha - repo - commit - triple - download_dir - github_token) - if(NOT download_dir) - set(download_dir "${CMAKE_BINARY_DIR}/_downloads") - endif() - file(MAKE_DIRECTORY "${download_dir}") - - _lk_github_headers(_headers "${github_token}") - if("${github_token}" STREQUAL "") - message(STATUS "LiveKitSDK: no GITHUB_TOKEN provided; " - "GitHub API may rate-limit and artifact downloads will fail.") - endif() - - # GitHub API requires the full 40-char SHA for the head_sha filter to work, - # so resolve any prefix to a full SHA via the commits endpoint first. - string(LENGTH "${commit}" _commit_len) - set(_full_sha "${commit}") - if(NOT _commit_len EQUAL 40) - set(_commit_url "https://api.github.com/repos/${repo}/commits/${commit}") - set(_commit_json "${download_dir}/livekit_commit_${commit}.json") - set(_dl_args TLS_VERIFY ON STATUS _st) - foreach(_h IN LISTS _headers) - list(APPEND _dl_args HTTPHEADER "${_h}") - endforeach() - file(DOWNLOAD "${_commit_url}" "${_commit_json}" ${_dl_args}) - list(GET _st 0 _code) - list(GET _st 1 _msg) - if(NOT _code EQUAL 0) - message(FATAL_ERROR - "LiveKitSDK: failed to resolve commit ${commit} via GitHub API\n" - "URL: ${_commit_url}\nStatus: ${_code}\nMessage: ${_msg}") - endif() - file(READ "${_commit_json}" _commit_body) - string(JSON _full_sha GET "${_commit_body}" sha) - endif() - - # Find a successful run of the "Builds" workflow for this exact commit. - set(_runs_url - "https://api.github.com/repos/${repo}/actions/workflows/builds.yml/runs?head_sha=${_full_sha}&status=success&per_page=20") - set(_runs_json "${download_dir}/livekit_runs_${_full_sha}.json") - set(_dl_args TLS_VERIFY ON STATUS _st LOG _log) - foreach(_h IN LISTS _headers) - list(APPEND _dl_args HTTPHEADER "${_h}") - endforeach() - file(DOWNLOAD "${_runs_url}" "${_runs_json}" ${_dl_args}) - list(GET _st 0 _code) - list(GET _st 1 _msg) - if(NOT _code EQUAL 0) - message(STATUS "LiveKitSDK: GitHub API log:\n${_log}") - message(FATAL_ERROR - "LiveKitSDK: failed to query Builds runs for ${_full_sha}\n" - "URL: ${_runs_url}\nStatus: ${_code}\nMessage: ${_msg}") - endif() - file(READ "${_runs_json}" _runs_body) - string(JSON _total_count ERROR_VARIABLE _err GET "${_runs_body}" total_count) - if(NOT _err STREQUAL "NOTFOUND" OR _total_count LESS_EQUAL 0) - if(_err STREQUAL "NOTFOUND") - # _total_count is set to the value - else() - message(FATAL_ERROR - "LiveKitSDK: GitHub API response missing total_count: ${_runs_body}") - endif() - endif() - if(_total_count LESS_EQUAL 0) - message(FATAL_ERROR - "LiveKitSDK: No successful Builds runs found for commit ${_full_sha} on ${repo}.\n" - "Either the commit is too old (artifacts expire after ~7 days), the build hasn't " - "completed yet, or the commit isn't on a branch CI runs against.") - endif() - - # Pick the newest run (the API returns newest first by default). - string(JSON _run_id GET "${_runs_body}" workflow_runs 0 id) - - # List artifacts for that run. - set(_artifacts_url "https://api.github.com/repos/${repo}/actions/runs/${_run_id}/artifacts?per_page=100") - set(_artifacts_json "${download_dir}/livekit_artifacts_${_run_id}.json") - set(_dl_args TLS_VERIFY ON STATUS _st LOG _log) - foreach(_h IN LISTS _headers) - list(APPEND _dl_args HTTPHEADER "${_h}") - endforeach() - file(DOWNLOAD "${_artifacts_url}" "${_artifacts_json}" ${_dl_args}) - list(GET _st 0 _code) - list(GET _st 1 _msg) - if(NOT _code EQUAL 0) - message(STATUS "LiveKitSDK: GitHub API log:\n${_log}") - message(FATAL_ERROR - "LiveKitSDK: failed to list artifacts for run ${_run_id}\n" - "URL: ${_artifacts_url}\nStatus: ${_code}\nMessage: ${_msg}") - endif() - file(READ "${_artifacts_json}" _artifacts_body) - - set(_target_name "livekit-sdk-${triple}") - string(JSON _artifact_count GET "${_artifacts_body}" total_count) - set(_found_id "") - set(_found_expired TRUE) - if(_artifact_count GREATER 0) - math(EXPR _last "${_artifact_count} - 1") - foreach(_i RANGE 0 ${_last}) - string(JSON _name GET "${_artifacts_body}" artifacts ${_i} name) - if(_name STREQUAL "${_target_name}") - string(JSON _id GET "${_artifacts_body}" artifacts ${_i} id) - string(JSON _expired GET "${_artifacts_body}" artifacts ${_i} expired) - set(_found_id "${_id}") - if(_expired) - set(_found_expired TRUE) - else() - set(_found_expired FALSE) - endif() - break() - endif() - endforeach() - endif() - - if(_found_id STREQUAL "") - message(FATAL_ERROR - "LiveKitSDK: artifact '${_target_name}' not found in Builds run ${_run_id} for ${_full_sha}.\n" - "Available artifacts may have expired (~7 day retention).") - endif() - if(_found_expired) - message(FATAL_ERROR - "LiveKitSDK: artifact '${_target_name}' for ${_full_sha} has expired.\n" - "Pin to a more recent commit, or use a tagged VERSION instead.") - endif() - - set(${out_artifact_id} "${_found_id}" PARENT_SCOPE) - set(${out_resolved_sha} "${_full_sha}" PARENT_SCOPE) -endfunction() - -# Synthesize the LiveKit CMake package config files inside an extracted -# per-commit artifact (which lacks the lib/cmake/LiveKit/ tree the tagged -# release tarballs ship with). -function(_lk_write_cmake_config extracted_root) - _lk_detect_host(_os _arch) - if(_os STREQUAL "windows") - set(_lib_name "livekit.lib") - set(_runtime_name "livekit.dll") - set(_imp_kind "SHARED") - elseif(_os STREQUAL "macos") - set(_lib_name "liblivekit.dylib") - set(_runtime_name "${_lib_name}") - set(_imp_kind "SHARED") - else() - set(_lib_name "liblivekit.so") - set(_runtime_name "${_lib_name}") - set(_imp_kind "SHARED") - endif() - - set(_cmake_dir "${extracted_root}/lib/cmake/LiveKit") - file(MAKE_DIRECTORY "${_cmake_dir}") - - file(WRITE "${_cmake_dir}/LiveKitConfig.cmake" -"# Auto-generated by LiveKitSDK.cmake for per-commit artifact builds. -get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/../../../\" ABSOLUTE) -include(\"\${CMAKE_CURRENT_LIST_DIR}/LiveKitTargets.cmake\") -") - - if(_os STREQUAL "windows") - set(_lib_path "\${_IMPORT_PREFIX}/lib/${_lib_name}") - set(_imploc_lines -" IMPORTED_IMPLIB_RELEASE \"\${_IMPORT_PREFIX}/lib/${_lib_name}\" - IMPORTED_LOCATION_RELEASE \"\${_IMPORT_PREFIX}/bin/${_runtime_name}\"") - else() - set(_imploc_lines -" IMPORTED_LOCATION_RELEASE \"\${_IMPORT_PREFIX}/lib/${_runtime_name}\"") - endif() - - file(WRITE "${_cmake_dir}/LiveKitTargets.cmake" -"# Auto-generated by LiveKitSDK.cmake. -if(TARGET LiveKit::livekit) - return() -endif() - -get_filename_component(_IMPORT_PREFIX \"\${CMAKE_CURRENT_LIST_FILE}\" PATH) -get_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH) -get_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH) -get_filename_component(_IMPORT_PREFIX \"\${_IMPORT_PREFIX}\" PATH) - -add_library(LiveKit::livekit ${_imp_kind} IMPORTED) -set_target_properties(LiveKit::livekit PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES \"\${_IMPORT_PREFIX}/include\" -) - -file(GLOB _cmake_config_files \"\${CMAKE_CURRENT_LIST_DIR}/LiveKitTargets-*.cmake\") -foreach(_cmake_config_file IN LISTS _cmake_config_files) - include(\"\${_cmake_config_file}\") -endforeach() -unset(_cmake_config_file) -unset(_cmake_config_files) -unset(_IMPORT_PREFIX) -") - - file(WRITE "${_cmake_dir}/LiveKitTargets-release.cmake" -"# Auto-generated by LiveKitSDK.cmake. -set_property(TARGET LiveKit::livekit APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) -set_target_properties(LiveKit::livekit PROPERTIES -${_imploc_lines} -) -") - - file(WRITE "${_cmake_dir}/LiveKitConfigVersion.cmake" -"# Auto-generated stub. Per-commit artifact builds report version 0.0.0. -set(PACKAGE_VERSION \"0.0.0\") -set(PACKAGE_VERSION_COMPATIBLE TRUE) -set(PACKAGE_VERSION_EXACT FALSE) -") -endfunction() - # -------------------- GitHub API helpers -------------------- # Resolve VERSION="latest" via GitHub API, returning version without leading "v". function(_lk_resolve_latest_version out_version repo download_dir github_token) @@ -377,36 +136,22 @@ endfunction() # -------------------- Public entrypoint -------------------- # livekit_sdk_setup( -# [VERSION ] tagged release (e.g. "0.3.4" or "latest") -# [COMMIT ] OR pin to per-commit Builds artifact +# VERSION # SDK_DIR # [REPO ] default: livekit/client-sdk-cpp # [SHA256 ] optional: verify download (only works for fixed VERSION) # [TRIPLE ] optional override # [DOWNLOAD_DIR ] default: /_downloads -# [GITHUB_TOKEN ] optional/required: auth for GitHub API -# - VERSION=latest: optional, avoids rate limits -# - COMMIT mode: required (artifact downloads need auth) +# [GITHUB_TOKEN ] optional: auth for GitHub API when VERSION=latest # [NO_DOWNLOAD] error if not already present # ) -# -# Exactly one of VERSION or COMMIT must be provided. COMMIT mode downloads the -# `livekit-sdk-` artifact uploaded by the upstream "Builds" workflow -# for that commit on `main`. Note: GitHub Actions artifacts have a 7-day -# retention by default; pinning to old commits will fail. function(livekit_sdk_setup) set(options NO_DOWNLOAD) - set(oneValueArgs VERSION COMMIT SDK_DIR REPO SHA256 TRIPLE DOWNLOAD_DIR GITHUB_TOKEN) + set(oneValueArgs VERSION SDK_DIR REPO SHA256 TRIPLE DOWNLOAD_DIR GITHUB_TOKEN) cmake_parse_arguments(LK "${options}" "${oneValueArgs}" "" ${ARGN}) - if(LK_VERSION AND LK_COMMIT) - message(FATAL_ERROR - "livekit_sdk_setup: pass either VERSION or COMMIT, not both") - endif() - if(NOT LK_VERSION AND NOT LK_COMMIT) - message(FATAL_ERROR - "livekit_sdk_setup: VERSION or COMMIT is required " - "(VERSION=\"latest\" picks the newest release)") + if(NOT LK_VERSION) + message(FATAL_ERROR "livekit_sdk_setup: VERSION is required (use \"latest\" if desired)") endif() if(NOT LK_SDK_DIR) message(FATAL_ERROR "livekit_sdk_setup: SDK_DIR is required") @@ -422,89 +167,6 @@ function(livekit_sdk_setup) _lk_default_triple(LK_TRIPLE) endif() - # -------------------- COMMIT mode -------------------- - if(LK_COMMIT) - if(NOT LK_GITHUB_TOKEN) - set(LK_GITHUB_TOKEN "$ENV{GITHUB_TOKEN}") - endif() - if("${LK_GITHUB_TOKEN}" STREQUAL "") - message(FATAL_ERROR - "LiveKitSDK: COMMIT mode requires GITHUB_TOKEN (artifact API needs auth).\n" - "Provide it via livekit_sdk_setup(... GITHUB_TOKEN ...) or env var GITHUB_TOKEN.") - endif() - if(LK_SHA256) - message(WARNING "LiveKitSDK: SHA256 ignored when COMMIT is set " - "(per-commit artifact contents change with each rebuild).") - endif() - - string(SUBSTRING "${LK_COMMIT}" 0 12 _short_sha) - set(_extracted_root "${LK_SDK_DIR}/livekit-sdk-${LK_TRIPLE}-commit-${_short_sha}") - set(_archive_path "${LK_DOWNLOAD_DIR}/livekit-sdk-${LK_TRIPLE}-commit-${_short_sha}.zip") - - file(MAKE_DIRECTORY "${LK_DOWNLOAD_DIR}") - file(MAKE_DIRECTORY "${LK_SDK_DIR}") - - if(NOT EXISTS "${_extracted_root}/lib/cmake/LiveKit/LiveKitConfig.cmake") - if(LK_NO_DOWNLOAD) - message(FATAL_ERROR - "LiveKitSDK: SDK not found at:\n ${_extracted_root}\n" - "and NO_DOWNLOAD was set.") - endif() - - _lk_resolve_commit_artifact(_artifact_id _full_sha - "${LK_REPO}" "${LK_COMMIT}" "${LK_TRIPLE}" - "${LK_DOWNLOAD_DIR}" "${LK_GITHUB_TOKEN}") - message(STATUS "LiveKitSDK: pinning to commit ${_full_sha}") - message(STATUS "LiveKitSDK: artifact id = ${_artifact_id}") - - _lk_github_headers(_headers "${LK_GITHUB_TOKEN}") - set(_artifact_url - "https://api.github.com/repos/${LK_REPO}/actions/artifacts/${_artifact_id}/zip") - set(_dl_args SHOW_PROGRESS TLS_VERIFY ON STATUS _st LOG _log) - foreach(_h IN LISTS _headers) - list(APPEND _dl_args HTTPHEADER "${_h}") - endforeach() - message(STATUS "LiveKitSDK: downloading ${_artifact_url}") - file(DOWNLOAD "${_artifact_url}" "${_archive_path}" ${_dl_args}) - list(GET _st 0 _code) - list(GET _st 1 _msg) - if(NOT _code EQUAL 0) - message(STATUS "LiveKitSDK: artifact download log:\n${_log}") - message(FATAL_ERROR - "LiveKitSDK: failed to download artifact ${_artifact_id}\n" - "URL: ${_artifact_url}\nStatus: ${_code}\nMessage: ${_msg}") - endif() - - file(REMOVE_RECURSE "${_extracted_root}") - file(MAKE_DIRECTORY "${_extracted_root}") - message(STATUS "LiveKitSDK: extracting ${_archive_path}") - file(ARCHIVE_EXTRACT - INPUT "${_archive_path}" - DESTINATION "${_extracted_root}") - - _lk_write_cmake_config("${_extracted_root}") - endif() - - if(NOT EXISTS "${_extracted_root}/include/livekit/livekit.h") - message(FATAL_ERROR - "LiveKitSDK: extracted artifact looks invalid (missing include/livekit/livekit.h)\n" - "Path: ${_extracted_root}") - endif() - - 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) - - set(LIVEKIT_SDK_EXTRACTED_ROOT "${_extracted_root}" CACHE PATH "LiveKit SDK extracted root" FORCE) - set(LIVEKIT_SDK_URL_USED "${_artifact_url}" CACHE STRING "LiveKit SDK URL used" FORCE) - set(LIVEKIT_SDK_VERSION_RESOLVED "commit-${_short_sha}" CACHE STRING "LiveKit SDK resolved version" FORCE) - set(LIVEKIT_SDK_TRIPLE_USED "${LK_TRIPLE}" CACHE STRING "LiveKit SDK triple used" FORCE) - set(LIVEKIT_SDK_COMMIT_RESOLVED "${LK_COMMIT}" CACHE STRING "LiveKit SDK commit resolved" FORCE) - - message(STATUS "LiveKitSDK: using SDK at ${_extracted_root}") - return() - endif() - # Resolve latest tag if requested set(_resolved_version "${LK_VERSION}") if(LK_VERSION STREQUAL "latest")