CMake多Boost单元测试项目编译运行配置问题咨询
解决CMake测试目标重复创建与测试未编译问题
看起来你踩了CMake循环创建目标的典型坑,同时也没把测试目标正确纳入构建流程。我来一步步帮你解决:
核心问题分析
- 重复
targetname报错:你在foreach循环里每次都调用add_custom_target(targetname),CMake不允许重复创建同名目标,循环多少次就会报错多少次。 - 注释后测试未编译:默认情况下CMake不会自动构建非默认目标,你之前的测试可执行文件没有被关联到默认构建流程里,所以注释掉自定义目标后,测试不会被自动编译。
修改后的tests/CMakeLists.txt
# 仅当测试文件名包含"test"且触发CMP0037警告时需要此政策,否则可移除 cmake_policy(SET CMP0037 OLD) # 配置Boost库查找参数 set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) set(Boost_USE_STATIC_RUNTIME OFF) find_package(Boost 1.59 REQUIRED COMPONENTS unit_test_framework date_time regex) # 引入头文件路径 include_directories("${CMAKE_SOURCE_DIR}/source" ${Boost_INCLUDE_DIRS}) # 收集测试源文件(小型项目可用,大型项目建议手动列源文件) file(GLOB APP_SOURCES *.cpp) # 创建统一的测试总目标,方便批量构建所有测试 add_custom_target(all_tests) foreach(testsourcefile ${APP_SOURCES}) # 提取干净的测试文件名(不带路径和后缀),避免路径导致的目标名异常 get_filename_component(testname ${testsourcefile} NAME_WE) # 为每个测试文件生成独立的可执行文件 add_executable(${testname} ${testsourcefile}) # 链接依赖库 target_link_libraries(${testname} LINK_PUBLIC ${Boost_LIBRARIES} MyProject_lib) # 将测试注册到CMake测试系统,支持用`ctest`批量运行 add_test(NAME ${testname} COMMAND ${testname}) # 让总测试目标依赖每个测试可执行文件,构建all_tests就会编译所有测试 add_dependencies(all_tests ${testname}) # 可选:构建完当前测试后自动运行它,方便即时查看结果 add_custom_command(TARGET ${testname} POST_BUILD COMMAND ${testname} COMMENT "Running test ${testname}..." ) endforeach(testsourcefile ${APP_SOURCES}) # 可选:取消注释后,编译主库时会自动编译并运行所有测试 # add_dependencies(MyProject_lib all_tests)
关键修改说明
- 消除重复目标报错:移除了循环内重复创建的
add_custom_target(targetname),转而将POST_BUILD命令直接绑定到每个测试可执行目标上,每个测试拥有独立的构建后执行逻辑。 - 解决测试未编译问题:
- 创建
all_tests总目标,所有测试可执行文件都依赖它,运行make all_tests(或在VS中构建all_tests目标)即可批量编译测试; - 若想让默认编译自动包含测试,取消最后一行注释,这样编译主库时会自动触发测试的编译与运行。
- 创建
- 优化目标名生成:用
get_filename_component替代简单的字符串替换,避免源文件带路径时生成奇怪的目标名(比如./test_user)。 - 集成CMake测试框架:通过
add_test将测试注册到CMake系统,之后可以直接用ctest命令批量运行所有测试,还能生成标准化测试报告。
额外建议
- 尽量避免依赖
file(GLOB)收集源文件,CMake不会自动检测新添加的文件,大型项目建议手动列出所有测试源文件; - 外层
CMakeLists.txt中的enable_testing()位置没问题,但通常建议放在项目初始化语句之后; - 如果你的环境Boost版本高于1.59,可以去掉版本限制,让CMake自动适配最新可用版本。
内容的提问来源于stack exchange,提问作者J. D.
相关产品推荐
相关产品推荐

