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

TEN Framework 仓库内 googletest 的构建与集成指南:从编译命令到 GN/CMake 接入

发布时间:2026/9/28 3:00:41

资讯中心
01
ARTICLE

TEN Framework 仓库内 googletest 的构建与集成指南:从编译命令到 GN/CMake 接入

TEN Framework 仓库内 googletest 的构建与集成指南:从编译命令到 GN/CMake 接入
人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载Google Testgoogletest是 TEN Framework 在 third_party/googletest 目录下随仓库携带的 C 单元测试框架也是 tests/ten_runtime/smoke 等测试套件的底层依赖。本文以该目录中的 README 构建说明为主体完整梳理 googletest 的通用编译流程、CMake 集成方式、旧版构建脚本、配置宏GTEST_*体系并结合本仓库的 GN 构建脚本BUILD.gn / BUILD_release.gn与测试代码的引用关系说明如何在 TEN Framework 内把 googletest 正确编译、打包和链接进测试程序。读完本文你将掌握 googletest 从零编译、以静态库/共享库方式接入、以及在本仓库 GN 工程中复用的完整路径。1. googletest 在 TEN Framework 中的角色在 TEN Framework 中googletest 不是业务运行时代码而是测试基础设施。其 manifest.json 声明type: system属于 system 类型的系统包name: googletest、version: 1.7.0-rc2dependencies: []无额外依赖。从源码布局看仓库内的 googletest 保留了完整的构建所需内容头文件位于 third_party/googletest/include/gtest/其中gtest.h是唯一需要#include的对外入口其余如gtest-death-test.h、gtest-param-test.h、gtest-typed-test.h、gtest-printers.h等按特性拆分实现源码位于 third_party/googletest/src/核心是聚合编译单元gtest-all.cc与可选的gtest_main.cc自带main()入口同时还提供make/、msvc/、xcode/等历史构建脚本以及 CMakeLists.txt 跨平台构建脚本。测试侧的直接证据在 tests/ten_runtime/smoke/BUILD.gnten_runtime_smoke_tests的public_deps同时引用//third_party/googlemock与//third_party/googletest最终测试可执行文件ten_runtime_smoke_test的public_deps再次声明这两个依赖。也就是说整个 smoke 测试集audio_frame_test、command、graph、timer、value 等数十个子目录都建立在 googletest 之上。2. 通用构建流程Generic Build InstructionsREADME 给出的最通用做法是让构建系统知道 googletest 的头文件与源文件位置然后直接编译src/gtest-all.cc。2.1 编译与归档Linux gcc 示例假设 googletest 位于${GTEST_DIR}在 Linux 类系统上用 gcc 编译静态库g -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ -pthread -c ${GTEST_DIR}/src/gtest-all.cc ar -rv libgtest.a gtest-all.o要点说明-isystem ${GTEST_DIR}/include把 googletest 头目录作为系统头文件目录避免编译用户代码时对 gtest 头产生告警噪声-I${GTEST_DIR}普通头文件搜索路径用于解析内部相对引用-pthread必需因为 googletest 内部使用了线程详见第 8 节多线程测试。2.2 编译用户测试并链接g -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \ -o your_test这里可以链接libgtest.a如果你不想自己写main()则链接带main()的gtest_main对应源文件为src/gtest_main.cc。2.3 使用 make/ 目录的 Makefile仓库 make/Makefile 提供了可直接参考的完整样例其关键变量GTEST_DIR .. # googletest 根目录移动文件时需调整 USER_DIR ../samples # 用户代码目录 CPPFLAGS -isystem $(GTEST_DIR)/include CXXFLAGS -g -Wall -Wextra -pthread TESTS sample1_unittest # 新增测试需加入此列表该 Makefile 把src/gtest-all.cc编译为gtest-all.o、src/gtest_main.cc编译为gtest_main.o再用ar归档出gtest.a与gtest_main.asample1_unittest链接gtest_main.a即可运行因为它没有自定义main()。README 说明在默认设置匹配环境的前提下cd ${GTEST_DIR}/make make ./sample1_unittest应当直接成功若失败按make/Makefile内的注释调整变量即可。注意该 Makefile 只构建 gtest 库与一个示例测试不构建 googletest 自身的测试。3. 使用 CMake 构建 googletest仓库自带的 CMakeLists.txt 支持跨平台构建“C”即 cross-platform。CMake 通过生成平台原生的 makefile 或工程文件来工作googletest 既可以作为独立工程构建也可以并入其他已有 CMake 工程。3.1 独立工程构建mkdir mybuild # 创建构建输出目录 cd mybuild cmake ${GTEST_DIR} # 生成原生构建脚本如需同时构建 googletest 自带的 samplescmake -Dgtest_build_samplesON ${GTEST_DIR}在 *nix 上会生成 Makefile执行make即可得到 gtest 库Windows Visual Studio 下会生成gtest.sln与若干.vcproj工程macOS Xcode 下会生成.xcodeproj工程。3.2 并入已有 CMake 工程当项目本身已使用 CMake 时更稳健的做法是通过add_subdirectory()把 googletest 直接编入主工程。其最大优势是 gtest 与主工程使用同一套编译器与链接器设置避免 debug/release 运行库不匹配等链接问题Windows 上尤其重要。源码可用多种方式提供给主构建README 列出了四种手动下载到固定位置——最不灵活不利于 CI直接拷贝到主工程源码树——最简单但最难保持同步作为 git submodule 等引入——有自己的利弊在 CMake 配置阶段自动下载——复杂度略高但无前述限制。其中第 4 种的标准实现是用一个独立文件CMakeLists.txt.in借助ExternalProject_Add()下载源码然后在配置阶段作为子构建执行最后用add_subdirectory()拉入主工程。README 给出的完整示例新建CMakeLists.txt.incmake_minimum_required(VERSION 2.8.2) project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG master SOURCE_DIR ${CMAKE_BINARY_DIR}/googletest-src BINARY_DIR ${CMAKE_BINARY_DIR}/googletest-build CONFIGURE_COMMAND BUILD_COMMAND INSTALL_COMMAND TEST_COMMAND )在主工程的CMakeLists.txt中# 配置阶段下载并解包 googletest configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt) execute_process(COMMAND ${CMAKE_COMMAND} -G ${CMAKE_GENERATOR} . RESULT_VARIABLE result WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download ) if(result) message(FATAL_ERROR CMake step for googletest failed: ${result}) endif() execute_process(COMMAND ${CMAKE_COMMAND} --build . RESULT_VARIABLE result WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download ) if(result) message(FATAL_ERROR Build step for googletest failed: ${result}) endif() # 防止覆盖父工程的编译器/链接器设置Windows 上尤其重要 set(gtest_force_shared_crt ON CACHE BOOL FORCE) # 把 googletest 直接加入本构建定义 gtest 与 gtest_main 两个 target add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src ${CMAKE_BINARY_DIR}/googletest-build EXCLUDE_FROM_ALL) # CMake 2.8.11 时 gtest/gtest_main target 会自动携带头文件搜索路径 # 更老版本则需要手动添加 if (CMAKE_VERSION VERSION_LESS 2.8.11) include_directories(${gtest_SOURCE_DIR}/include) endif() # 链接示例 add_executable(example example.cpp) target_link_libraries(example gtest_main) add_test(NAME example_test COMMAND example)该方式要求 CMake 2.8.2 及以上因为使用了ExternalProject_Add()。3.3 CMake 提供的构建选项对照仓库 CMakeLists.txt 顶部可用的option()包括选项默认作用BUILD_SHARED_LIBSOFF是否构建共享库DLLgtest_force_shared_crtOFF即使 gtest 以静态库构建也强制使用共享DLL运行库gtest_build_testsOFF是否构建 gtest 自身的全部测试gtest_build_samplesOFF是否构建 gtest 的示例程序sample1~sample10gtest_disable_pthreadsOFF是否禁用 gtest 对 pthread 的使用gtest_hide_internal_symbolsOFF构建共享库时是否隐藏内部符号INSTALL_GTEST—是否生成安装规则库、头文件与 pkgconfig 文件该文件还定义了gtest编译src/gtest-all.cc与gtest_main编译src/gtest_main.cc并链接gtest两个库目标且从 CMake 2.8.11 起通过target_include_directories(... SYSTEM INTERFACE ${gtest_SOURCE_DIR}/include)让依赖方自动获得头文件搜索路径。此外MSVC 2012MSVC_VERSION1700需要额外定义/D _VARIADIC_MAX10才能正确使用std::tr1::tuple。3.4 Visual Studio 动态/静态运行库不匹配默认情况下新建的 Visual Studio 工程动态链接 C 运行库而 googletest 静态链接运行库会产生类似如下 LNK2038 错误gtest.lib(gtest-all.obj) : error LNK2038: mismatch detected for RuntimeLibrary: value MTd_StaticDebug doesnt match value MDd_DynamicDebug in main.obj解决办法就是启用 CMake 选项gtest_force_shared_crt它会令 gtest 也动态链接运行库与所在工程保持一致。4. 旧版构建脚本Legacy Build Scripts在转向 CMake 之前googletest 长期提供手写维护的 Visual Studio、Xcode 与 Autotools 工程/脚本。README 明确说明这些脚本仅为便利而保留已不再积极维护强烈建议按前文方式集成。若仍要使用MSVC打开 msvc/ 下的gtest.sln或gtest-md.sln。文件名带-md的工程使用 DLL 版微软运行库/MD或/MDd不带后缀的用静态运行库/MT或/MTdgtest 与测试代码必须使用相同选项。Visual Studio 2005 建议用-md版本因为/MD是新工程的默认值。Xcode打开 xcode/ 下的gtest.xcodeproj构建gtesttarget或命令行执行xcodebuild构建 Release 配置的gtest.framework。Xcode 4.x 以上需在xcode/Config/General.xconfig中注释SDKROOT、MACOS_DEPLOYMENT_TARGET、GCC_VERSION代价是无法再针对更早的 macOS 版本或安装旧版 SDK。5. 通过编译宏定制 googletestTweakinggoogletest 面向多样化环境默认配置在某些环境下可能不适用。它提供了一系列形如GTEST_XYZ的编译期宏在命令行定义成 1 或 0 即可开启/关闭对应特性。这些宏的权威定义与注释集中在 include/gtest/internal/gtest-port.h。下面按原文档顺序逐项展开。6. 选择 TR1 Tuple 库部分 googletest 特性依赖 C TR1 的 tuple 库而旧编译器未必提供。googletest 自带一份“够用”的 TR1 tuple 子集实现仓库内对应 include/gtest/internal/gtest-tuple.h其生成模板为 gtest-tuple.h.pump在编译器不提供 TR1 tuple 时自动启用通常无需关心。但若你的项目本身已使用 TR1 tuple则必须让 googletest 与项目使用同一个 tuple 实现否则两套 tuple 会冲突。对应做法强制使用外部 TR1 tuple-DGTEST_USE_OWN_TR1_TUPLE0强制使用 googletest 自带 tuple-DGTEST_USE_OWN_TR1_TUPLE1完全禁用 tuple所有依赖 tuple 的特性一并关闭-DGTEST_HAS_TR1_TUPLE0从 gtest-port.h 第 83–102 行的注释可以印证GTEST_HAS_TR1_TUPLE用于指示是否存在tr1::tupleGTEST_USE_OWN_TR1_TUPLE用于指示是否使用 googletest 自带实现且两者有联动关系——当编译器不提供 TR1 时默认GTEST_HAS_TR1_TUPLE置 0见第 651–659 行的#ifndef GTEST_HAS_TR1_TUPLE逻辑。7. 多线程测试支持在 pthread 可用的平台上googletest 是线程安全的。#include gtest/gtest.h之后可用宏GTEST_IS_THREADSAFE检测宏被#defined为 1 表示线程安全未定义则否。若 googletest 对 pthread 的探测不准确可强制指定-DGTEST_HAS_PTHREAD1 -DGTEST_HAS_PTHREAD0在 gtest-port.h 第 619–630 行可以看到默认探测逻辑未定义时按平台自动推断且当GTEST_HAS_PTHREAD为真时会保证#include pthread.h。当启用 pthread 时编译器/链接器可能需要额外指定 pthread 库否则会出现链接错误。CMake 脚本和已废弃的Autotools 脚本会自动处理该问题自定义构建脚本则需自行查阅编译器/链接器手册。8. 作为共享库DLL构建googletest 体积紧凑多数用户以静态库方式构建链接即可。若希望以共享库Windows 上即 DLL方式使用编译 gtest 库本身时加入-DGTEST_CREATE_SHARED_LIBRARY1编译使用该共享库的测试时加入-DGTEST_LINKED_AS_SHARED_LIBRARY1注意虽然当前某些编译器如 GCC下不加这些标志也可能工作但未来若 googletest 优化共享库加载速度这些标志可能变为必需。因此 README 建议只要以共享库方式使用就始终加上上述标志否则未来版本可能破坏既有构建脚本。仓库 CMakeLists.txt 中cxx_shared_library(gtest_dll ...)以及gtest_dll_test_目标上的COMPILE_DEFINITIONS GTEST_LINKED_AS_SHARED_LIBRARY1正是这一用法的自测印证。9. 避免宏名冲突C 中宏不遵循命名空间两个库若定义了同名宏同时#include就会冲突。当 googletest 的宏与其他库冲突时可强制 googletest 改名规避。若双方都定义了宏FOO可加入-DGTEST_DONT_DEFINE_FOO1让 googletest 把FOO更名为GTEST_FOO。目前FOO可取FAIL、SUCCEED、TEST三者。例如加了-DGTEST_DONT_DEFINE_TEST1后定义测试需写作GTEST_TEST(SomeTest, DoesThis) { ... }而不是TEST(SomeTest, DoesThis) { ... }10. 在 TEN Framework 的 GN 构建系统中复用 googletestTEN Framework 主构建采用 GNBUILD.gn与 README 的 CMake/make 路线不同但思路一致把src/gtest-all.cc作为库源码编译并把头文件路径暴露给使用者。10.1 头文件与库目标config(gtest_header) { include_dirs [ ., include, ../googlemock, ../googlemock/include, ] } source_set(googletest) { public_configs [ :gtest_header ] sources [ src/gtest-all.cc ] } source_set(gtest_main) { public_configs [ :gtest_header ] sources [ src/gtest_main.cc ] }可见 GN 侧的googletestsource_set 只编译src/gtest-all.ccgtest_main只编译src/gtest_main.cc且gtest_headerconfig 额外包含../googlemock目录与//third_party/googlemock配套使用smoke 测试的public_deps正是同时引用两者。10.2 打包为 system 包ten_package(gtest_system_package) { package_kind system package_output_root_dir_name googletest ... }该 target 把include/**与src/**全部打进 system 包。BUILD.gn 中的注释说明了设计动机googletest 全部由 C 编写预编译成库会带来 C ABI 不兼容风险尤其当构建 gtest 的编译器与用户编译器不一致时因此system 包携带源码而非预编译库由使用方自行编译。打包后还可通过ten_package_publish(upload_gtest_to_server)上传最终由googletest_system_packagegroup 聚合。10.3 发布版配置发布用的 BUILD_release.gn 精简为config(gtest_header)只包含.与include不依赖 googlemock两个source_setgoogletest与gtest_main若干公共配置googletest_common_config指向//ten_packages/system/googletest/include、config_for_app、config_for_ten_packages以及面向独立 ten 包的config_for_standalone_ten_packages//.ten/app/ten_packages/system/googletest。10.4 测试工程中的引用方式在 tests/ten_runtime/smoke/BUILD.gn 中ten_runtime_smoke_tests的public_deps声明//third_party/googletestten_executable(ten_runtime_smoke_test)的public_deps同样包含//third_party/googletest与//third_party/googlemock。由此可以推断仓库内 googletest 的标准接入姿势在BUILD.gn中deps加入//third_party/googletest需要自带main()时额外链接gtest_main目标通过gtest_headerconfig 自动获得头文件搜索路径测试源码只需#include gtest/gtest.h。11. 小结与快速参考使用场景推荐方式独立编译静态库Linux/gccg -isystem ... -pthread -c src/gtest-all.ccar -rv libgtest.a快速验证GNU makecd third_party/googletest/make make ./sample1_unittest跨平台构建cmake ${GTEST_DIR}可用gtest_build_samples/gtest_build_tests等选项并入现有 CMake 工程add_subdirectory()Windows 上加gtest_force_shared_crtON与主工程运行库保持一致启用gtest_force_shared_crt共享库方式库侧-DGTEST_CREATE_SHARED_LIBRARY1测试侧-DGTEST_LINKED_AS_SHARED_LIBRARY1规避宏冲突-DGTEST_DONT_DEFINE_FOO1FOO 可为 FAIL/SUCCEED/TESTTEN Framework GN 工程deps引用//third_party/googletest可选gtest_main依赖 BUILD.gn 提供的头文件 config本文所有命令与参数均以仓库内实际文件为准通用构建指令见 README.mdMakefile 示例见 make/MakefileCMake 选项与库目标见 CMakeLists.txt宏定义与默认探测逻辑见 include/gtest/internal/gtest-port.hGN 接入方式见 BUILD.gn 与 BUILD_release.gn仓库内的实际使用范例见 tests/ten_runtime/smoke/BUILD.gn。赞分享人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载相关推荐MNN 仓库内 FlatBuffers 构建指南从 flatc 编译器到 CMake 集成实战MNN 仓库内 FlatBuffers 构建指南从 flatc 编译器到 CMake 集成实战 FlatBuffers 是 MNN 模型文件 .mnn 的人工智能大模型推理引擎深度学习本地部署模型量化模型优化多模态计算机视觉嵌入式GoogleTest 构建与编译配置完全指南从 CMake 集成到编译宏级定制GoogleTest 构建与编译配置完全指南从 CMake 集成到编译宏级定制 本篇指南以仓库内 googletest/README.md https://l测试质量保障开发工具Geyser资源包转换指南让Java版材质在基岩版上快速生效Geyser资源包转换指南让Java版材质在基岩版上快速生效 Java服装好了自定义材质基岩版玩家连进来却全是原版贴图Geyser是连接基岩版与Java版网络游戏开发上一篇Spring生态权威博客推荐Baeldung到官方指南全解析下一篇终极Java字节码分析神器Bytecode Viewer完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

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

03
WHY YAOTU

想打造同款高转化官网?

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

◈

场景化定制

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

◐

营销型架构

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

▲

全周期服务

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

免费获取你的建站方案

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