我正在使用CMake构建测试可执行文件。在构建过程中,我想运行可执行文件,它返回测试是否通过。如果没有,我希望构建失败。但是,当我使用add_custom_command(... POST_BUILD ... )
并使用Makefile
生成器时,测试可执行文件将被删除(在此问题中解释:Why does GNU make delete a file)。
有没有办法让CMake将可执行文件视为.PRECIOUS
,或以其他方式更改CMakeLists.txt,以便在测试失败时不会删除可执行文件?
作为参考,我的CMakeList.txt如下所示(从实际中简化):
add_executable(UnitTest unittest.cpp)
add_custom_command(TARGET UnitTest POST_BUILD COMMAND $<TARGET_FILE:UnitTest>)
答案 0 :(得分:2)
我提到的解决方案是使用add_custom_target
而不是add_custom_command
。虽然如果runUnitTest失败,如果测试失败并且整个构建过程失败,它将不会删除可执行文件,但是由于特定地构建UnitTest目标而不会构建此目标。
add_executable(UnitTest unittest.cpp)
add_custom_target(runUnitTest UnitTest COMMAND $<TARGET_FILE:UnitTest> DEPENDS UnitTest)
答案 1 :(得分:0)
我也遇到同样的问题:我有一个单元测试,我只想在以下条件下运行:
如果测试运行失败,我希望保留测试二进制文件以进行调试。
我最终得到的解决方案使用一个标志文件来指示测试已运行,并且不再需要再次执行。请注意,该标志必须位于二进制目录中,这样其他版本才不会受到影响。但是,已设置WORKING_DIRECTORY,因此测试可以访问相对于其源位置的只读数据文件。这就是它的样子-我将其粘贴在宏中,以便所有各种单元测试都可以调用此函数,该宏的唯一输入是测试可执行文件:
set (TEST_FLAG_FILE ${CMAKE_CURRENT_BINARY_DIR}/${TEST_EXECUTABLE}.PASSED)
# This isn't normally needed since a rebuild will have a newer time stamp.
# But it adds robustness to handle changes to the system clock.
add_custom_command(TARGET ${TEST_EXECUTABLE}
COMMENT "Unit test ${TEST_EXECUTABLE} rebuilt; clearing flag ${TEST_FLAG_FILE}."
COMMAND ${CMAKE_COMMAND} -E remove -f ${TEST_FLAG_FILE}
POST_BUILD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# This command only runs if the flag isn't present or is older than the executable.
add_custom_command(OUTPUT ${TEST_FLAG_FILE}
COMMENT "Unit Test Execution: ${TEST_EXECUTABLE}"
COMMAND ${TEST_EXECUTABLE}
COMMAND ${CMAKE_COMMAND} -E touch ${TEST_FLAG_FILE}
MAIN_DEPENDENCY ${TEST_EXECUTABLE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# Any "make all" will evaluate the preceding custom command.
add_custom_target(run_${TEST_EXECUTABLE} ALL DEPENDS ${TEST_FLAG_FILE})