尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

miniblink49 内嵌 V8 的 Google Test(gtest)构建与集成指南:从源码编译到宏级定制

miniblink49 内嵌 V8 的 Google Test(gtest)构建与集成指南:从源码编译到宏级定制 miniblink49 内嵌 V8 的 Google Testgtest构建与集成指南从源码编译到宏级定制【免费下载链接】miniblink49a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核用来取代wke和libcef项目地址: https://gitcode.com/GitHub_Trending/mi/miniblink49导读本文以 miniblink49 仓库中 V8 7.5 所捆绑的 Google Test 构建文档 为主线系统讲解 Google Testgtest的四种构建方式、CMake 与 Makefile 的完整配置、以及GTEST_*系列编译宏的定制原理。读者将掌握如何把 gtest 以静态库或共享库形式接入自己的 C 项目、如何规避 TR1 tuple 与宏命名冲突、如何验证多线程环境下的线程安全以及如何在 Chromium/V8 的 GN 构建体系中复用这份测试框架。文中所有命令与配置均可直接在仓库对应目录中验证。一、仓库中的 gtest 位置与角色在 miniblink49 中Google Test 以第三方测试依赖的形式内嵌于 v8_7_5/testing/gtest/ 目录服务于 V8 7.5 自身的单元测试体系。目录结构完整保留了 gtest 官方布局src/核心实现包括 gtest-all.cc聚合编译入口#include全部 gtest 实现、gtest_main.cc提供现成main()、gtest-death-test.cc死亡测试、gtest-printers.cc值打印等include/gtest/全部公共头文件测试程序只需#include gtest/gtest.hsamples/10 个官方示例sample1_unittest.cc~sample10_unittest.cc演示断言、测试固件、参数化测试、类型参数化测试等make/、msvc/、xcode/、codegear/各平台手写构建脚本CMakeLists.txt跨平台 CMake 构建脚本BUILD.gn供 Chromium 系 GN 构建体系使用的目标定义V8 即运行于此类体系。README 的核心主张是告诉你的构建系统 gtest 的头文件与源文件在哪里剩下的交给编译器和链接器。下文按 README 的脉络逐层展开。二、通用构建指令手写编译 gtest2.1 Setup确定${GTEST_DIR}将 gtest 解压/内嵌到目录${GTEST_DIR}在本仓库即v8_7_5/testing/gtest后需要让构建系统知道两处位置${GTEST_DIR}/include作为系统头文件搜索路径-isystem这样编译器不会对 gtest 头文件内部的警告大呼小叫${GTEST_DIR}作为普通头文件搜索路径-I因为部分内部头文件如src/gtest-internal-inl.h以相对路径被引用。2.2 Build两步编译第一步把 gtest-all.cc 编译成目标文件并打包成静态库g -isystem ${GTEST_DIR}/include -I${GTEST_DIR} \ -pthread -c ${GTEST_DIR}/src/gtest-all.cc ar -rv libgtest.a gtest-all.o注意-pthread是必需的因为 gtest 内部使用线程线程安全断言、死亡测试的超时控制等。第二步编译你的测试源文件并链接g -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \ -o your_test这里的your_test.cc中#include gtest/gtest.h后用TEST()/TEST_F()等宏编写用例并链接gtest_main或自行实现main()后调用RUN_ALL_TESTS()。2.3 快速验证make 目录make/Makefile 是一个可直接运行的完整示例它不构建 gtest 自身测试只产出libgtest.a、libgtest_main.a和一个示例测试。其关键变量GTEST_DIR .. USER_DIR ../samples CPPFLAGS -isystem $(GTEST_DIR)/include CXXFLAGS -g -Wall -Wextra -pthread TESTS sample1_unittest只要环境默认设置正确以下命令应直接成功cd ${GTEST_DIR}/make make ./sample1_unittest从 Makefile 可见编译 gtest 只需src/*.cc与src/*.h加上全部头文件GTEST_SRCS_依赖关系写得“保守但不优化”——因为 gtest 编译极快、普通用户很少改动其源码。若出现错误按make/Makefile中的注释调整GTEST_DIR、USER_DIR等变量即可。三、使用 CMake 构建跨平台首选gtest 自带 CMakeLists.txtC代表 cross-platform可在 WindowsVisual Studio、macOSXcode、LinuxMakefile等环境生成原生构建工程。典型工作流mkdir mybuild # 创建存放构建输出的目录 cd mybuild cmake ${GTEST_DIR} # 生成原生构建脚本如需一并构建官方示例cmake -Dgtest_build_samplesON ${GTEST_DIR}在 *nix 上会生成 Makefile执行make即得libgtest.a在 Windows Visual Studio 下会生成gtest.sln与若干.vcproj可直接用 IDE 构建在 macOS Xcode 下会生成.xcodeproj。3.1 CMake 提供的可配置选项从 CMakeLists.txt 的option()声明中可以整理出完整的开关表CMake 选项默认值作用BUILD_SHARED_LIBSOFF是否构建共享库Windows 上即 DLLgtest_force_shared_crtOFF即使 gtest 以静态库构建也强制使用共享DLL运行时库当宿主项目使用共享 CRT 时必须打开gtest_build_testsOFF是否构建 gtest 自身全部测试gtest_build_samplesOFF是否构建samples/下的示例程序gtest_disable_pthreadsOFF禁用 pthread 使用gtest_hide_internal_symbolsOFF构建共享库时隐藏内部符号等价设置CMAKE_CXX_VISIBILITY_PRESEThiddenCMake 脚本中还内置了 Visual Studio 的 tuple 支持矩阵第 72~80 行注释VS 2010 及更早MSVC ≤ 1600使用 gtest 自带的 tupleVS 2012MSVC 1700使用std::tr1::tuple且需定义_VARIADIC_MAX10脚本已自动添加/D _VARIADIC_MAX10VS 2013 起MSVC ≥ 1800直接使用std::tr1::tuple。目标产物为两个库gtest核心库编译自 src/gtest-all.cc与gtest_main额外包含 src/gtest_main.cc提供main()并链接gtest。用户测试应链接二者之一。四、Legacy 构建脚本不推荐但兼容在转向 CMake 之前gtest 长期维护着 Visual Studio、Xcode 与 Autotools 三套手写工程。README 明确说明它们已不再积极维护强烈建议优先使用前两节的通用构建或 CMake 方式仅当确有需要时才使用。MSVC打开msvc\gtest.sln或msvc\gtest-md.sln。文件名以-md结尾的使用动态 CRT/MD或/MDd不带后缀的使用静态 CRT/MT或/MTd。关键约束编译 gtest 与编译测试代码必须使用相同的 CRT 选项否则链接期会报 CRT 符号冲突VS 2005 及以上建议使用-md版本/MD是新项目的默认选项。Xcode打开xcode/gtest.xcodeproj并构建gtesttarget通用二进制 framework 输出到构建目录命令行下可直接执行xcodebuild该命令在默认构建位置生成Release配置的gtest.framework。若使用 Xcode 4.x 及以上需二选一要么在xcode/Config/General.xconfig中注释掉SDKROOT、MACOS_DEPLOYMENT_TARGET、GCC_VERSION三个选项代价是无法再针对旧版 macOS 构建要么安装旧版 SDK。Autotools仓库根目录保留configure.ac、Makefile.am、m4/等文件对应传统./configure make流程CMake 时代之前的产物。五、Tweaking Google TestGTEST_*控制宏gtest 通过一组形如GTEST_XYZ、取值为1/0的编译期宏实现特性开关在编译器命令行以-D定义即可。完整清单见 include/gtest/internal/gtest-port.h 顶部的注释块第 70~180 行该文件集中处理平台差异、线程、tuple、共享库等可移植性问题。以下为 README 点名的常用宏及源码佐证。5.1 选择 TR1 tuple 库部分 gtest 特性如参数化测试TEST_P依赖 C TR1 的 tuple而早期编译器未必提供。gtest 自带一个“够用”的 TR1 tuple 子集实现编译器缺 tuple 时自动启用见 gtest-port.h 第 634~677 行的条件编译逻辑。若你的项目已使用 TR1 tuple必须让 gtest 与项目使用同一份否则两个 tuple 实现会冲突。编译 gtest 与测试时都加上-DGTEST_USE_OWN_TR1_TUPLE0若想强制 gtest 用自己的 tuple-DGTEST_USE_OWN_TR1_TUPLE1若完全禁用 tuple相应特性随之关闭-DGTEST_HAS_TR1_TUPLE0仓库佐证gtest-tuple.h 与其.pump模板文件位于include/gtest/internal/而 gtest-port.h 中GTEST_HAS_TR1_TUPLE与GTEST_USE_OWN_TR1_TUPLE的默认推导第 634/646 行会依据编译器版本自动决定。5.2 多线程测试与线程安全gtest 在具备 pthread 的环境下是线程安全的。#include gtest/gtest.h后可用GTEST_IS_THREADSAFE宏探测若该宏被#define为 1 则线程安全未定义则否。其定义位于 gtest-port.h 第 926~929 行条件为操作系统支持且GTEST_HAS_PTHREAD为真。如果 gtest 对 pthread 的自动探测有误可强制指定-DGTEST_HAS_PTHREAD1 # 强制启用 pthread -DGTEST_HAS_PTHREAD0 # 强制禁用链接期陷阱启用 pthread 后编译器与链接器可能需要显式加-pthread或-lpthread标志否则出现链接错误。使用 CMake 脚本或旧的 Autotools 脚本时此步已自动处理手写构建脚本则需自行查阅编译器手册。仓库的 make/Makefile 正是在CXXFLAGS中显式写了-pthread来规避该问题。5.3 作为共享库DLL构建gtest 体量小默认建议以静态库链接。若偏好共享库分两侧设置编译gtest 本身为共享库-DGTEST_CREATE_SHARED_LIBRARY1同时需告知链接器产出共享库见各链接器手册。编译使用 gtest 的测试-DGTEST_LINKED_AS_SHARED_LIBRARY1README 特别提醒虽然对部分编译器如 GCC当前不强制但这是为未来优化加载速度符号可见性控制预留的接口建议始终加上这两个宏否则 gtest 未来版本可能破坏你的构建脚本。仓库 CMakeLists.txt 第 201~208 行的gtest_dll目标即为共享库自测示例编译时定义GTEST_LINKED_AS_SHARED_LIBRARY1。5.4 规避宏名冲突C 宏不遵循命名空间两个库若定义了同名宏#include后必然冲突。gtest 允许通过GTEST_DONT_DEFINE_FOO1把宏FOO改名为GTEST_FOO来规避。当前支持改名的宏为FAIL、SUCCEED、TEST-DGTEST_DONT_DEFINE_TEST1此后定义测试需写GTEST_TEST(SomeTest, DoesThis) { ... }而非TEST(SomeTest, DoesThis) { ... }仓库佐证GTEST_DONT_DEFINE_*系列宏的实际处理逻辑分布在 gtest.h 等公共头文件的底部——先#define GTEST_TEST(...)作为内部实现再在#ifndef GTEST_DONT_DEFINE_TEST分支下将TEST别名化从而支持上述改名机制。六、Developing Google Test自测与代码生成6.1 运行 gtest 自身测试修改 gtest 源码后应编译并运行其自带测试验证不破坏既有功能。CMake 方式mkdir mybuild cd mybuild cmake -Dgtest_build_testsON ${GTEST_DIR} make make test注意两点部分 gtest 测试用 Python 编写需预装 Python若 CMake 报Could NOT find PythonInterp (missing: PYTHON_EXECUTABLE)显式指定解释器路径cmake -DPYTHON_EXECUTABLEpath/to/python -Dgtest_build_testsON ${GTEST_DIR}自测体系覆盖极广。以 CMakeLists.txt 第 142~286 行为证gtest_build_testsON时会构建常规 C 测试gtest-death-test_test死亡测试、gtest_environment_test环境变量、gtest-param-test_test参数化测试、gtest-typed-test_test类型参数化、gtest_unittest核心等 20 余个非常规编译旗标测试禁用异常gtest_no_exception、禁用 RTTIgtest_main_no_rtti、开关GTEST_ENABLE_CATCH_EXCEPTIONS_的死亡测试变体、共享库测试gtest_dll等Python 驱动测试gtest_color_test、gtest_filter_unittest、gtest_output_test、gtest_shuffle_test、gtest_xml_output_unittest等 10 余个通过py_test()辅助函数注册。6.2 使用 Pump 重新生成代码gtest 中一批“重复模式”头文件如 gtest-param-util-generated.h、gtest-type-util.h、gtest-tuple.h、gtest-param-test.h由 Pump 模板生成源码维护.pump模板文件运行时执行 scripts/pump.py 输出实际.h。只有当你需要修改这些模板时才需关心再生成流程详细用法参见 Pump 手册。七、在 Chromium/V8 的 GN 体系中使用除 CMake 与手写构建外本仓库还提供 v8_7_5/testing/gtest/BUILD.gn这是 Chromium/V8 在 GN 构建gn gen ninja下复用 gtest 的接入层static_library(gtest)testonly true仅列出公共头文件与empty.cc该空文件是规避 Mac/Windows 上静态库无源文件报错、以及 Android 上complete_static_lib重复符号问题的 workaround实际实现通过public_deps委托给//third_party/googletest:gtest通过public_configs注入UNIT_TEST宏gtest_direct_configsource_set(gtest_main)同样委托//third_party/googletest:gtest_main附带gtest_include_multiprocess、gtest_include_platform_test、gtest_include_objc_support、gtest_include_ios_coverage等条件开关按平台Mac/iOS追加gtest_mac、覆盖率支持等文件。这印证了 README 的论断gtest 与具体构建系统解耦任意构建系统只要找到头文件与源文件即可接入——无论是裸g、make、CMake、Visual Studio、Xcode还是 Chromium 系的 GN。八、FAQ 与排错速查现象原因与对策链接期报 pthread 相关未定义符号使用了线程安全特性但未加-pthread/-lpthreadCMake 与 Autotools 自动处理手写构建需手动补编译 gtest 与测试的 CRT 选项不一致导致链接错误静态/动态 CRT/MT与/MD必须统一VS 场景见本文第四节tuple 相关编译错误或重复定义项目已用 TR1 tuple 时设置-DGTEST_USE_OWN_TR1_TUPLE0保持统一或-DGTEST_HAS_TR1_TUPLE0整体禁用宏TEST/FAIL/SUCCEED与第三方库冲突用-DGTEST_DONT_DEFINE_XXX1改名为GTEST_XXXCMake 找不到 Python-DPYTHON_EXECUTABLEpath/to/python显式指定构建 gtest 自身测试时才需要共享库链接异常编译 gtest 加-DGTEST_CREATE_SHARED_LIBRARY1编译测试加-DGTEST_LINKED_AS_SHARED_LIBRARY1九、小结从 README.md 的构建指南出发本文完整覆盖了 gtest 的三条接入路径手写编译、make、CMake与两条兼容路径MSVC/Xcode/Autotools 旧脚本、GN 的 BUILD.gn并深入 gtest-port.h 与 CMakeLists.txt 源码层验证了 tuple 选择、线程安全、共享库与宏改名等定制机制。对于 miniblink49 这样同时携带 V8 多版本与 Chromium 系代码库的项目理解这份捆绑 gtest 的构建细节是维护其测试体系、避免跨平台链接坑位的基础能力——所有命令与配置均可直接在本仓库v8_7_5/testing/gtest目录下复现验证。【免费下载链接】miniblink49a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核用来取代wke和libcef项目地址: https://gitcode.com/GitHub_Trending/mi/miniblink49创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表