cmake add_custom_command 失败,目标被删除
cmake add_custom_command failure, target gets deleted
我正在使用 CMake 构建测试可执行文件。在构建过程中,我想要 运行 可执行文件,returns 无论测试是否通过。如果没有,我希望构建失败。但是,当我使用 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>)
我提到的解决方案是使用 add_custom_target
而不是 add_custom_command
。虽然如果测试失败它不会删除可执行文件,如果 runUnitTest 失败则整个构建过程失败,但由于专门构建 UnitTest 目标,因此不会构建此目标。
add_executable(UnitTest unittest.cpp)
add_custom_target(runUnitTest UnitTest COMMAND $<TARGET_FILE:UnitTest> DEPENDS UnitTest)
我遇到了同样的问题:我有一个单元测试我只想 运行 在以下条件下:
- 测试已修改
- 被测代码已修改
- 测试在之前的执行中失败。
如果测试 运行 失败,我希望保留测试二进制文件以进行调试。
我最终得到的解决方案使用标志文件来指示测试已经 运行 并且不再需要再次执行。请注意,该标志必须位于二进制目录中,这样其他构建才不会受到影响。但是 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})
我正在使用 CMake 构建测试可执行文件。在构建过程中,我想要 运行 可执行文件,returns 无论测试是否通过。如果没有,我希望构建失败。但是,当我使用 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>)
我提到的解决方案是使用 add_custom_target
而不是 add_custom_command
。虽然如果测试失败它不会删除可执行文件,如果 runUnitTest 失败则整个构建过程失败,但由于专门构建 UnitTest 目标,因此不会构建此目标。
add_executable(UnitTest unittest.cpp)
add_custom_target(runUnitTest UnitTest COMMAND $<TARGET_FILE:UnitTest> DEPENDS UnitTest)
我遇到了同样的问题:我有一个单元测试我只想 运行 在以下条件下:
- 测试已修改
- 被测代码已修改
- 测试在之前的执行中失败。
如果测试 运行 失败,我希望保留测试二进制文件以进行调试。
我最终得到的解决方案使用标志文件来指示测试已经 运行 并且不再需要再次执行。请注意,该标志必须位于二进制目录中,这样其他构建才不会受到影响。但是 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})