cmake add_custom_command失败,目标被删除

时间:2016-09-21 16:48:28

标签: c++ cmake gnu-make

我正在使用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>)

2 个答案:

答案 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)

我也遇到同样的问题:我有一个单元测试,我只想在以下条件下运行:

  1. 测试已修改。
  2. 被测代码已被修改。
  3. 测试未通过之前的执行。

如果测试运行失败,我希望保留测试二进制文件以进行调试。

我最终得到的解决方案使用一个标志文件来指示测试已运行,并且不再需要再次执行。请注意,该标志必须位于二进制目录中,这样其他版本才不会受到影响。但是,已设置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})