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

src与test目录分离的CMake项目集成googletest的问题及解决方案

CMake分离结构项目GTest集成避免重复配置方案

项目基础信息

项目采用头文件与源码分离的结构,目录树如下:

.
├── 1Cmake.sh
├── 2runExe.sh
├── 3cleanTarget.sh
├── 4runTest.sh
├── 7VersionOfCurrentTools.sh
├── build
│   ├── CMakeCache.txt
│   ├──...
│   ...
├── CMakeDefaults.txt
├── CMakeLists.txt
├── compile_commands.json -> ...
├── data
├── docs
│   ├── ...
├── include
│   └── addition
│       └── addition.hpp
├── src
│   ├── addition
│   │   └── addition.cpp
│   ├── main.cpp
├── tests
│   └── test01_proofOfWork
│       ├── CMakeLists.txt
│       └── tests.cpp

核心业务代码

  • addition.hpp头文件
#pragma once
int add(int a, int b);
  • addition.cpp实现
#include "addition.hpp"
int add(int a, int b) { return a + b; }
  • main.cpp程序入口
#include "addition.hpp"

#include <iostream>
int main() {
  int a = 5;
  int b = 3;
  std::cout << "a is " << a << "\nb is " << b << "\nThe Sum of both "
<< add(a, b) << std::endl; }

原有配置与问题说明

根目录CMakeLists.txt配置

cmake_minimum_required(VERSION 3.21.2)
set (This
    Project_main)

project(${This}
    LANGUAGES CXX
    VERSION 1.000)

enable_testing()
find_package(GTest REQUIRED)

add_subdirectory(./tests/test01_proofOfWork)

# Custom Variables
set(QUELLE src/main.cpp)
set(ZIEL finalExecutable)

# integrate lib (with .cpp and its header)
set(LIB_1 addition)

add_library(                                
    ${LIB_1}                                
    STATIC src/addition/addition.cpp        
    )
# add .hpp hinzufuegen and connect to lib
target_include_directories(              
    ${LIB_1}                             
    PUBLIC include/addition             
    )
# add executable
add_executable(${ZIEL} ${QUELLE})       

# linking the lib  
target_link_libraries(                  
    ${ZIEL}                             
    PRIVATE ${LIB_1}                    
    #    PUBLIC ${LIB_1}                    
    )

测试目录原有配置

测试目录CMakeLists.txt:

# Name of the Tests
set (This
    runTest)

# Location of the test
set (Sources
    tests.cpp)

# executable of the test
add_executable(${This} ${Sources})

# linking libs for the test
target_link_libraries(${This} PUBLIC
    GTest::gmock
    GTest::gtest
    GTest::gmock_main
    GTest::gtest_main)
# registrating the test 
gtest_discover_tests(${This})

测试用例代码:

// tests.cpp
// #include "./../../include/addition/addition.hpp"
#include <gtest/gtest.h>
#include <gtest/internal/gtest-internal.h>

// bool foo(){
//     return true;
// }
// 
// 
// TEST(Simpletest, trueEqualsTrue) {
//     EXPECT_TRUE(foo());
//     EXPECT_FALSE(foo());
//     EXPECT_EQ(true, foo());
//     ASSERT_FALSE(foo());
//     EXPECT_EQ(false, foo());
// }
//
TEST(SquareRootTest, PositiveNos) {
    ASSERT_EQ(18.0, add(1,17));
    EXPECT_EQ(6, add(1,6));
    ASSERT_EQ(25.4, add(55, -1));
    ASSERT_EQ(0, add(-4, 4));
}


int main(int argc, char **argv) {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

注释掉的同文件内测试逻辑可正常编译运行,说明GTest安装、CMake基础配置无误,但调用业务层的add函数时会报头文件缺失、符号未定义错误。如果每个测试都单独配置头文件路径、链接依赖,项目复杂度升高后会产生大量重复配置工作。

解决方案

CMake支持将静态库的头文件路径、依赖等属性自动传递给链接该库的目标,本次场景中业务代码已经封装为带PUBLIC头文件声明的addition静态库,只需在测试目标的链接配置中加入该业务静态库即可,无需额外重复配置头文件路径。
修改后的测试目录CMakeLists.txt链接部分:

# linking libs for the test
target_link_libraries(${This} PUBLIC
    GTest::gmock
    GTest::gtest
    GTest::gmock_main
    GTest::gtest_main
    # 新增:将需要测试的业务静态库链接到测试可执行文件
    addition
    )

配置完成后,测试代码中直接引入addition.hpp即可正常调用业务接口,不会再报头文件或符号未定义错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:57:01