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
相关产品推荐
相关产品推荐

