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

如何用CMake同时构建32位和64位GoogleTest测试程序

同一CMake项目中同时构建32/64位GoogleTest测试程序的架构冲突解决办法

问题背景

为支持32/64位核心的平台开发软件,需用GoogleTest分别为两类软件编写单元测试:32位软件的测试程序必须以32位构建,64位软件的测试程序以64位构建,这意味着要分别编译对应架构的GoogleTest。

单独构建子目录可正常工作,但根目录通过add_subdirectory同时添加两个子目录后构建失败——GoogleTest仅被构建一次,导致架构不兼容,触发链接错误。

需求:

  • VSCode环境下无需手动修改cmake.sourceDirectory,一次性编译两种架构的所有测试程序
  • 不将预编译库及GoogleTest头文件加入Git仓库,优先使用CMake FetchContent特性按需获取编译
  • 分别编译构建各目标,规避架构冲突

项目结构:

├─ CMakeLists.txt
├─ test32/
   ├─ CMakeLists.txt
   ├─ src/
      ├─ calc32.c
      ├─ calc32.h
   ├─ tests/
      ├─ tests32.cpp
      ├─ unit_tests_main.cpp
└─ test64/
   ├─ CMakeLists.txt
   ├─ src/
      ├─ calc64.c
      ├─ calc64.h
   ├─ tests/
      ├─ tests64.cpp
      ├─ unit_tests_main.cpp

原根目录CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)

project(tests)

add_subdirectory("test32")
add_subdirectory("test64")

原test32与test64目录的CMakeLists.txt基本一致,仅32位版本多了设置-m32属性的代码。

解决方案

核心问题是FetchContent默认全局共享依赖构建结果,导致32/64位GoogleTest冲突。解决思路是让每个子项目独立构建专属的GoogleTest实例,互不干扰。

1. 根目录CMakeLists.txt无需修改

保持原结构即可,确保CMake版本≥3.14。

2. 修改test32/CMakeLists.txt

替换FetchContent_MakeAvailable为手动流程,指定独立的依赖目录,并在构建GoogleTest时直接设置32位编译选项:

project(test32)

cmake_minimum_required(VERSION 3.14)

set(EXEC_NAME "calc32")
set(TEST_EXEC_NAME "calc32_tests")
set(TEST_DIR "./tests")
set(SRC_DIR "./src")

include(GoogleTest)
include(FetchContent)

enable_testing()

FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git 
    GIT_TAG v1.13.0
)

# 为32位测试单独设置依赖目录,避免与64位共享
set(FETCHCONTENT_BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}/_deps)
FetchContent_Populate(googletest)

# 全局设置32位编译链接选项,确保GoogleTest本身以32位构建
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")

# 构建32位GoogleTest,EXCLUDE_FROM_ALL避免被根项目默认触发
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)

# 恢复全局编译选项,避免影响其他子项目
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")

add_executable(${TEST_EXEC_NAME}
    ${TEST_DIR}/unit_tests_main.cpp
    ${TEST_DIR}/tests32.cpp
    ${SRC_DIR}/calc32.c
)

# 强制测试程序以32位构建
set_target_properties(${TEST_EXEC_NAME} PROPERTIES COMPILE_OPTIONS "-m32" LINK_FLAGS "-m32")

target_include_directories(${TEST_EXEC_NAME} PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${SRC_DIR}
)

target_link_libraries(
    ${TEST_EXEC_NAME}
    gtest
)

gtest_discover_tests(${TEST_EXEC_NAME})

3. 修改test64/CMakeLists.txt

同样使用独立依赖目录,默认构建64位GoogleTest:

project(test64)

cmake_minimum_required(VERSION 3.14)

set(EXEC_NAME "calc64")
set(TEST_EXEC_NAME "calc64_tests")
set(TEST_DIR "./tests")
set(SRC_DIR "./src")

include(GoogleTest)
include(FetchContent)

enable_testing()

FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git 
    GIT_TAG v1.13.0
)

# 为64位测试单独设置依赖目录
set(FETCHCONTENT_BASE_DIR ${CMAKE_CURRENT_BINARY_DIR}/_deps)
FetchContent_Populate(googletest)

# 构建64位GoogleTest
add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL)

add_executable(${TEST_EXEC_NAME}
    ${TEST_DIR}/unit_tests_main.cpp
    ${TEST_DIR}/tests64.cpp
    ${SRC_DIR}/calc64.c
)

target_include_directories(${TEST_EXEC_NAME} PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${SRC_DIR}
)

target_link_libraries(
    ${TEST_EXEC_NAME}
    gtest
)

gtest_discover_tests(${TEST_EXEC_NAME})

关键说明

  • FETCHCONTENT_BASE_DIR指定为当前子项目二进制目录下的_deps,确保两个子项目的GoogleTest下载、构建目录完全独立,无交叉污染。
  • 用FetchContent_Populate+add_subdirectory替代FetchContent_MakeAvailable,完全控制GoogleTest的构建流程,从根源保证架构匹配。
  • EXCLUDE_FROM_ALL参数确保GoogleTest仅在测试程序依赖时才会构建,不会被根项目的all目标默认触发。

修改完成后,根项目构建时会分别编译32位/64位的GoogleTest及对应测试程序,无架构冲突,无需手动修改VSCode配置即可一次性完成所有编译。

内容的提问来源于stack exchange,提问作者Nr7

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:12:13