如何为非POSIX目标编译googletest并解决跨编译报错
问题
项目需适配Linux、Windows及一个在Windows上交叉编译的自定义目标,使用googletest做单元测试,通过以下FindGTest.cmake引入:
# FindGTest.cmake if (CMAKE_SYSTEM_NAME STREQUAL "TheTarget") FetchContent_Declare( GTest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG v1.14.0) FetchContent_MakeAvailable(GTest) else() find_package(GTest CONFIG REQUIRED) endif()
Windows和Linux本地编译正常,但自定义目标编译时出现如下错误:
C:/dev/project/build/_deps/gtest-src/googletest/include\gtest/internal/gtest-port.h:2058:38: error: use of undeclared identifier 'isatty' ... C:/dev/project/build/_deps/gtest-src/googletest/include\gtest/internal/gtest-port.h:2087:44: error: use of undeclared identifier 'chdir' ... C:/dev/project/build/_deps/gtest-src/googletest/include\gtest/internal/gtest-port.h:2135:10: error: use of undeclared identifier 'getenv'; did you mean 'GetEnv'? ... C:/dev/project/build/_deps/gtest-src/googletest\src/gtest-death-test.cc:1106:27: error: use of undeclared identifier 'pipe' ... C:/dev/project/build/_deps/gtest-src/googletest\src/gtest-death-test.cc:1119:27: error: use of undeclared identifier 'fork' ... C:/dev/project/build/_deps/gtest-src/googletest\src/gtest-death-test.cc:1204:3: error: use of undeclared identifier 'execv' ... C:/dev/project/build/_deps/gtest-src/googletest\src/gtest-filepath.cc:115:18: error: use of undeclared identifier 'getcwd'
请问如何解决这些跨编译报错?是否可通过CMake的add_definition()添加宏实现,还是必须定制googletest版本,比如将其作为项目子目录并修改代码?
解决方案
这些错误源于googletest默认适配标准POSIX/Windows环境,你的自定义目标未提供相关POSIX系统调用,通过CMake定义适配宏即可解决,无需修改gtest源码。
1. 通过CMake添加编译宏适配
在FindGTest.cmake中,针对自定义目标为gtest添加编译宏,禁用依赖缺失系统调用的功能:
if (CMAKE_SYSTEM_NAME STREQUAL "TheTarget") FetchContent_Declare( GTest GIT_REPOSITORY https://github.com/google/googletest.git GIT_TAG v1.14.0) FetchContent_MakeAvailable(GTest) # 为gtest相关目标添加编译宏 target_compile_definitions(gtest PUBLIC GTEST_HAS_PTHREAD=0 GTEST_HAS_FORK=0 GTEST_HAS_CHDIR=0 GTEST_HAS_GETENV=0 GTEST_HAS_GETCWD=0 GTEST_HAS_ISATTY=0 ) target_compile_definitions(gtest_main PUBLIC GTEST_HAS_PTHREAD=0 GTEST_HAS_FORK=0 GTEST_HAS_CHDIR=0 GTEST_HAS_GETENV=0 GTEST_HAS_GETCWD=0 GTEST_HAS_ISATTY=0 ) target_compile_definitions(gmock PUBLIC GTEST_HAS_PTHREAD=0 GTEST_HAS_FORK=0 GTEST_HAS_CHDIR=0 GTEST_HAS_GETENV=0 GTEST_HAS_GETCWD=0 GTEST_HAS_ISATTY=0 ) else() find_package(GTest CONFIG REQUIRED) endif()
2. 各宏的作用说明
GTEST_HAS_FORK=0:禁用依赖fork/execv/pipe的死亡测试功能GTEST_HAS_CHDIR=0:禁用chdir相关调用GTEST_HAS_GETENV=0:禁用getenv调用,避免与Windows的GetEnv冲突GTEST_HAS_GETCWD=0:禁用getcwd调用GTEST_HAS_ISATTY=0:禁用isatty调用GTEST_HAS_PTHREAD=0:若自定义目标不支持POSIX线程,需保留该宏
3. 特殊场景适配
如果自定义目标有部分系统调用的替代实现,可单独调整对应宏:比如有兼容的getenv包装,可将GTEST_HAS_GETENV设为1,同时在项目中提供符合gtest调用要求的getenv实现。
无需定制gtest版本
通过上述CMake宏定义即可解决问题,不需要修改gtest源码或作为子目录定制,仅当目标环境有极端特殊需求(如完全不兼容标准C++库部分功能)时,才需要考虑修改gtest的端口适配代码。
内容的提问来源于stack exchange,提问作者StoneThrow
相关产品推荐
相关产品推荐

