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

How do I add valgrind tests to my cmake "test" target

我 运行 通过使用 ninja 进行构建然后从我的构建树 运行ning ninja test 进行单元测试:

cmake -G Ninja /source/tree
ninja
ninja test

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

valgrind rel/path/to/test

我想在 运行 ninja test 时自动 valgrind 到 运行。 According to the cmake documentation"setting up [valgrind tests] is extremely easy",但是当我运行

ctest -D NightlyMemoryCheck

我刚收到这个错误:

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.

当我按照这个 SO 问题的说明操作时,我遇到了类似的错误:

How do I make ctest run a program with valgrind without dart?

我不知道 dart 是什么,但根据该网站,它是某种在线测试工具。

显然 非常简单 对我来说还不够简单。有谁知道一个非常简单的解决方案,以至于您必须是某种 IT 术士才能使它有效?

这是一个独立的示例,展示了如何将 valgrind 测试添加到 CMake 项目。该示例由单个 C++ 源文件组成 main.cpp:

#include <iostream>

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

代码包含故意泄漏,应由 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)

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

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

$ mkdir build; cd build
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..

我们可以构建和 运行 测试 而无需 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

为了 运行 测试 with 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

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)
...

当你 运行 ninja test 时无法自动 运行 valgrind 因为 CMake 的内置测试目标无法修改并且总是 运行s 测试在常规方式。然而,我们可以添加一个自定义 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"
    WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")

--test-action 是开关 -T.

的详细版本

然后我们可以使用

从 Ninja 调用 valgrind 测试
$ ninja test_memcheck

并像我们手动 运行 valgrind 一样得到结果。