【问题标题】:CMake exclude tests in subdirectoriesCMake 排除子目录中的测试
【发布时间】:2014-05-17 16:29:49
【问题描述】:

我有一个包含 libevent 库的 c++ 项目。项目结构:

.
|_ CMakeLists.txt
|_ Makefile
|_ src
| |_ my_lib.cpp
|_ test
| |_ my_lib_test.cpp
|_ lib
  |_ libevent
    |_ CMakeLists.txt
    |_ ...

当我构建和运行我的测试时,libevent 测试也会被执行。如何排除它们并只运行我自己的测试?

【问题讨论】:

    标签: cmake ctest


    【解决方案1】:

    还有一种更通用的方法。将一个名为 CTestCustom.cmake 的文件添加到您的源代码树中,并添加一个您希望 CTest 不运行的测试列表:

    set(CTEST_CUSTOM_TESTS_IGNORE
       test1
       ....
       testN
    )
    

    将此文件复制到执行测试的构建目录:

    configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake ${CMAKE_BINARY_DIR})
    

    这将使CTest 忽略列出的测试。请参阅this 了解更多信息。

    【讨论】:

    • 这不太方便:我想排除测试3rd 方库,枚举数百个测试有点累。
    【解决方案2】:

    查看 libevent 的 CMakeLists.txt 文件中的 available options,您可以通过将 EVENT__DISABLE_TESTS 设置为 ON 来轻松禁用这些。

    您可以在包含 libevent 之前在自己的 CMakeLists.txt 中执行此操作:

    set(EVENT__DISABLE_TESTS ON)
    ...
    add_subdirectory(lib/libevent)
    

    或者当你在命令行调用 CMake 时:

    cmake . -DEVENT__DISABLE_TESTS=ON
    

    【讨论】:

    • 如果下次不只是libevent怎么办?是否有标准的 CMake 方法来禁用/启用子项目测试?
    • 没有。在这种情况下,您很幸运,libevent CMakeLists.txt 的创建者已努力提供此选项。许多其他项目确实有类似的选项来避免构建测试/示例/文档/等。但很多人没有。对于那些不这样做的人,您必须修改他们的 CMakeLists.txt 文件(例如,删除/跳过 [add_test] 命令的所有实例)。
    【解决方案3】:

    我找到了另一种(更好的)方法来解决实际问题。

    TL;DR

    添加到您的 CMakeLists.txt 文件中:

    configure_file(${CMAKE_SOURCE_DIR}/CTestCustom.cmake ${CMAKE_BINARY_DIR} @ONLY)
    

    在您的源代码中添加您的CTestCustom.cmake 文件:

    file (STRINGS "@CMAKE_BINARY_DIR@/CTestTestfile.cmake" LINES)
    
    # overwrite the file....
    file(WRITE "@CMAKE_BINARY_DIR@/CTestTestfile.cmake" "")
    
    # loop through the lines,
    foreach(LINE IN LISTS LINES)
      # remove unwanted parts
      string(REGEX REPLACE ".*directory_to_remove.*" "" STRIPPED "${LINE}")
      # and write the (changed) line ...
      file(APPEND "@CMAKE_BINARY_DIR@/CTestTestfile.cmake" "${STRIPPED}\n")
    endforeach()
    

    (删除线的函数形式见https://stackoverflow.com/a/59506088/4166604

    说明:

    排除每个测试方法有很多缺点,包括动态(通过宏)添加测试、浪费时间等......

    这是在 CMake 3.x 上测试的:当构建启用了测试的 CMake 项目时,CTestTestfile.cmake 文件会在 CMAKE_BINARY_DIR 中生成。基本上每次调用add_subdirectory 时,都会将等效的subdirs 命令添加到CTestTestfile.cmake 文件中。 CTestTestfile.cmake 文件将模仿与CMakeLists.txt 文件等效的目录结构。 (因此,如果您需要删除另一个目录中的子目录,那就是您需要编辑的CTestTestfile.cmake)。

    CTestCustom.cmakeCTestTestfile.cmake 之前执行,所以CTestCustom.cmake 需要做的就是从CTestTestfile.cmake 文件中删除有问题的行。这可以通过sed 完成,但本着交叉兼容的精神,现在都是纯 CMake。 CTestCustom.cmake 没有设置CMAKE_BINARY_DIR,所以我们使用@ 替换在CMake 生成时获取CMAKE_BINARY_DIR 的值,并替换构建目录中CTestCustom.cmake 副本中的值,使用@ONLY 替换,不理会其他变量$

    【讨论】:

      【解决方案4】:

      我同意@Ivan Baidakou。

      我不确定这是否更好,但这里有一个不可移植的 hack(默认情况下不适用于 Windows)来完成它。

      execute_process(COMMAND sh -c "echo 'set(CTEST_CUSTOM_TESTS_IGNORE'; find '${CMAKE_SOURCE_DIR}/relative_paths' -path '*tests/CMakeLists.txt' -exec sed -nE '/add_test.*NAME/{s|.*NAME *([^ ]+).*|\\1|; p}' {} +; echo ')'"
                      OUTPUT_FILE ${CMAKE_BINARY_DIR}/CTestCustom.cmake)
      

      如果您愿意,${CMAKE_SOURCE_DIR}/relative_paths 可以是多个库的多个路径。

      【讨论】:

        猜你喜欢
        • 2014-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-13
        • 2018-07-23
        • 2016-06-09
        • 1970-01-01
        相关资源
        最近更新 更多