【问题标题】:CMake "RUN_TESTS" or "test" targetCMake“RUN_TESTS”或“测试”目标
【发布时间】:2018-05-10 00:09:00
【问题描述】:

在我的“plange_superbuild”CMakeLists.txt 中,我有:

add_test(plange_test ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/prefix/src/plange-build --target test)

它应该调用“plange”子项目的测试目标,并且在使用 Makefile 生成器时可以正常工作。但是,CMake 测试documentation 解释说:

[ enable_testing() ] 添加另一个构建目标,它是 Makefile 生成器的测试, 或 RUN_TESTS 用于集成开发环境(如 Visual 工作室)。

所以,我的 sn-p 不适用于使用 IDE 构建的版本,因为我只是在说“测试”。如何使该命令在 IDE 版本中也能正常工作?

我已经想到了一些可能的解决方法。一种是使用现有的 CMake 变量(如果存在)来获取测试目标的名称。这是一个等于 test 的变量(我们称之为 CMAKE_TEST_TARGET),除非在 IDE 构建中它等于 RUN_TESTS,允许以下操作:

add_test(plange_test ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/prefix/src/plange-build --target ${CMAKE_TEST_TARGET})

虽然我不知道这样的变量。也许我可以通过 CMAKE_GENERATOR 变量(或 MSVC 和类似变量)检测基于 IDE 的构建,并手动设置所谓的 CMAKE_TEST_TARGET 变量。这将需要了解(并维护)CMake 用于确定我的 CMakeLists.txt 中的“测试”或“RUN_TESTS”的确切逻辑,这将是不可靠的。

我的另一个想法是使用类似于 CMAKE_COMMAND 的变量(我们称之为 CTEST_COMMAND)直接调用 ctest,但指向 ctest 可执行文件。同样,我不知道这样的变量。

编辑:有 CMAKE_CTEST_COMMAND 请参阅https://stackoverflow.com/a/736838/395029 和我在其中的评论

我从 CMAKE_COMMAND 派生了这个变量,使用 get_filename_component() 来提取 bin 目录,但这取决于 CMAKE_COMMAND 没有任何嵌入的参数。这是一个安全的假设吗?这适用于 Makefile 生成器,但不适用于 VC++2017 生成器。 VC++ 中的错误信息不清楚,但我试过了:

get_filename_component(CMAKE_EXECUTABLES_DIR ${CMAKE_COMMAND} DIRECTORY)
set(CTEST_COMMAND "${CMAKE_EXECUTABLES_DIR}/ctest${CMAKE_EXECUTABLE_SUFFIX}")
add_test(NAME plange_test COMMAND ${CTEST_COMMAND} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/prefix/src/plange-build)

superbuild项目中VC++2017的错误信息:

1>The following tests FAILED:
1>    1 - plange_test (Failed)
1>Errors while running CTest
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: The command "setlocal
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: "C:\Program Files\CMake\bin\ctest.exe" --force-new-ctest-process -C Debug
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: :cmEnd
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: :cmErrorLevel
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: exit /b %1
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: :cmDone
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: :VCEnd" exited with code 8.
1>Done building project "RUN_TESTS.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

我能够成功地从该错误输出运行命令:

C:\...\plange.build\prefix\src\plange-build>ctest --force-new-ctest-process -C Debug

但是:

C:\...\plange.build>ctest --force-new-ctest-process -C Debug

失败,所以这使失败更加混乱。这些是常见的做法之一吗?是否有一些我没有考虑过的优越(有效)方法?

编辑:通过 CMAKE_CTEST_COMMAND 我了解到“-C 调试”没有通过,这使得它在 IDE 中失败。查看我的 cmets

【问题讨论】:

  • 我发现如果我添加“-C Debug”它可以在 VC++2017 中工作。 add_test(NAME plange_test COMMAND ${CTEST_COMMAND} -C Debug WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/prefix/src/plange-build)。但是,当我将 Debug 替换为 CMAKE_CFG_INTDIR 时,它不起作用。
  • 鉴于 CMAKE_CFG_INTDIR 的限制,我改为在子项目的 CMakeLists.txt 中复制(更改路径)测试以直接运行测试。 add_test(NAME plange_test COMMAND "${ARTIFACTS_PREFIX}/bin/plc${CMAKE_EXECUTABLE_SUFFIX}" --test)。这行得通,但我仍然想要上面的答案,这是 IMO 的首选。
  • 最终,我放弃了 CMake 的“超级构建”概念,并想出了如何扁平化构建。

标签: testing cmake


【解决方案1】:

在 cmake 源代码中,您可以找到一个未记录的变量,但如果您使用 include(CTest) 而不是 enable_testing() 则可能会达到您的目的

查看此提交:https://github.com/Kitware/CMake/commit/816c9d1aa1f2b42d40c81a991b68c96eb12b6d26#diff-73eaa76f278a4e8afe41a9ffb838ccc4:

 # If requested, add an alias that is the equivalent of the built-in "test"
  # or "RUN_TESTS" target:
  if(CTEST_TEST_TARGET_ALIAS)
    add_custom_target(${CTEST_TEST_TARGET_ALIAS}
      ${CMAKE_CTEST_COMMAND} ${__conf_types}
      USES_TERMINAL
      )
  endif()
endif()

这意味着如果在您的 Cmakelist.txt 中您调用 set(CTEST_TEST_TARGET_ALIAS my_name_for_target_test) 然后 include(CTest),您可以可靠地使用 my_name_for_target_test 根据此评论(我没有检查自己是否真的有效)。由于此别名是通过 add_custom_target 创建的,因此这不是内置目标,并且您没有那些(非常烦人的)限制,包括无法添加对它/从它的依赖项。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多