引言
做实时音视频项目绕不开 WebRTC。但官方基于 GN 和 Ninja 的构建流程对习惯 CMake 的开发者来说门槛较高,依赖复杂且编译时间长,尤其是多平台交叉编译更是噩梦。经过多次踩坑,我总结了一套利用 CMake 整合 WebRTC 的方案,将编译时间大幅缩短。

为什么选择 CMake
WebRTC 官方使用 GN + Ninja。这系统高效但有痛点:GN 语法门槛高,依赖管理需 depot_tools,定制化困难,且跨平台一致性维护成本高。
CMake 是 C++ 标准工具,生态成熟。核心思路是利用 CMake 的 ExternalProject 模块,在配置阶段调用 GN 生成 Ninja 文件,再由 CMake 驱动编译。既保留 GN 对项目结构的精确描述,又留在熟悉的 CMake 工作流中。
环境准备与结构
需要 C++ 编译器(VS2019+/Clang)、Python、Git、depot_tools 及 CMake 3.16+。 目录规划建议:
your_project/
├── CMakeLists.txt
├── webrtc.cmake
├── deps/
│ └── webrtc/
└── src/
构建配置详解
核心逻辑封装在 webrtc.cmake 中。
定义外部项目
使用 ExternalProject_Add 管理下载、配置和编译。
include(ExternalProject)
set(WEBRTC_COMMIT "branch-heads/stable-branch")
ExternalProject_Add(webrtc
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/third_party/webrtc"
GIT_REPOSITORY "https://webrtc.googlesource.com/src.git"
GIT_TAG ${WEBRTC_COMMIT}
UPDATE_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_IN_SOURCE 1
INSTALL_COMMAND ""
BUILD_COMMAND
"${CMAKE_COMMAND}" -E env PATH="${DEPOT_TOOLS_PATH}:$ENV{PATH}" python3 src/tools/webrtc_deps/fetch_webrtc_deps.py
&& "${CMAKE_COMMAND}" -E env PATH="${DEPOT_TOOLS_PATH}:$ENV{PATH}" gn gen out/Release --args="is_debug=false target_cpu=\"${WEBRTC_TARGET_CPU}\" use_custom_libcxx=false"
&& ninja -C out/Release -j ${NPROC}
BUILD_ALWAYS FALSE
)
注意 GIT_TAG 锁定版本,PATH 必须包含 depot_tools。gn gen 参数控制调试模式和 CPU 架构。ninja -j 开启并行加速。
导入编译产物
编译后需将头文件和库文件'安装'到主项目。
ExternalProject_Get_Property(webrtc source_dir binary_dir)
set(WEBRTC_INCLUDE_DIR "${source_dir}")
set(WEBRTC_LIB_DIR "${binary_dir}/out/Release/obj")
add_custom_target(webrtc_install DEPENDS webrtc
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/webrtc_install/include
COMMAND ${CMAKE_COMMAND} -E copy_directory ${WEBRTC_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/webrtc_install/include
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/webrtc_install/lib
COMMAND ${CMAKE_COMMAND} -E copy ${WEBRTC_LIB_DIR}/libwebrtc.a ${CMAKE_CURRENT_BINARY_DIR}/webrtc_install/lib/
)
add_subdirectory(deps)
add_dependencies(my_app webrtc_install)
target_include_directories(my_app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/webrtc_install/include)
target_link_directories(my_app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/webrtc_install/lib)
target_link_libraries(my_app PRIVATE webrtc)


