Существует ли метод кросс-компиляции для отключения флагов покрытия для тестовых исполняемых файлов, использующих CMake?

Я создаю общий C ++, CMake и Ловить шаблон проекта, который я планирую использовать в будущем, и хочу включить отчеты о покрытии кода для него. Для этого я решил добавить следующий модуль CMake в свой список модулей: CodeCoverage.cmake. Мое использование этого сводится к следующему фрагменту:

if (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Coverage in a non-debug build may lead to misleading results! Setting build type to 'Debug'!")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE)
endif (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")

include(CodeCoverage)
APPEND_COVERAGE_COMPILER_FLAGS()

if (NOT BUILD_TESTS)
message(STATUS "Tests must be enabled in a coverage build! Setting BUILD_TESTS to On!")
set(BUILD_TESTS On CACHE STRING "" FORCE)
endif (NOT BUILD_TESTS)

set(COVERAGE_EXCLUDES 'tests/*')

include(CodeCoverage)
APPEND_COVERAGE_COMPILER_FLAGS()

SETUP_TARGET_FOR_COVERAGE(NAME coverage EXECUTABLE tests DEPENDENCIES coverage)
else (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)
# ...
endif (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)

Подробности.

  • ENABLE_COVERAGE это флаг командной строки, который я использую для включения / выключения покрытия кода, которое будет сгенерировано с помощью lcov / gcov.
  • tests это имя моего исполняемого файла, который запускает все мои модульные тесты.
    Сначала я использую add_subdirectory чтобы добавить свою папку, и внутри папки, которую я использую:

    set(TEST_SOURCES test_hello_world.cpp test_factorial.cpp)
    
    add_executable(tests main.cpp ${TEST_SOURCES})
    target_link_libraries(tests Project-Name-lib)
    
    include(ParseAndAddCatchTests)
    ParseAndAddCatchTests(tests)
    

Моя проблема:

Когда я обычно бегаю make скрипт, код компилируется с легкостью, в том числе тестовый исполняемый файл, который занимает ~ 10 секунд для сборки. Однако, когда я включаю покрытие для своего кода, код застревает при построении main.cpp.o (Внутри tests), а также make никогда не заканчивается Когда я бегу make VERBOSE=1Я получаю следующую команду, которая выполняется для указанного объекта:

cd project_dir/build/tests && /usr/bin/g++-5
-g -O0 --coverage -fprofile-arcs -ftest-coverage -g -O0
--coverage -fprofile-arcs -ftest-coverage -g
-I/project_dir/include -I/project_dir/build
-std=c++14 -o CMakeFiles/tests.dir/main.cpp.o -c /project_dir/main.cpp

(Я сократил некоторые пути для удобства чтения и строки с отступом являются частью одной и той же команды)

Видимо, даже с set(COVERAGE_EXCLUDES 'tests/*')Компилятор еще добавление флагов покрытия к исполняемому файлу теста, который, я думаю, является источником медленного времени сборки. Если мой вывод верен, то как я могу сказать компилятору не добавить эти флаги в мой тестовый исполняемый файл? Если мой вывод неверен, то как я могу сократить время сборки этого исполняемого файла? (Я не хочу прямо упоминать имена флагов, поскольку это может работать не во всех компиляторах (под этим я подразумеваю GCC / Clang))

На заметку, мой main.cpp содержит:

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

И образец тестового файла содержит:

#include <project-abbr/factorial.hpp>
#include "catch.hpp"
TEST_CASE("function factorial")
{
SECTION("normal arguments")
{
REQUIRE(factorial(2) == 2);
REQUIRE(factorial(3) == 6);
REQUIRE(factorial(4) == 24);
REQUIRE(factorial(5) == 120);
}
}

0

Решение

ОБНОВИТЬ

Следующий код на самом деле не является решением. Оно работает только для всех функций, которые определены только в исходных файлах. Это означает, что если у вас есть библиотека шаблонов или библиотека только заголовков, то это решение совершенно бесполезно. Истинное решение является вызвать функцию append_coverage_compiler_flags что позволяет для полного охвата. Однако, это может привести к зависанию компиляции, как показано в посте ОП …


Хорошо, я немного поэкспериментировал, посмотрел документацию и нашел решение, которое не совсем оптимально, но, тем не менее, работает. Я использовал функцию target_compile_options добавить только флаги покрытия к нужным целям вместо функции ADD_COVERAGE_COMPILE_FLAGS() из модуля, следующим образом:

если (НЕ CMAKE_BUILD_TYPE STREQUAL "Debug")
сообщение (СОСТОЯНИЕ «Освещение в не отладочной сборке может привести к ошибочным результатам! Установка типа сборки на« Отладка »!»)
set (CMAKE_BUILD_TYPE "Отладка" CACHE STRING "" FORCE)
endif (НЕ CMAKE_BUILD_TYPE STREQUAL "Отладка")

включают в себя (покрытие кода)

если (НЕ BUILD_TESTS)
сообщение (СОСТОЯНИЕ "Тесты должны быть включены в сборку покрытия! Установка BUILD_TESTS на Вкл!")
set (BUILD_TESTS On CACHE STRING "" FORCE)
endif (НЕ BUILD_TESTS)

набор (COVERAGE_EXCLUDES 'тесты / *')

включают в себя (покрытие кода)

include_directories (включая $ {PROJECT_BINARY_DIR})
add_subdirectory (SRC)

target_compile_options (Project-Name-lib PRIVATE "--coverage")
target_compile_options (Project-Name PRIVATE "--coverage")

SETUP_TARGET_FOR_COVERAGE (покрытие NAME EXECUTABLE тестирует покрытие DEPENDENCIES)

Существует предостережение для этого решения. Судя по всему, файлы заголовков не включены в покрытие кода …

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector