这里有一个自包含的示例,展示了如何将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
要使用 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的内置测试目标无法修改,并且始终以常规方式运行测试。但是,我们可以添加一个自定义的CMake目标,该目标使用-T memcheck
选项调用ctest,然后打印详细的valgrind报告:
add_custom_target(test_memcheck
COMMAND ${CMAKE_CTEST_COMMAND}
--force-new-ctest-process --test-action memcheck
COMMAND ${CMAKE_COMMAND} -E cat "${CMAKE_BINARY_DIR}/Testing/Temporary/MemoryChecker.*.log"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
--test-action
是开关 -T
的冗长版本。
然后我们可以通过 Ninja 调用 valgrind 进行测试:
$ ninja test_memcheck
并且以我们手动运行valgrind的方式获取结果。
ctest_memcheck
命令,参考链接:https://cmake.org/cmake/help/v3.7/command/ctest_memcheck.html#command:ctest_memcheck 和 https://cmake.org/cmake/help/v3.7/manual/ctest.1.html?highlight=valgrind#ctest-memcheck-step。 - usr1234567