OBS Windows 编译新流程解析:cmake --preset windows-x64 背后依赖是怎么自动下载的?
现在编译 OBS(Windows)其实已经非常方便了,核心命令基本就是:
bash
cmake --preset windows-x64
官方文档:
和以前手动准备一堆依赖相比,现在 OBS 已经把依赖下载、校验、解压这套流程集成到了 CMake 里。
一、先说结论:cmake --preset windows-x64 到底做了什么?
在 Windows 下执行:
bash
cmake --preset windows-x64
本质上会做三件事:
-
读取
CMakePresets.json里的预设配置 -
根据预设确定当前平台(例如
windows-x64) -
在 CMakeList.txt 会调用
_check_dependencies_windows()→_check_dependencies()自动处理依赖- 从
CMakePresets.json读取依赖元数据 - 生成具体下载文件名
- 拼接完整下载 URL
- 下载到
.deps - 校验 hash
- 解压到对应目录
- 把路径加入后续构建搜索路径
- 从
二、依赖配置从哪里来?
OBS 的依赖配置定义在:
text
CMakePresets.json
里面有一个隐藏的 preset:dependencies
例如:
json
{
"name": "dependencies",
"hidden": true,
"vendor": {
"obsproject.com/obs-studio": {
"dependencies": {
"prebuilt": {
"version": "2025-08-23",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-Built obs-deps",
"hashes": {
"windows-x64": "8de229cff6f1981508c0eb646b35e644633a5855787b9f5d3b90ae2aeb87ffc1",
"windows-x86": "fb3c68b75911f292b3206e346053638db1c73605957207445a0a92b33ab5e00a",
"windows-arm64": "dd87ba00a6cbc153182fb62b3678a3b5021d1d11eb2730442060937a645eb97e"
}
},
"qt6": {
"version": "2025-08-23",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download",
"label": "Pre-Built Qt6"
},
"cef": {
"version": "6533",
"baseUrl": "https://cdn-fastly.obsproject.com/downloads",
"label": "Chromium Embedded Framework"
}
}
}
}
}
这里可以把每个依赖理解成一份"元数据描述":
version:依赖版本baseUrl:下载根地址label:显示名称hashes:不同平台对应的 SHA256revision:某些依赖的额外修订号(可选)
三、Windows 下会下载哪些依赖?
Windows 逻辑在:
cmake
function(_check_dependencies_windows)
set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps")
set(prebuilt_filename "windows-deps-VERSION-ARCH-REVISION.zip")
set(prebuilt_destination "obs-deps-VERSION-ARCH")
set(qt6_filename "windows-deps-qt6-VERSION-ARCH-REVISION.zip")
set(qt6_destination "obs-deps-qt6-VERSION-ARCH")
set(cef_filename "cef_binary_VERSION_windows_ARCH_REVISION.zip")
set(cef_destination "cef_binary_VERSION_windows_ARCH")
if(CMAKE_VS_PLATFORM_NAME STREQUAL Win32)
set(arch x86)
set(dependencies_list prebuilt)
else()
string(TOLOWER "${CMAKE_VS_PLATFORM_NAME}" arch)
set(dependencies_list prebuilt qt6 cef)
endif()
set(platform windows-${arch})
_check_dependencies(${dependencies_list})
if(NOT CMAKE_VS_PLATFORM_NAME STREQUAL Win32)
_handle_qt_cross_compile(${CMAKE_HOST_SYSTEM_PROCESSOR} DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.deps/${qt6_destination}")
endif()
endfunction()
结论
1)如果是 Win32
只下载:
prebuilt
并且:
cmake
set(arch x86)
所以平台是:
text
windows-x86
2)如果是 x64 / ARM64
下载:
prebuiltqt6cef
并且:
cmake
string(TOLOWER "${CMAKE_VS_PLATFORM_NAME}" arch)
例如:
x64→x64ARM64→arm64
最终平台名:
windows-x64windows-arm64
四、最关键的部分:file 是怎么拼接出来的?
OBS 依赖下载最核心的逻辑,其实就是:
先取一个"文件名模板",再把
VERSION / ARCH / REVISION替换成真实值。
代码如下:
cmake
set(file "${${dependency}_filename}")
set(destination "${${dependency}_destination}")
string(REPLACE "VERSION" "${version}" file "${file}")
string(REPLACE "VERSION" "${version}" destination "${destination}")
string(REPLACE "ARCH" "${arch}" file "${file}")
string(REPLACE "ARCH" "${arch}" destination "${destination}")
if(revision)
string(REPLACE "_REVISION" "_v${revision}" file "${file}")
string(REPLACE "-REVISION" "-v${revision}" file "${file}")
else()
string(REPLACE "_REVISION" "" file "${file}")
string(REPLACE "-REVISION" "" file "${file}")
endif()
五、先理解这句:CMake 的"二级变量展开"
最容易让人一开始看懵的是:
cmake
set(file "${${dependency}_filename}")
如果当前:
cmake
set(dependency prebuilt)
那么:
cmake
"${${dependency}_filename}"
会先展开成:
cmake
"${prebuilt_filename}"
而在 _check_dependencies_windows() 里,前面已经定义了:
cmake
set(prebuilt_filename "windows-deps-VERSION-ARCH-REVISION.zip")
所以最终:
cmake
file = windows-deps-VERSION-ARCH-REVISION.zip
同理:
cmake
set(destination "${${dependency}_destination}")
会变成:
cmake
destination = obs-deps-VERSION-ARCH
六、以 prebuilt 为例:完整推导文件名
prebuilt 的模板是:
cmake
set(prebuilt_filename "windows-deps-VERSION-ARCH-REVISION.zip")
set(prebuilt_destination "obs-deps-VERSION-ARCH")
假设当前平台是:
text
windows-x64
那么从 CMakePresets.json 里读到的依赖信息是:
dependency = prebuiltversion = 2025-08-23arch = x64revision = 空(prebuilt通常没有 revision)
第 1 步:取模板
text
file = windows-deps-VERSION-ARCH-REVISION.zip
destination = obs-deps-VERSION-ARCH
第 2 步:替换 VERSION
text
file = windows-deps-2025-08-23-ARCH-REVISION.zip
destination = obs-deps-2025-08-23-ARCH
第 3 步:替换 ARCH
text
file = windows-deps-2025-08-23-x64-REVISION.zip
destination = obs-deps-2025-08-23-x64
第 4 步:处理 REVISION
因为 prebuilt 没有 revision,所以会走:
cmake
string(REPLACE "-REVISION" "" file "${file}")
最终得到:
text
file = windows-deps-2025-08-23-x64.zip
最终结果
- 下载包名:
text
windows-deps-2025-08-23-x64.zip
- 解压目录:
text
obs-deps-2025-08-23-x64
七、完整下载 URL 是怎么拼的?
CMakePresets.json 里 prebuilt 配置:
json
"prebuilt": {
"version": "2025-08-23",
"baseUrl": "https://github.com/obsproject/obs-deps/releases/download"
}
然后通常会拼成:
text
{baseUrl}/{version}/{file}
也就是:
text
https://github.com/obsproject/obs-deps/releases/download/2025-08-23/windows-deps-2025-08-23-x64.zip
所以你日志里看到的下载地址,本质就是:
baseUrl + "/" + version + "/" + 模板替换后的 file