【问题标题】:CMake unit structure with many tests具有许多测试的 CMake 单元结构
【发布时间】:2018-01-05 09:40:15
【问题描述】:

我想设置 cmake 以在具有单元测试的项目上运行。项目结构如下:

|---CMakeLists.txt
|---build
|---source
|   |---CMakeLists.txt
|   |---many .cpp and .h files
|---tests
|   |---CMakeLists.txt
|   |---many .cpp files

tests 中的源文件使用 Boost unit_test.h 库。

我的外层CMakeLists.txt如下:

cmake_minimum_required(VERSION 2.8.11)

set(CMAKE_CXX_FLAGS "-std=c++11")

project(MyProject CXX)
add_subdirectory(source)
add_subdirectory(tests)
enable_testing()

source 文件夹中的CMakeLists.txt 是:

file( GLOB LIB_SOURCES *.cpp )
file( GLOB LIB_HEADERS *.h )
add_library( MyProject_lib ${LIB_SOURCES} ${LIB_HEADERS} )

tests 文件夹中的CMakeLists.txt 是:

# require old policy to allow for source files containing the name "test"
cmake_policy(SET CMP0037 OLD)
# Locate Boost libraries: unit_test_framework, date_time and regex
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)
foreach(testsourcefile ${APP_SOURCES})
    string(REPLACE ".cpp" "" testname ${testsourcefile})
    add_executable(${testname} ${testsourcefile})
    target_link_libraries(${testname} LINK_PUBLIC ${Boost_LIBRARIES} MyProject_lib)
    add_custom_target(targetname)
    add_custom_command(TARGET targetname POST_BUILD COMMAND ${testname})
endforeach(testsourcefile ${APP_SOURCES})

如果我用add_custom_targetadd_custom_command 注释这些行,则此配置的结果是库已正确构建和链接,但没有编译任何测试。

如果我不使用add_custom_targetadd_custom_command 注释这两行,运行cmake 得到的错误是:

CMake Error at tests/CMakeLists.txt:25 (add_custom_target):
add_custom_target cannot create target "targetname" because another target
with the same name already exists.  The existing target is a custom target
created in source directory "/tests".  See
documentation for policy CMP0002 for more details.

由于我有大量的测试,一一列出是不切实际的。我想让 cmake 找到所有 .cpp 文件,就像对源文件夹中的库所做的那样,编译并运行它们。

【问题讨论】:

    标签: c++ unit-testing cmake


    【解决方案1】:

    这是我在库中使用的解决方案:

    FILE( GLOB log_testprograms *.cpp )
    
    FOREACH( testsource ${log_testprograms} )
       GET_FILENAME_COMPONENT( filename ${testsource} NAME_WE )
       celma_add_celma_boost_testprogram( ${filename} )
    ENDFOREACH()
    

    celma_add_celma_boost_testprogram 是这样的宏:

    macro( celma_add_celma_boost_testprogram  filename )
       add_executable(        ${filename}  ${filename}.cpp )
       target_link_libraries( ${filename}  celma ${Boost_Test_Link_Libs} )
       add_test(              ${filename}  ${CMAKE_CURRENT_BINARY_DIR}/${filename} )
    endmacro( celma_add_celma_boost_testprogram )
    

    Celma 是我的库的名称,变量 Boost_Test_Link_Libs 包含要链接的 Boost 库列表,包括 Boost.Test 库。

    【讨论】:

    • 谢谢,这确实解决了编译tests文件夹中的源文件的问题,但是编译链接后的可执行文件如何运行呢?
    • 当你使用add_test命令时,你可以在之后简单的输入make test来运行所有的测试程序。
    • 如果我输入 make test,我会收到警告 No tests were found!!!。如果我在宏中添加以下行:add_custom_command(TARGET ${filename} POST_BUILD COMMAND ${filename}) 那么它可以工作,但我认为这不是使用 cmake 进行单元测试的正确方法。
    • 我贴的那几行就够了。也许你应该在add_subdirectory 调用之前移动你的enable_testing 调用。
    猜你喜欢
    • 2013-01-04
    • 2018-09-08
    • 2011-11-07
    • 2016-02-05
    • 1970-01-01
    • 1970-01-01
    • 2022-11-08
    • 2018-10-12
    • 1970-01-01
    相关资源
    最近更新 更多