升级googletest至1.12.1后链接问题解决咨询(保留指定编译选项)
问题描述
将GoogleTest从1.8.1升级至1.12.1后,构建过程出现链接错误,触发条件为启用gcov并同时使用-fkeep-inline-functions和-std=gnu++2a编译选项。链接错误涉及以下两处代码:
代码位置1(gtest-printers.h)
#ifdef __cpp_char8_t // Overloads for u8 strings. GTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os); inline void PrintTo(char8_t* s, ::std::ostream* os) { PrintTo(ImplicitCast_<const char8_t*>(s), os); } #endif
代码位置2(gtest-printers.h)
// gcc/clang __{u,}int128_t #if defined(__SIZEOF_INT128__) GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os); GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os); #endif // __SIZEOF_INT128__
GoogleTest 1.12.1的相关CMake配置片段:
配置片段1(internal_utils.cmake)
if (NOT "${CMAKE_VERSION}" VERSION_LESS "3.8") target_compile_features(${name} PUBLIC cxx_std_11) endif()
配置片段2(CMakeLists.txt)
if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX) set(CMAKE_CXX_EXTENSIONS OFF) endif()
需求:在必须保留-std=gnu++2a(支持C++20特性)、可选保留-fkeep-inline-functions的前提下,提供最优解决路径。
解决路径
核心原因
链接错误的本质是项目与GoogleTest的编译标准不匹配:
-std=gnu++2a启用C++20特性,触发__cpp_char8_t宏并开启__int128_t/__uint128_t支持,项目代码生成了对这些类型PrintTo函数的引用;- GoogleTest 1.12.1默认以纯C++11标准编译(
cxx_std_11为PUBLIC级别且关闭GNU扩展),库中未生成对应函数的实现; -fkeep-inline-functions强制保留内联函数符号,放大了符号缺失问题——原本可能被优化掉的引用现在必须找到实现。
具体方案
方案1:统一编译标准(优先推荐)
修改CMake配置,让GoogleTest使用与项目一致的gnu++2a标准,确保生成对应符号的实现:
# 覆盖GoogleTest默认编译标准,启用带GNU扩展的C++20 set_target_properties(gtest gtest_main PROPERTIES CXX_STANDARD 20 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS ON )
此方案可完全保留-std=gnu++2a和-fkeep-inline-functions,从根源解决标准不匹配问题。
方案2:针对GoogleTest禁用-fkeep-inline-functions
若无需对GoogleTest代码做gcov覆盖率统计,可仅在项目代码中保留该选项,对GoogleTest目标移除:
# 移除GoogleTest目标的-fkeep-inline-functions选项 target_compile_options(gtest gtest_main PRIVATE -fno-keep-inline-functions)
此方案无需修改编译标准,但仅适用于不需要覆盖GoogleTest代码的场景。
方案3:升级GoogleTest版本(长期推荐)
GoogleTest 1.12.x对C++20的支持不完善,升级至1.13.x及以上版本后,CMake配置会自动适配项目的编译标准,可直接解决此类链接问题,同时兼容-std=gnu++2a和-fkeep-inline-functions。
内容的提问来源于stack exchange,提问作者MarkB
相关产品推荐
相关产品推荐

