#c #cmake #gcov
#c #cmake #gcov
Вопрос:
Я изо всех сил пытаюсь получить информацию о покрытии для gcov. Никаких ошибок во время компиляции и компоновки, но когда я запускаю исполняемый файл, данные о покрытии не создаются.
Я использую CMake с отдельным каталогом сборки, передавая флаги компилятору и компоновщику таким образом:
add_definitions(--coverage)
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} " --coverage")
Ожидает ли исполняемый файл, что исходный код будет находиться в определенном месте?
Что я должен добавить к своему CMakeLists.txt чтобы все пошло своим чередом?
С уважением, Бьорн
Ответ №1:
CMake, похоже, помещает файлы покрытия кода (*.gcda, *.gcdo) в объектные файлы вашего проекта. Если бы ваш исполняемый файл был назван «tester», то они отображались бы по следующему пути
${CMAKE_BINARY_DIR}/CMakeFiles/tester.dir/
CMake, похоже, называет исходные файлы способом, который не очень совместим с gcov. Например, если бы у меня был исходный файл под названием «mytestprog.cpp «это была бы сборка
mytestprog.cpp.o
mytestprog.cpp.gcda
mytestprog.cpp.gcdno
где, как gcov, кажется, ожидает
mytestprog.gcda
mytestprog.gcdno
Я не совсем уверен, как это исправить. Я пытался использовать вместо этого LCov, и это «казалось», сработало, но я не совсем уверен, сработало ли это.
Комментарии:
1. по какой-то причине вы можете получить информацию профиля, указав только объектные файлы и передав фиктивное значение в качестве исходного файла. Например:
gcov -o mytestprog.cpp.o x
создастmytestprog.cpp.gcov
.2. @bcmpinc, однако, он не сможет проверить заголовки, которые вы использовали в этом файле.
Ответ №2:
Delcypher указал на проблему.
Решение 1: вы можете попросить cmake
называть объектные файлы как main.o
вместо main.cpp.o
и т.д., Используя недокументированный CMAKE_CXX_OUTPUT_EXTENSION_REPLACE
переключатель:
cmake -DCMAKE_CXX_OUTPUT_EXTENSION_REPLACE=ON ...
Решение 2: если вам не нужны .gcov
файлы, которые вы можете вызвать lcov
из каталога сборки:
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory out
В out
каталоге вы найдете информацию о покрытии в форме html.
Ответ №3:
Не уверен, откуда вы взяли --coverage
, но это аргументы, которые я использую в Linux для получения информации о покрытии с использованием gcc и gcov:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS
"${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
Вот что gcc --help --verbose
можно сказать об этих параметрах:
-ftest-coverage Создает файлы данных, необходимые «gcov»
-fprofile-arcs Вставить код профилирования программы на основе arc
Комментарии:
1. При использовании Clang
--coverage
выполняет то же, что и эти два аргумента, в более коротком формате.2.GCC поддерживает
--coverage
gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html
Ответ №4:
Вам не нужно передавать —coverage компоновщику. —coverage передаст -fprofile-arcs -ftest-coverage компилятору и -lgcov компоновщику.
Вы уверены, что при этом не создаются какие-либо файлы gcdo или gcda? Где вы ищете эти файлы? Он должен поместить файл gcov для каждого объектного файла в тот же каталог, что и объектный файл. Найдите файлы .gcda в верхней части вашего каталога сборки. Если ничего не отображается, возможно, gcov не подключается. Запустите следующую команду, чтобы проверить, является ли это:
nm name_of_binary | grep "gcov"
Если он подключается, у gcov может не быть разрешения на запись файлов, в которые вы запускаете исполняемый файл. Если у него есть разрешение, то я в тупике.