ci: patch obs-studio's Windows CMake to define OBS::w32-pthreads
Build / macOS (macos-latest) (push) Successful in 32s
Build / Linux (ubuntu-24.04) (push) Successful in 1m2s
Build / Windows (windows-latest) (push) Failing after 11m20s

libobs/cmake/os-windows.cmake unconditionally links OBS::w32-pthreads, but
in the OBS_CMAKE_VERSION>=3.0.0 ("modern") top-level CMakeLists.txt branch
this bootstrap selects, nothing ever adds deps/w32-pthreads (confirmed at
every checked tag, 30.0.2 through 31.1.1) -- only the legacy branch's
add_subdirectory(deps) does, and libobs/CMakeLists.txt itself only adds
deps/libcaption and deps/uthash.

Upstream's own CI never hits this because it leaves ENABLE_UI on, and
UI/cmake/os-windows.cmake happens to add deps/w32-pthreads as a side effect
of building the Qt UI. Building obs-frontend-api instead of libobs (as
upstream's CI does) does not help: UI/obs-frontend-api/CMakeLists.txt only
links OBS::libobs, and UI/CMakeLists.txt returns before reaching the file
that adds w32-pthreads whenever ENABLE_UI is off -- which this bootstrap
deliberately keeps off to avoid a ~100 MB Qt6 download this plugin's plain
obs_properties_* UI does not need.

Add _patch_obs_studio_w32_pthreads() to buildspec_common.cmake: after the
obs-studio archive is extracted and before the OBS sub-configure runs, patch
its libobs/CMakeLists.txt to add deps/w32-pthreads itself, guarded by the
same if(NOT TARGET OBS::w32-pthreads) check UI/cmake/os-windows.cmake already
uses upstream. Idempotent (skips if already patched) and fails loudly if the
expected anchor text is missing, rather than silently no-opping against a
future OBS version with a different libobs/CMakeLists.txt shape.

Verified locally: the CMake string(FIND)/string(REPLACE) patch logic was run
against the real libobs/CMakeLists.txt fetched from the obs-studio 30.0.2
tag, confirmed to produce the intended block, and confirmed idempotent on a
second run. The actual Windows CMake configure/build this unblocks cannot be
verified from this Linux sandbox -- that's what the next CI run is for.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
This commit is contained in:
2026-09-06 23:12:41 -07:00
co-authored by Claude Sonnet 5
parent c5fedd176f
commit 2bbd94775a
2 changed files with 121 additions and 14 deletions
+69
View File
@@ -24,6 +24,7 @@
# build tree, so it does not trip over the install rules of targets that
# were deliberately never built.
# 7. _resolve_versioned_macos_sdk exists at all -- see its own comment.
# 8. _patch_obs_studio_w32_pthreads exists at all -- see its own comment.
#
include_guard(GLOBAL)
@@ -147,6 +148,70 @@ function(_resolve_versioned_macos_sdk out_path)
endif()
endfunction()
# _patch_obs_studio_w32_pthreads: Windows-only. Confirmed at every obs-studio
# tag from 30.0.2 through 31.1.1 (checked directly against
# libobs/cmake/os-windows.cmake and the top-level CMakeLists.txt at each tag):
# libobs/cmake/os-windows.cmake unconditionally links `OBS::w32-pthreads`, but
# that target is defined only by deps/w32-pthreads/CMakeLists.txt, and nothing
# in the OBS_CMAKE_VERSION>=3.0.0 ("modern") top-level CMakeLists.txt branch --
# the one -DOBS_CMAKE_VERSION=3.0.0 selects -- ever adds deps/w32-pthreads.
# libobs/CMakeLists.txt itself only adds deps/libcaption and deps/uthash.
#
# Upstream obs-studio's own CI never hits this because it builds with
# ENABLE_UI left ON: UI/cmake/os-windows.cmake happens to add
# deps/w32-pthreads too (guarded by `if(NOT TARGET OBS::w32-pthreads)`), which
# satisfies libobs's link by the time CMake generates -- purely as a side
# effect of Qt still being in the build, not because anything wires
# w32-pthreads to libobs on purpose. This bootstrap deliberately builds with
# ENABLE_UI:BOOL=OFF (see the file header) specifically to avoid pulling in
# Qt6, so that side effect never happens here, and the gap is exposed.
#
# Rather than re-enable ENABLE_UI (and pay for a ~100 MB Qt6 download this
# plugin's plain obs_properties_* UI does not need) or vendor a full copy of
# deps/CMakeLists.txt, patch libobs/CMakeLists.txt to add the one missing
# subdirectory itself, using the exact same existence guard
# UI/cmake/os-windows.cmake already relies on. Idempotent: running this again
# against an already-patched tree is a no-op (the search text no longer
# matches), so it is safe to call on every configure regardless of whether
# .deps/ was freshly extracted or reused from a previous run.
function(_patch_obs_studio_w32_pthreads)
set(_cmakelists "${dependencies_dir}/${_obs_destination}/libobs/CMakeLists.txt")
if(NOT EXISTS "${_cmakelists}")
message(FATAL_ERROR "Cannot apply the w32-pthreads workaround: ${_cmakelists} does not exist.")
endif()
file(READ "${_cmakelists}" _contents)
string(FIND "${_contents}" "deps/w32-pthreads" _already_patched)
if(NOT _already_patched EQUAL -1)
message(STATUS "libobs/CMakeLists.txt already carries the w32-pthreads workaround - skipping")
return()
endif()
set(_needle "if(OS_WINDOWS)\n include(cmake/os-windows.cmake)")
set(_replacement
"if(OS_WINDOWS)\n if(NOT TARGET OBS::w32-pthreads)\n add_subdirectory(\"\${CMAKE_SOURCE_DIR}/deps/w32-pthreads\" \"\${CMAKE_BINARY_DIR}/deps/w32-pthreads\")\n endif()\n include(cmake/os-windows.cmake)"
)
string(FIND "${_contents}" "${_needle}" _pos)
if(_pos EQUAL -1)
message(
FATAL_ERROR
"Could not find the expected 'if(OS_WINDOWS) / include(cmake/os-windows.cmake)' block in "
"${_cmakelists} to apply the w32-pthreads workaround. obs-studio's libobs/CMakeLists.txt "
"layout may have changed since this was written against 30.0.2."
)
endif()
string(REPLACE "${_needle}" "${_replacement}" _patched "${_contents}")
file(WRITE "${_cmakelists}" "${_patched}")
message(
STATUS
"Patched ${_cmakelists}: added deps/w32-pthreads so OBS::w32-pthreads exists "
"(obs-studio's modern Windows CMake path never defines it with ENABLE_UI=OFF)."
)
endfunction()
# _setup_obs_studio: Create obs-studio build project, then build libobs and obs-frontend-api
function(_setup_obs_studio)
if(NOT libobs_DIR)
@@ -366,5 +431,9 @@ function(_check_dependencies)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} CACHE PATH "CMake prefix search path" FORCE)
if(OS_WINDOWS)
_patch_obs_studio_w32_pthreads()
endif()
_setup_obs_studio()
endfunction()