为基础CMake项目集成Google Test时遭遇链接错误求助
基础CMake项目集成Google Test时遭遇链接错误求助
嗨,我一眼就看到问题所在啦——你遇到的链接错误,核心原因是测试代码在尝试链接一个名为my_project的库,但你的根目录CMakeLists.txt里根本没生成这个库!
你的根目录CMake是直接把代码编译成了可执行文件my_app,而可执行文件是不能被其他目标(比如你的测试程序)链接的。要让测试能调用主项目的业务代码,我们得把主项目里的业务逻辑抽出来编译成一个库,再让主程序和测试程序分别链接这个库。
具体修改方案
第一步:调整根目录的CMakeLists.txt
首先,我们要把主项目的业务逻辑和入口代码(main.cpp)分离:
- 如果你的
main.cpp里既有业务逻辑(需要被测试的函数)又有main入口函数,先把业务逻辑移到单独的文件里(比如app_logic.cpp),并在header_1.h中声明这些函数。 - 然后修改根目录CMake,先构建业务库,再构建主程序并链接这个库:
cmake_minimum_required (VERSION 3.1) project (my_project) set (CMAKE_CXX_STANDARD 23) set (CXX_STANDARD_REQUIRED ON) set (CMAKE_CXX_EXTENSIONS OFF) # 1. 把业务代码编译为静态库(命名为my_project,和项目名一致) add_library(my_project STATIC header_1.h app_logic.cpp) # 公开当前目录作为头文件目录,让测试和主程序都能找到header_1.h target_include_directories(my_project PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # 2. 构建主程序可执行文件,链接业务库 add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE my_project) # 3. 添加测试子目录 add_subdirectory(test)
第二步:优化测试目录的CMakeLists.txt
接下来调整测试目录的CMake,用更现代的CMake写法,同时确保链接的是我们刚创建的业务库:
set(BINARY ${CMAKE_PROJECT_NAME}_test) # 更推荐明确列出测试文件,避免GLOB意外包含无关文件 set(TEST_SOURCES main.cpp tests.cpp) add_executable(${BINARY} ${TEST_SOURCES}) # 用现代CMake方式查找GTest find_package(GTest REQUIRED) include(GoogleTest) # 链接依赖:业务库、GTest组件和线程库 target_link_libraries(${BINARY} PRIVATE ${CMAKE_PROJECT_NAME} GTest::GTest GTest::Main pthread ) # 自动发现测试用例(比传统add_test更灵活) gtest_discover_tests(${BINARY})
为什么这样改能解决问题?
- 库 vs 可执行文件:我们把业务代码编译成了名为
my_project的静态库,测试程序现在能找到这个库并链接它,而不是尝试链接一个不存在的库。 - 头文件可见性:
target_include_directories确保测试程序能找到主项目的头文件(比如header_1.h)。 - 现代CMake用法:使用
GTest::GTest、GTest::Main和gtest_discover_tests比旧的${GTEST_LIBRARIES}和add_test更可靠,也更符合当前CMake的最佳实践。
额外小提示
- 尽量避免用
file(GLOB_RECURSE)来收集源文件,因为它可能会意外包含临时文件或无关文件,明确列出文件更安全。 - 如果你的业务逻辑本来就和
main入口完全分离,那只需要调整根目录CMake的构建顺序,把业务代码做成库即可,不需要修改源文件结构。
现在清理你的build目录,重新运行cmake ..和make,链接错误应该就消失啦!
内容来源于stack exchange
相关产品推荐
相关产品推荐

