You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为非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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 19:54:50