我想用CMake写一个小单元测试系统,我可以轻松地复制并粘贴到我的所有项目中,所以我想出了这个:
include(CMakeParseArguments)
set(UNIT_TEST "unit_tests")
add_custom_target(${UNIT_TEST} ALL VERBATIM)
function(add_unit_test dependency)
cmake_parse_arguments(UT_ "" "NAME" "" ${ARGN})
if(NOT ${UT_NAME})
set(${UT_NAME} ${ARG0})
endif()
add_test(${ARGN})
add_dependencies(${UNIT_TEST} ${dependency})
add_custom_command(TARGET ${UNIT_TEST}
COMMENT "Run tests"
POST_BUILD COMMAND ctest
ARGS -R ${UT_NAME} --output-on-failures
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
VERBATIM)
endfunction(add_unit_test)
我希望它可以正常运行并运行我将在项目中添加的所有单元测试,通过调用add_unit_test(dep ...)
来依次编译,然后使用与add_test(...)
相同的参数。实际上,这个错误出现了:
CMake Warning (dev) at cmake/testing.cmake:13 (add_custom_command):
Policy CMP0040 is not set: The target in the TARGET signature of
add_custom_command() must exist. Run "cmake --help-policy CMP0040" for
policy details. Use the cmake_policy command to set the policy and
suppress this warning.
The target name "unit_tests" is unknown in this context.
Call Stack (most recent call first):
source/test/CMakeLists.txt:10 (add_unit_test)
This warning is for project developers. Use -Wno-dev to suppress it.
为什么此时目标未知? include(cmake/testing.cmake)
是我在项目构建脚本中cmake_minimum_required
之后调用的第一个内容,因此无法调用add_custom_target(${UNIT_TEST} ALL VERBATIM)
。
有没有办法可以将自定义命令添加到UNIT_TEST目标?
答案 0 :(得分:1)
刚刚遇到了您的问题并尝试重现您的问题。
我的第一个建议是:如果你致电enable_testing()
,你会直接获得由CMake生成的“运行测试”目标。见CMake: Testing with CTest:
构建项目后,您可以通过
执行所有测试make test
使用Makefile生成器,或者通过重建RUN_TESTS目标 你骑。在内部,它运行CTest以实际执行测试; 你也可以执行
ctest
在构建的二进制目录中。
调试您的指定代码
如果我将有效目标命名为add_unit_test()
的第一个参数,则表示我未收到CMP0040
错误。因此,请再次检查您是否提供了有效的目标。
但是你的脚本中有一些错误。这是一个工作版本:
include(CMakeParseArguments)
enable_testing()
set(UNIT_TEST "unit_tests")
add_custom_target(${UNIT_TEST} ALL)
function(add_unit_test dependency)
cmake_parse_arguments(UT "" "NAME" "COMMAND" ${ARGN} )
if("${UT_NAME}" STREQUAL "")
set(${UT_NAME} "${ARGV1}")
endif()
add_test(${ARGN})
add_dependencies(${UNIT_TEST} ${dependency})
add_custom_command(TARGET ${UNIT_TEST}
COMMENT "Run tests"
POST_BUILD COMMAND ctest
ARGS -C $<CONFIGURATION> -R "^${UT_NAME}$" --output-on-failures)
endfunction(add_unit_test)
enable_testing()
_
UT
的结尾cmake_parse_arguments(UT ...)
STREQUAL ""
V
添加ARGV1
并转到第二个参数(索引0为dependency
)VERBATIM
-C $<CONFIGURATION>
参数(请参阅How to run ctest after building my project with cmake)"^${UT_NAME}$"
以获取完全匹配的名称将上述代码移至名为UnitTest.cmake
的文件中我已成功使用以下主CMakeLists.txt
进行测试:
cmake_minimum_required(VERSION 2.8)
project(Example CXX)
include(${CMAKE_CURRENT_LIST_DIR}/UnitTest.cmake)
file(WRITE foo.cc "#include <windows.h>\nint main() {\nreturn 0;\n}")
add_executable(MyTest foo.cc)
add_unit_test(MyTest NAME SomeTest COMMAND $<TARGET_FILE:MyTest>)
add_executable(MyTest2 foo.cc)
add_unit_test(MyTest2 NAME SomeTest2 COMMAND $<TARGET_FILE:MyTest2>)