gcov с CMake с использованием отдельного каталога сборки

#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 может не быть разрешения на запись файлов, в которые вы запускаете исполняемый файл. Если у него есть разрешение, то я в тупике.