Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dependencies 科马克公司;CTest:使测试不';t构建测试_Dependencies_Cmake_Ctest - Fatal编程技术网

Dependencies 科马克公司;CTest:使测试不';t构建测试

Dependencies 科马克公司;CTest:使测试不';t构建测试,dependencies,cmake,ctest,Dependencies,Cmake,Ctest,我正在CMake中尝试CTest,以便使用maketesttarget自动运行一些测试。问题是CMake不“理解”我愿意运行的测试必须构建,因为它是项目的一部分 因此,我正在寻找一种明确指定这种依赖关系的方法。这可以说是一种(以前跟踪过的)不开箱即用的方法。解决方法是执行以下操作: add_test(TestName ExeName) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS

我正在CMake中尝试CTest,以便使用
maketest
target自动运行一些测试。问题是CMake不“理解”我愿意运行的测试必须构建,因为它是项目的一部分

因此,我正在寻找一种明确指定这种依赖关系的方法。

这可以说是一种(以前跟踪过的)不开箱即用的方法。解决方法是执行以下操作:

add_test(TestName ExeName)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
                  DEPENDS ExeName)

然后您可以运行
makecheck
,它将编译并运行测试。如果您有多个测试,那么您必须在上行中使用
dependens exe1 exe2 exe3…

实际上有一种方法可以使用
进行测试。您需要将测试可执行文件的构建定义为测试之一,然后在测试之间添加依赖项。即:

ADD_TEST(ctest_build_test_code
         "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target test_code)
ADD_TEST(ctest_run_test_code test_code)
SET_TESTS_PROPERTIES(ctest_run_test_code
                     PROPERTIES DEPENDS ctest_build_test_code)

以上所有答案都是完美的。但实际上,CMake使用CTest作为其测试工具,因此执行任务的标准方法(我认为是这样的)是:

enable_testing ()
add_test (TestName TestCommand)
add_test (TestName2 AnotherTestCommand)
然后运行cmakemake来构建目标。之后,您可以运行进行测试,也可以直接运行

ctest
你会得到结果的。这是在CMake 2.8下测试的


查看详情:

我使用richq答案的变体。在顶级的
CMakeLists.txt
中,我添加了一个自定义目标,
build_and_test
,用于构建和运行所有测试:

find_package(GTest)
if (GTEST_FOUND)
    enable_testing()
    add_custom_target(build_and_test ${CMAKE_CTEST_COMMAND} -V)
    add_subdirectory(test)
endif()
test/
下的各个子项目
CMakeLists.txt
文件中,我将每个测试可执行文件添加为
构建和测试的依赖项:

include_directories(${CMAKE_SOURCE_DIR}/src/proj1)
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(proj1_test proj1_test.cpp)
target_link_libraries(proj1_test ${GTEST_BOTH_LIBRARIES} pthread)
add_test(proj1_test proj1_test)
add_dependencies(build_and_test proj1_test)
使用这种方法,我只需要
makebuild\u and\u test
,而不是
maketest
(或
makeall test
),它的好处是只生成测试代码(及其依赖项)。很遗憾,我不能使用目标名称
test
。在我的例子中,这并不糟糕,因为我有一个顶级脚本,它通过调用
cmake
然后
make
来进行树外调试和发布(以及交叉编译)构建,它将
test
转换为
build\u和\u test

显然,不需要GTest的东西。我只是碰巧使用/喜欢GoogleTest,并想与CMake/CTest分享一个使用它的完整示例。IMHO,这种方法还有一个好处,就是允许我使用
ctest-V
,它在测试运行时显示Google测试输出:

1: Running main() from gtest_main.cc
1: [==========] Running 1 test from 1 test case.
1: [----------] Global test environment set-up.
1: [----------] 1 test from proj1
1: [ RUN      ] proj1.dummy
1: [       OK ] proj1.dummy (0 ms)
1: [----------] 1 test from proj1 (1 ms total)
1:
1: [----------] Global test environment tear-down
1: [==========] 1 test from 1 test case ran. (1 ms total)
1: [  PASSED  ] 1 test.
1/2 Test #1: proj1_test .......................   Passed    0.03 sec

如果您试图模拟
进行检查
,您可能会发现此wiki条目非常有用:


我刚刚检查了is是否成功地做到了它所说的(CMake 2.8.10)。

所有的答案都是好的,但它们意味着违反了传统,即通过命令运行测试
进行测试。我做了这个把戏:

add_test(NAME <mytest>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND sh -c "make <mytarget>; $<TARGET_FILE:<mytarget>>")
add_测试(名称
工作目录${CMAKE\u BINARY\u DIR}
命令sh-c“make;$”)

这意味着测试包括构建(可选)和运行可执行目标。

省去您自己的烦恼:

make all test

这对我来说是开箱即用的,并且将在运行测试之前构建依赖项。考虑到这是多么简单,它几乎使本机的
make test
功能变得非常方便,因为它让您可以选择运行最后的编译测试,即使您的代码已损坏。

这就是我一直在使用的:

set(${PROJECT_NAME}_TESTS a b c)

enable_testing()
add_custom_target(all_tests)
foreach(test ${${PROJECT_NAME}_TESTS})
        add_executable(${test} EXCLUDE_FROM_ALL ${test}.cc)
        add_test(NAME ${test} COMMAND $<TARGET_FILE:${test}>)
        add_dependencies(all_tests ${test})
endforeach(test)

build_command(CTEST_CUSTOM_PRE_TEST TARGET all_tests)
string(CONFIGURE \"@CTEST_CUSTOM_PRE_TEST@\" CTEST_CUSTOM_PRE_TEST_QUOTED ESCAPE_QUOTES)
file(WRITE "${CMAKE_BINARY_DIR}/CTestCustom.cmake" "set(CTEST_CUSTOM_PRE_TEST ${CTEST_CUSTOM_PRE_TEST_QUOTED})" "\n")
set(${PROJECT\u NAME}\u测试a b c)
启用_测试()
添加自定义目标(所有测试)
foreach(test${${PROJECT\u NAME}\u TESTS})
添加\u可执行文件(${test}从\u ALL${test}.cc中排除\u)
添加测试(名称${test}命令$)
添加_依赖项(所有_测试${test})
endforeach(测试)
build_命令(CTEST_CUSTOM_PRE_测试目标所有_测试)
字符串(配置\“@CTEST\u CUSTOM\u PRE\u TEST@”CTEST\u CUSTOM\u PRE\u TEST\u引号转义\u引号)
文件(写入“${CMAKE_BINARY_DIR}/CTestCustom.CMAKE”集合(CTEST_CUSTOM_PRE_TEST${CTEST_CUSTOM_PRE_TEST})”“\n”)

YMMV

如果您使用的是CMake>=3.7,则建议使用以下方法:

添加可执行文件(test.cpp) 添加测试(测试构建) “${CMAKE_COMMAND}” --生成“${CMAKE\u BINARY\u DIR}” --配置“$” --目标测试 ) 设置测试属性(测试构建属性夹具设置测试夹具) 添加测试(测试) 设置测试\u属性(测试属性夹具\u所需测试夹具)
这样做的目的如下:

add_test(TestName ExeName)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
                  DEPENDS ExeName)
  • 添加从
    test.cpp
  • 添加一个
    test\u build
    “test”,该测试运行Cmake以生成目标
    test
  • test\u build
    test标记为fixture的设置任务
    test\u fixture
  • 添加一个
    测试
    测试,该测试只运行
    测试
    可执行文件
  • 测试
    测试标记为需要夹具
    测试夹具

因此,每次运行test
test
时,它首先运行test
test\u build
,这将构建必要的可执行文件。

Derrick的答案经过简化和注释:

# It is impossible to make target "test" depend on "all":
# https://gitlab.kitware.com/cmake/cmake/-/issues/8774
# Set a magic variable in a magic file that tells ctest
# to invoke the generator once before running the tests:
file(WRITE "${CMAKE_BINARY_DIR}/CTestCustom.cmake"
    "set(CTEST_CUSTOM_PRE_TEST ${CMAKE_MAKE_PROGRAM})\n"
)
这并不完全正确,因为它不能解决运行
ninja-all-test
的并发问题,以防有人这样做。相反,因为现在,你有两个忍者进程


(Ftr,我也分享了这个解决方案。)

对于CMake 3.10或更高版本,另一个选项是使用directory属性设置脚本,在运行测试之前触发构建。在最外层的
CMakeLists.txt
中添加以下代码:

set_property(DIRECTORY APPEND
    PROPERTY TEST_INCLUDE_FILES "${CMAKE_CURRENT_BINARY_DIR}/BuildTestTarget.cmake")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/BuildTestTarget.cmake"
   "execute_process(COMMAND \"${CMAKE_COMMAND}\""
   " --build \"${CMAKE_BINARY_DIR}\""
   " --config \"\$ENV{CMAKE_CONFIG_TYPE}\")")

实际测试配置通过环境变量
CMAKE\u CONFIG\u TYPE
传递给构建。(可选)您可以添加一个选项,以仅生成测试所需的目标。

因此我猜“make test”目标将保持未使用状态,因为您似乎必须在add_custom_target命令中选择不同的目标名称?是的。“make test”和“make check”之间的唯一区别是前者首先显示“Running tests…”,而不检查任何构建依赖项。@rq-但我如何才能做到这一点