尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

GoogleTest 构建与集成实战指南:以 SRS 的 gtest-fit 内嵌源码为例

发布时间:2026/9/10 11:00:43

资讯中心
01
ARTICLE

GoogleTest 构建与集成实战指南:以 SRS 的 gtest-fit 内嵌源码为例

GoogleTest 构建与集成实战指南:以 SRS 的 gtest-fit 内嵌源码为例
GoogleTest 构建与集成实战指南以 SRS 的 gtest-fit 内嵌源码为例【免费下载链接】srsSRS is a simple, high-performance, AI-driven real-time media server supporting RTMP, WebRTC, HLS, HTTP-FLV, HTTP-TS, SRT, MPEG-DASH, and GB28181, with codec support for H.264, H.265, AV1, VP9, AAC, Opus, and G.711.项目地址: https://gitcode.com/GitHub_Trending/sr/srs本篇技术指南围绕 GoogleTestgtest的官方构建说明展开讲解如何在独立工程、已有 CMake 工程中编译与接入 GoogleTest并深入剖析其可裁剪的编译宏体系pthread 线程安全、共享库、宏命名冲突等。文章同时以 SRS 仓库中内嵌的 gtest-fit 第三方源码trunk/3rdparty/gtest-fit为真实落地样本展示一个大型 C 媒体服务器如何把 GoogleTest 装进自己的 3rdparty 目录、通过自研 configure Makefile 生成流程驱动srs_utest单元测试二进制。读完本文你将掌握 GoogleTest 从下载编译到嵌入现有构建系统再到按需裁剪宏的完整方法论并能在 SRS 仓库中直接复现这一套测试构建链路。一、GoogleTest 构建的基本前提GoogleTest 是一个跨平台的 C 单元测试框架其源码同时包含 GoogleTest 本体与 GoogleMock 模拟库。官方构建说明即 trunk/3rdparty/gtest-fit/googletest/README.md首先强调无论使用哪种构建系统核心工作都是告诉构建系统头文件在哪、源文件在哪剩下的工作通常顺理成章。在本仓库中GoogleTest 以内嵌源码的方式直接放在第三方目录下trunk/3rdparty/gtest-fit/CMakeLists.txtgtest-fit 的顶层 CMake 工程声明GOOGLETEST_VERSION 1.11.0默认BUILD_GMOCKONgooglemock 子目录会连带构建 googletest并可通过INSTALL_GTEST开关控制是否安装trunk/3rdparty/gtest-fit/googletest/CMakeLists.txtGoogleTest 本体的 CMake 脚本定义gtest、gtest_main两个库目标以及一系列裁剪选项trunk/3rdparty/gtest-fit/googletest/include/gtest对外头文件目录核心为gtest.h另有gtest-death-test.h、gtest-param-test.h、gtest-typed-test.h、gtest-matchers.h等分功能头文件trunk/3rdparty/gtest-fit/googletest/src实现源码编译入口是gtest-all.cc一次性包含全部实现gtest_main.cc提供默认的main()入口。由于 SRS 采用内嵌拷贝方式本仓库中的 gtest 版本以顶层 CMake 声明的1.11.0为准。二、独立 CMake 工程构建 GoogleTest官方 README 给出了从零构建的标准流程以 *nix 为例git clone googletest 仓库 -b release-1.10.0 cd googletest # 克隆仓库的主目录 mkdir build # 创建存放构建输出的目录 cd build cmake .. # 为 GoogleTest 生成原生构建脚本上述命令默认同时包含 GoogleMock。如果只想构建 GoogleTest 本体把最后一条命令替换为cmake .. -DBUILD_GMOCKOFF在 *nix 系统上此时当前目录下会生成一个 Makefile直接执行make sudo make install # 默认安装到 /usr/local即可完成库的编译与系统级安装。在不同平台上cmake ..生成的工程形态各不相同Windows Visual Studio会生成gtest.sln与若干.vcproj工程文件可用 Visual Studio 直接构建macOS Xcode会生成.xcodeproj工程文件*Linux / 其他nix生成 Makefile。这与 gtest 顶层 CMake 中option(BUILD_GMOCK ...)的默认值ON一致——想要仅 gtest必须显式传入-DBUILD_GMOCKOFF。SRS 内嵌的 gtest-fit 中该选项逻辑见 trunk/3rdparty/gtest-fit/CMakeLists.txtoption(BUILD_GMOCK Builds the googlemock subproject ON) option(INSTALL_GTEST Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.) ON) if(BUILD_GMOCK) add_subdirectory( googlemock ) else() add_subdirectory( googletest ) endif()注意对内嵌第三方源码的项目而言INSTALL_GTEST通常应设为OFF避免把第三方库安装进系统目录污染环境。三、把 GoogleTest 并入已有 CMake 工程对于已经使用 CMake 的项目官方文档给出两种路径。3.1 基于安装产物find_package先通过系统安装或包管理获得库与头文件然后在工程中导入find_package(GTest CONFIG REQUIRED) target_link_libraries(你的目标 GTest::gtest GTest::gmock)find_package(GTest CONFIG REQUIRED)成功后可以直接使用GTest::gtest、GTest::gmock这两个导入目标。3.2 源码级集成add_subdirectory 与 FetchContent更稳健、更灵活的做法是把 GoogleTest 作为主工程的一部分直接构建。这样GoogleTest 与项目其余部分使用同一套编译器和链接器设置可避免因库不兼容如 debug/release 混用引发的问题在 Windows 上尤其有价值。官方文档列出了几种让源码可用的方式手动下载源码放到固定位置——最不灵活不利于接入持续集成系统把 GoogleTest 源码直接拷贝进主工程源码树——往往最简单但难以跟随上游更新部分组织不允许这样做以 git submodule 等方式引入——submodule 本身有一系列优缺点未必总是可行用 CMake 在 configure 阶段自动下载——规避上述所有限制。其中configure 阶段下载的方式通过一小段 CMake 代码实现官方文档给出的示例include(FetchContent) FetchContent_Declare( googletest # 指定你依赖的 commit并定期更新 URL googletest 源码压缩包地址 ) # Windows防止覆盖父工程的编译器/链接器设置 set(gtest_force_shared_crt ON CACHE BOOL FORCE) FetchContent_MakeAvailable(googletest) # 然后按需链接 gtest 或 gtest_main例如 add_executable(example example.cpp) target_link_libraries(example gtest_main) add_test(NAME example_test COMMAND example)注意该方式依赖FetchContent_MakeAvailable()要求 CMake 3.14 及以上版本。而 SRS 内嵌的 googletest 本体 CMake 脚本要求cmake_minimum_required(VERSION 3.10)见 trunk/3rdparty/gtest-fit/googletest/CMakeLists.txt两者并不冲突gtest 自身的下限是 3.10而使用 FetchContent 集成方式时父工程需要 3.14。SRS 的落地方式属于 3.2 中的直接拷贝进源码树在 trunk/3rdparty/gtest-fit 下完整保留 googletest 与 googlemock 两棵源码由 SRS 自己的构建系统见下文第五节负责编译无需联网下载天然适合离线构建与 CI 环境。3.3 Visual Studio 动态库与静态库运行时不一致LNK2038默认情况下新建的 Visual Studio 工程会把 C 运行库动态链接而 GoogleTest 是静态链接运行库的两者混用会产生类似下面的链接错误gtest.lib(gtest-all.obj) : error LNK2038: mismatch detected for RuntimeLibrary: value MTd_StaticDebug doesnt match value MDd_DynamicDebug in main.objGoogleTest 为此内置了 CMake 选项gtest_force_shared_crt开启后 gtest 也改为动态链接运行库与所在工程保持一致。该选项在 SRS 内嵌的 trunk/3rdparty/gtest-fit/googletest/CMakeLists.txt 中默认值为OFF。在上一节 FetchContent 示例中set(gtest_force_shared_crt ON ...)正是为规避该问题而设置。四、C 标准版本要求构建 GoogleTest 需要支持 C11 的环境。有两种方式保证这一点在顶层工程中显式指定标准例如set(CMAKE_CXX_STANDARD 11)若不可行比如在 C 项目中用 GoogleTest 做校验可以把它加到 cmake 的选项中-DCMAKE_CXX_FLAGS...。SRS 正是通过第二种思路落地的在生成 utest 构建脚本时固定传入-stdc11。见 trunk/auto/utest.sh# Whether enable C11 or higher versions. # For linux, always use C11 for gtest required, see https://github.com/google/googletest SRS_CPP_VERSION-stdc11该变量随后被写入生成的CXXFLAGS确保 gtest 源码与 SRS 的 utest 用例都按 C11 标准编译。五、SRS 真实落地configure utest.sh 驱动 gtest 构建SRS 并没有使用 CMake 来构建 GoogleTest而是用自己的一套configure Makefile 生成流程这是对官方文档Generic Build Instructions告诉构建系统头文件与源码在哪的典型实践。整体链路如下开关控制在 trunk/auto/options.sh 中提供--uteston|off选项默认 off另有--with-utest/--without-utest已标记为 Deprecated 的别名对应变量SRS_UTEST。configure 编排trunk/configure 在SRS_UTESTYES时收集src/utest下全部测试模块文件MODULE_FILES包含srs_utest、大量srs_utest_manual_*、srs_utest_workflow_*、srs_utest_ai*系列并调用 trunk/auto/utest.sh 生成 utest 的 Makefile。Makefile 生成trunk/auto/utest.sh 把 GoogleTest 编译为两个静态库并链接出srs_utest可执行文件GTEST_DIR 3rdparty 下的 googletest 源码目录 CPPFLAGS -I$(GTEST_DIR)/include CXXFLAGS $(SRS_CPP_VERSION) # -stdc11 # 编译 gtest-all.cc 与 gtest_main.cc gtest-all.o : $(GTEST_SRCS_) $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest-all.cc gtest_main.o : $(GTEST_SRCS_) $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(CXXFLAGS) -c $(GTEST_DIR)/src/gtest_main.cc gtest.a : gtest-all.o $(AR) $(ARFLAGS) $ $^ gtest_main.a : gtest-all.o gtest_main.o $(AR) $(ARFLAGS) $ $^ # srs_utest 链接 gtest.a并带上 -lpthread 等链接选项 $(SRS_TRUNK_PREFIX)/$(SRS_OBJS)/$(APP_NAME) : $(SRS_SOURCE_OBJS) $(MODULE_OBJS) gtest.a $(CXX) -o $ $(CPPFLAGS) $(CXXFLAGS) $^ $(DEPS_LIBRARIES_FILES) $(LINK_OPTIONS)可以看到这与官方文档描述的标准做法完全一致gtest-all.cc编译进gtest.agtest_main.cc额外构成gtest_main.a测试目标根据是否自带main()选择链接gtest.a还是gtest_main.aSRS 的srs_utest.cpp自带main逻辑因此链接gtest.a。运行方式./configure --uteston make后执行make utest或直接运行生成的objs/srs_utest即可跑完全部用例参见 trunk/configure 中utest: server目标。SRS 的测试用例全部集中在 trunk/src/utest共 100 余个.cpp/.hpp文件对覆盖配置解析、RTMP/RTCP/SRT/HTTP 协议、RTC 推拉流工作流、Forward、GB28181 等模块。以 trunk/src/utest/srs_utest_ai01.cpp 为例可以看到典型的 gtest 用法VOID TEST(ConfigRtcTest, CheckRtcPliForRtmpDefault) { // ... HELPER_ASSERT_SUCCESS(conf.mock_parse(_MIN_OK_CONF)); EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp(__defaultVhost__)); EXPECT_EQ(6 * SRS_UTIME_SECONDS, conf.get_rtc_pli_for_rtmp(test.com)); // ... }TEST(SuiteName, TestName)宏注册用例EXPECT_EQ做非致命断言配合 SRS 封装的HELPER_ASSERT_SUCCESS等辅助宏测试上下文临时配置文件、日志、全局配置对象等的初始化在 trunk/src/utest/srs_utest.cpp 中完成。这正是把第三方测试框架编译进自己工程并大规模使用的最佳例证。六、按需裁剪GTEST_XYZ 控制宏GoogleTest 需要适应各种环境默认配置在某些环境下可能不适用。官方文档指出可以通过在编译器命令行定义GTEST_XYZ形式的控制宏值为 1 或 0来开关某个特性。这些宏的完整清单定义在 gtest 的内部头文件中即本仓库的 trunk/3rdparty/gtest-fit/googletest/include/gtest/internal/gtest-port.h。SRS 自身就提供了一个真实案例在 macOS 上configure 会额外追加-DGTEST_USE_OWN_TR1_TUPLE1编译宏以解决 TR1 tuple 的兼容问题见 trunk/configure# For utest on mac. # see https://github.com/protocolbuffers/protobuf/issues/51#issuecomment-111044468 if [[ $SRS_OSX YES ]]; then UTEST_EXTRA_DEFINES-DGTEST_USE_OWN_TR1_TUPLE1 fi该宏随后通过UTEST_EXTRA_DEFINES注入CXXFLAGStrunk/auto/utest.sh演示了不改 gtest 源码、仅靠编译宏完成环境适配的官方推荐做法。七、多线程测试与 pthreadGoogleTest 在pthread 库可用时是线程安全的。#include gtest/gtest.h之后可以检查GTEST_IS_THREADSAFE宏若被#define为 1 则线程安全未定义则否。如果 GoogleTest 未能正确探测环境中是否可用 pthread可以强制指定-DGTEST_HAS_PTHREAD1或-DGTEST_HAS_PTHREAD0当 GoogleTest 使用 pthread 时可能需要给编译器和/或链接器额外添加选择 pthread 库的旗标否则会报链接错误。使用 CMake 脚本时该问题已被自动处理使用自研构建脚本时需要查阅自己编译器和链接器的手册自行添加。SRS 的落地同样印证了这一点在 utest 链接选项中显式加入了-lpthreadtrunk/configure 的LINK_OPTIONS${LDFLAGS} -lpthread ${SrsLinkOptions}确保srs_utest与 gtest 的线程支持正确链接。GTEST_HAS_PTHREAD的自动探测逻辑与开关定义位于 gtest-port.h。八、把 gtest 编译为共享库DLLGoogleTest 体积小巧多数用户为简单起见以静态库方式构建链接但也可以选择以共享库Windows 上称 DLL方式使用此时需要两组宏编译gtest 本身为共享库给编译器加-DGTEST_CREATE_SHARED_LIBRARY1编译你的测试程序使用该共享库给编译器加-DGTEST_LINKED_AS_SHARED_LIBRARY1链接器侧还需要告诉链接器产出共享库而不是可执行/静态库具体旗标查阅链接器手册。官方文档特别提醒虽然现阶段对某些编译器如 GCC以上步骤并非严格必需但未来若 GoogleTest 优化共享库加载速度涉及符号可见性这两组宏可能变成必需项。因此只要以共享库方式使用就建议始终加上上述宏否则未来某个 GoogleTest 版本可能破坏你的构建脚本。这两个宏在 gtest-port.h 与GTEST_LINKED_AS_SHARED_LIBRARY约 gtest-port.h处均有声明且 googletest 本体的 CMake 脚本在自测模式下也构建了一个gtest_dll共享库目标见 googletest/CMakeLists.txt可作为参考实现。九、避免宏名冲突GTEST_DONT_DEFINE_*C 中宏不遵守命名空间。因此两个库若都定义了同名宏一旦同时#include两者就会冲突。若 GoogleTest 的宏与其他库冲突可以强制 GoogleTest 重命名自己的宏-DGTEST_DONT_DEFINE_FOO1效果是把宏名从FOO改为GTEST_FOO。目前FOO可取FAIL、SUCCEED、TEST三者。例如加了-DGTEST_DONT_DEFINE_TEST1后定义测试用例需要写GTEST_TEST(SomeTest, DoesThis) { ... }而不是TEST(SomeTest, DoesThis) { ... }十、常见问题速查问题现象原因解决方案error LNK2038: RuntimeLibrary mismatchMTd vs MDdgtest 静态链接运行库而 VS 工程动态链接开启gtest_force_shared_crtON链接错误找不到 pthread 相关符号编译器/链接器未选择 pthread 库追加-lpthread用 CMake 则自动处理环境不支持 C11gtest 要求 C11顶层set(CMAKE_CXX_STANDARD 11)或-DCMAKE_CXX_FLAGS指定测试宏与其他库冲突宏不遵守命名空间-DGTEST_DONT_DEFINE_TEST1等改用GTEST_*前缀宏只想构建 gtest 不想构建 gmock默认BUILD_GMOCKONcmake .. -DBUILD_GMOCKOFF使用 FetchContent 集成报错需要 CMake 3.14 的FetchContent_MakeAvailable()升级 CMake 到 3.14 或更高结语GoogleTest 的构建与集成看似琐碎实则围绕几条清晰的规则展开告诉构建系统源码与头文件在哪、保证 C11 环境、按需用GTEST_*宏裁剪特性。官方 READMEtrunk/3rdparty/gtest-fit/googletest/README.md覆盖了独立构建、CMake 集成、运行时链接策略、线程安全与宏冲突等全部关键点而 SRS 仓库则提供了一个不用 CMake、用自研 configure 脚本驱动 gtest 编译的完整工业级范例——从 trunk/auto/options.sh 的--uteston开关到 trunk/auto/utest.sh 生成的gtest.a/gtest_main.a再到 trunk/src/utest 下 100 余个测试文件的实际用例。无论你是想给个人项目引入 gtest还是想理解 SRS 这样的大型项目如何组织单元测试构建都可以从本文的链路直接上手。【免费下载链接】srsSRS is a simple, high-performance, AI-driven real-time media server supporting RTMP, WebRTC, HLS, HTTP-FLV, HTTP-TS, SRT, MPEG-DASH, and GB28181, with codec support for H.264, H.265, AV1, VP9, AAC, Opus, and G.711.项目地址: https://gitcode.com/GitHub_Trending/sr/srs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。