diff options
Diffstat (limited to 'project')
-rw-r--r-- | project/cmake/CMakeLists.txt | 9 | ||||
-rw-r--r-- | project/cmake/README.md | 6 | ||||
-rw-r--r-- | project/cmake/scripts/linux/ArchSetup.cmake | 8 | ||||
-rw-r--r-- | project/cmake/scripts/linux/CodeCoverage.cmake | 97 | ||||
-rw-r--r-- | project/cmake/scripts/linux/Macros.cmake | 8 |
5 files changed, 127 insertions, 1 deletions
diff --git a/project/cmake/CMakeLists.txt b/project/cmake/CMakeLists.txt index e209ed9791..7017a9bf21 100644 --- a/project/cmake/CMakeLists.txt +++ b/project/cmake/CMakeLists.txt @@ -358,6 +358,15 @@ if(NOT CMAKE_CROSSCOMPILING) -DCMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}) endif() +# code coverage +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + if(EXISTS ${PROJECT_SOURCE_DIR}/scripts/${CORE_SYSTEM_NAME}/CodeCoverage.cmake) + include(${PROJECT_SOURCE_DIR}/scripts/${CORE_SYSTEM_NAME}/CodeCoverage.cmake) + else() + message(FATAL_ERROR "Code coverage not (yet) implemented for platform ${CORE_SYSTEM_NAME}") + endif() +endif() + # link wrapper if(FFMPEG_LINK_EXECUTABLE) set(CMAKE_CXX_LINK_EXECUTABLE "${FFMPEG_LINK_EXECUTABLE}") diff --git a/project/cmake/README.md b/project/cmake/README.md index fafd07885a..2ac01f1689 100644 --- a/project/cmake/README.md +++ b/project/cmake/README.md @@ -152,6 +152,12 @@ When using the makefile builds a few extra targets are defined: - `make check` builds and executes the test suite. +Code coverage (with Gcov, LCOV and Gcovr) can be built on Linux: + +- CMake has to be executed with `-DCMAKE_BUILD_TYPE=Coverage` +- `make coverage` generates an HTML code coverage report. +- `make coverage_xml` generates an XML code coverage report. + ## Sanitizers Clang and GCC support different kinds of Sanitizers. To enable a Sanitizer call CMake with the diff --git a/project/cmake/scripts/linux/ArchSetup.cmake b/project/cmake/scripts/linux/ArchSetup.cmake index e2adf5bb3b..09675f19b2 100644 --- a/project/cmake/scripts/linux/ArchSetup.cmake +++ b/project/cmake/scripts/linux/ArchSetup.cmake @@ -22,3 +22,11 @@ if(ENABLE_LIRC) set(LIRC_DEVICE "\"/dev/lircd\"" CACHE STRING "LIRC device to use") set(DEP_DEFINES -DLIRC_DEVICE=${LIRC_DEVICE} -DHAVE_LIRC=1) endif() + +# Code Coverage +if(CMAKE_BUILD_TYPE STREQUAL Coverage) + set(COVERAGE_TEST_BINARY ${APP_NAME_LC}-test) + set(COVERAGE_SOURCE_DIR ${CORE_SOURCE_DIR}) + set(COVERAGE_DEPENDS "\${APP_NAME_LC}" "\${APP_NAME_LC}-test") + set(COVERAGE_EXCLUDES */test/* lib/* */lib/*) +endif() diff --git a/project/cmake/scripts/linux/CodeCoverage.cmake b/project/cmake/scripts/linux/CodeCoverage.cmake new file mode 100644 index 0000000000..efc2208b07 --- /dev/null +++ b/project/cmake/scripts/linux/CodeCoverage.cmake @@ -0,0 +1,97 @@ +# - CodeCoverage +# Generate code coverage reports with LCOV and GCovr. +# +# Configuration: +# COVERAGE_SOURCE_DIR - Source root directory (default ${CMAKE_SOURCE_DIR}). +# COVERAGE_BINARY_DIR - Directory where the coverage reports (and intermediate files) +# are generated to. +# COVERAGE_EXCLUDES - List of exclude patterns (for example '*/tests/*'). +# +# The following targets will be generated: +# coverage - Builds an html report. Requires LCOV. +# coverage_xml - Builds an xml report (in Cobertura format for Jenkins). +# Requires Gcovr. +# +# Inspired by https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake + +# Comiler and linker setup +set(CMAKE_C_FLAGS_COVERAGE "-g -O0 --coverage" CACHE STRING + "Flags used by the C compiler during coverage builds." FORCE) +set(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 --coverage" CACHE STRING + "Flags used by the C++ compiler during coverage builds." FORCE) +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING + "Flags used for linking binaries during coverage builds." FORCE) +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage" CACHE STRING + "Flags used by the shared libraries linker during coverage builds." FORCE) +mark_as_advanced( + CMAKE_C_FLAGS_COVERAGE CMAKE_CXX_FLAGS_COVERAGE CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE CMAKE_STATIC_LINKER_FLAGS_COVERAGE +) + +find_program(LCOV_EXECUTABLE lcov) +find_program(GENINFO_EXECUTABLE geninfo) +find_program(GENHTML_EXECUTABLE genhtml) +find_program(GCOVR_EXECUTABLE gcovr) +mark_as_advanced(LCOV_EXECUTABLE GENINFO_EXECUTABLE GENHTML_EXECUTABLE GCOVR_EXECUTABLE) + +# Default options +if(NOT COVERAGE_SOURCE_DIR) + set(COVERAGE_SOURCE_DIR ${CMAKE_SOURCE_DIR}) +endif() +if(NOT COVERAGE_BINARY_DIR) + set(COVERAGE_BINARY_DIR ${CMAKE_BINARY_DIR}/coverage) +endif() +if(NOT COVERAGE_EXCLUDES) + set(COVERAGE_EXCLUDES) +endif() + +# Allow variables in COVERAGE_DEPENDS that are not evaluated before this file is included. +string(CONFIGURE "${COVERAGE_DEPENDS}" COVERAGE_DEPENDS) + +# Add coverage target that generates an HTML report using LCOV +if(LCOV_EXECUTABLE AND GENINFO_EXECUTABLE AND GENHTML_EXECUTABLE) + file(MAKE_DIRECTORY ${COVERAGE_BINARY_DIR}) + add_custom_target(coverage + COMMAND ${CMAKE_COMMAND} -E make_directory ${COVERAGE_BINARY_DIR} + COMMAND ${LCOV_EXECUTABLE} -z -q -d ${CMAKE_BINARY_DIR} + COMMAND ${LCOV_EXECUTABLE} -c -q -i -d ${CMAKE_BINARY_DIR} -b ${COVERAGE_SOURCE_DIR} + -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_base.info + COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test || true + COMMAND ${LCOV_EXECUTABLE} -c -q -d ${CMAKE_BINARY_DIR} -b ${COVERAGE_SOURCE_DIR} + -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_test.info + COMMAND ${LCOV_EXECUTABLE} -a ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_base.info + -a ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage_test.info + -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info -q + COMMAND ${LCOV_EXECUTABLE} -q -r ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info + /usr/include/* ${CMAKE_BINARY_DIR}/* ${COVERAGE_EXCLUDES} + -o ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info + COMMAND ${GENHTML_EXECUTABLE} ${COVERAGE_BINARY_DIR}/${PROJECT_NAME}.coverage.info + -o ${COVERAGE_BINARY_DIR}/html -s --legend --highlight --demangle-cpp + COMMAND ${CMAKE_COMMAND} -E echo "Coverage report: file://${COVERAGE_BINARY_DIR}/html/index.html" + WORKING_DIRECTORY ${COVERAGE_BINARY_DIR} + VERBATIM + DEPENDS ${COVERAGE_DEPENDS} + COMMENT "Generate code coverage html report" + ) +else() + message(WARNING "Target coverage not available (lcov, geninfo and genhtml needed).") +endif() + +# Add coverage target that generates an XML report using Gcovr +if(GCOVR_EXECUTABLE) + file(MAKE_DIRECTORY ${COVERAGE_BINARY_DIR}) + string(REGEX REPLACE "([^;]+)" "--exclude=\"\\1\"" _gcovr_excludes "${COVERAGE_EXCLUDES}") + string(REPLACE "*" ".*" _gcovr_excludes "${_gcovr_excludes}") + add_custom_target(coverage_xml + COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target test || true + COMMAND ${GCOVR_EXECUTABLE} -x -r ${COVERAGE_SOURCE_DIR} -o ${COVERAGE_BINARY_DIR}/coverage.xml + --object-directory ${CMAKE_BINARY_DIR} ${_gcovr_excludes} ${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E echo "Coverage report: file://${COVERAGE_BINARY_DIR}/coverage.xml" + WORKING_DIRECTORY ${COVERAGE_BINARY_DIR} + DEPENDS ${COVERAGE_DEPENDS} + COMMENT "Generate code coverage xml report" + ) + unset(_gcovr_excludes) +else() + message(WARNING "Target coverage_xml not available (gcovr needed).") +endif() diff --git a/project/cmake/scripts/linux/Macros.cmake b/project/cmake/scripts/linux/Macros.cmake index 7453a1c03d..9d8c00a984 100644 --- a/project/cmake/scripts/linux/Macros.cmake +++ b/project/cmake/scripts/linux/Macros.cmake @@ -14,8 +14,14 @@ function(core_link_library lib wraplib) set(check_arg ${ARGV3}) set(data_arg ${ARGV4}) endif() + + # wrapper has to be adapted in order to support coverage. + if(CMAKE_BUILD_TYPE STREQUAL Coverage) + set(export "") + endif() + if(check_arg STREQUAL export) - set(export ${export} + set(export ${export} -Wl,--version-script=${ARGV3}) elseif(check_arg STREQUAL nowrap) set(export ${data_arg}) |