如何将valgrind测试添加到我的cmake"test"目标中

qua*_*ant 20 c++ valgrind cmake

我通过构建,ninja然后ninja test从我的构建树运行来运行单元测试:

cmake -G Ninja /source/tree
ninja
ninja test
Run Code Online (Sandbox Code Playgroud)

但是,要运行valgrind,我需要手动运行它:

valgrind rel/path/to/test
Run Code Online (Sandbox Code Playgroud)

我想valgrind在跑步时自动跑步ninja test.根据cmake文档 "设置[valgrind测试] 非常容易 ",但是当我运行时

ctest -D NightlyMemoryCheck
Run Code Online (Sandbox Code Playgroud)

我刚收到这个错误:

Cannot find file: /home/arman/tinman/deb/DartConfiguration.tcl
   Site: 
   Build name: (empty)
WARNING: No nightly start time found please set in CTestConfig.cmake or DartConfig.cmake
Problem initializing the dashboard.
Run Code Online (Sandbox Code Playgroud)

当我遵循此SO问题的说明时,我收到类似的错误:

如何让ctest用valgrind运行一个没有dart的程序?

我不知道是什么dart,但根据网站它是某种在线测试doodad.

对我来说,显然非常容易.有谁知道一个解决方案,使超级容易,你就必须是某种IT术士,使它的不是工作?

sak*_*kra 36

这是一个自包含的示例,演示如何将valgrind测试添加到CMake项目.该示例包含单个C++源文件main.cpp:

#include <iostream>

int main()
{
    double* leak = new double[10];
    std::cout << "Hello!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

该代码包含故意泄漏,应该由valgrind接收.我们还需要一个CMakeLists.txt需要CMake> = 2.8 的文件:

cmake_minimum_required(VERSION 2.8)

project (ValgrindExample)

include (CTest)
add_executable(example main.cpp)
add_test(example_test example)
Run Code Online (Sandbox Code Playgroud)

这里包含CTest模块非常重要,include而不仅仅是启用测试enable_testing().CTest模块负责设置机器,以便能够通过测试运行内存检查(例如,它定位valgrind可执行文件).

现在我们可以在项目文件夹中打开一个shell会话并创建一个Ninja构建树:

$ mkdir build; cd build
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
Run Code Online (Sandbox Code Playgroud)

我们可以以常规方式构建和运行没有 valgrind的测试:

$ ninja
[2/2] Linking CXX executable example
$ ninja test
[0/1] Running tests...
...
100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.01 sec
Run Code Online (Sandbox Code Playgroud)

使用 valgrind 运行测试,我们必须使用CMake的ctest可执行文件和测试操作memcheck:

$ ctest -T memcheck
...
1/1 MemCheck #1: example_test .....................   Passed    0.77 sec

100% tests passed, 0 tests failed out of 1

Total Test time (real) =   0.77 sec
-- Processing memory checking output: 
Memory checking results:
Memory Leak - 2
Run Code Online (Sandbox Code Playgroud)

ctest打印内存检查结果的摘要.valgrind的详细输出位于构建树中的临时目录中:

$ cat ./Testing/Temporary/MemoryChecker.*.log
==4565== 80 bytes in 1 blocks are definitely lost in loss record 37 of 64
==4565==    at 0x10000B681: malloc (in /usr/local/Cellar/valgrind/3.12.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==4565==    by 0x1000507DD: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==4565==    by 0x100000F93: main (main.cpp:5)
...
Run Code Online (Sandbox Code Playgroud)

运行时无法自动运行valgrind,ninja test因为无法修改CMake的内置测试目标并始终以常规方式运行测试.但是,我们可以添加一个自定义CMake目标,该目标使用该-T memcheck选项调用ctest,然后打印详细的valgrind报告:

add_custom_target(test_memcheck
    COMMAND ${CMAKE_CTEST_COMMAND} 
        --force-new-ctest-process --test-action memcheck
    COMMAND cat "${CMAKE_BINARY_DIR}/Testing/Temporary/MemoryChecker.*.log")
Run Code Online (Sandbox Code Playgroud)

--test-action是交换机的冗长版本-T.

然后我们可以从Ninja调用valgrind测试

$ ninja test_memcheck
Run Code Online (Sandbox Code Playgroud)

并获得结果,就像我们手动运行valgrind一样.

  • 如何仅在 valgrind 检查失败时才捕获 valgrind 日志?如何以-1退出? (2认同)
  • @sakra如何设置`CTEST_MEMORYCHECK_SUPPRESSIONS_FILE`变量?我尝试使用`-D`选项进行测试,但这似乎无济于事。有任何想法吗?我确实希望能够在运行ctest时从命令行设置抑制文件和memcheck选项。 (2认同)