Ответ 1
Вот пример, который показывает, как добавлять тесты valgrind в проект CMake. Пример состоит из одного исходного файла С++ 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)
Здесь важно включить модуль CTest с include
вместо того, чтобы включать тесты с enable_testing()
. Модуль CTest позаботится о настройке оборудования для возможности проверки памяти с помощью тестов (например, он находит исполняемый файл valgrind).
Теперь мы можем открыть сеанс оболочки в папке проекта и создать дерево сборки 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)
...
Невозможно автоматически запустить valgrind при запуске ninja test
, потому что встроенная тестовая цель CMake не может быть изменена и всегда запускает тесты обычным способом. Однако мы можем добавить пользовательскую цель CMake, которая вызывает ctest с опцией -T memcheck
, а затем печатает подробный отчет 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")
--test-action
является вербальной версией коммутатора -T
.
Затем мы можем вызвать тестирование valgrind от Ninja с помощью
$ ninja test_memcheck
и получите результаты, как если бы мы выполнили команду valgrind вручную.