mirror of
https://github.com/XRPLF/rippled.git
synced 2026-02-13 02:12:31 +00:00
For coverage builds, we try to link against the `gcov` library (specific to the environment). But as macOS doesn't have this library and thus doesn't have the coverage tools to generate reports, the coverage builds on that platform were failing on linking. We actually don't need to explicitly force this linking, as the `CodeCoverage` file already has correct detection logic (currently on lines 177-193), which is invoked when the `--coverage` flag is provided: * AppleClang: Uses `xcrun -f llvm-cov` to set `GCOV_TOOL="llvm-cov gcov"`. * Clang: Finds `llvm-cov` to set `GCOV_TOOL="llvm-cov gcov"`. * GCC: Finds `gcov` to set `GCOV_TOOL="gcov"`. The `GCOV_TOOL` is then passed to `gcovr` on line 416, so the correct tool is used for processing coverage data. This change therefore removes the `gcov` suffix from lines 473 and 475 in the `CodeCoverage.cmake` file.
472 lines
21 KiB
CMake
472 lines
21 KiB
CMake
# Copyright (c) 2012 - 2017, Lars Bilke
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without modification,
|
|
# are permitted provided that the following conditions are met:
|
|
#
|
|
# 1. Redistributions of source code must retain the above copyright notice, this
|
|
# list of conditions and the following disclaimer.
|
|
#
|
|
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
# this list of conditions and the following disclaimer in the documentation
|
|
# and/or other materials provided with the distribution.
|
|
#
|
|
# 3. Neither the name of the copyright holder nor the names of its contributors
|
|
# may be used to endorse or promote products derived from this software without
|
|
# specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
# CHANGES:
|
|
#
|
|
# 2012-01-31, Lars Bilke
|
|
# - Enable Code Coverage
|
|
#
|
|
# 2013-09-17, Joakim Söderberg
|
|
# - Added support for Clang.
|
|
# - Some additional usage instructions.
|
|
#
|
|
# 2016-02-03, Lars Bilke
|
|
# - Refactored functions to use named parameters
|
|
#
|
|
# 2017-06-02, Lars Bilke
|
|
# - Merged with modified version from github.com/ufz/ogs
|
|
#
|
|
# 2019-05-06, Anatolii Kurotych
|
|
# - Remove unnecessary --coverage flag
|
|
#
|
|
# 2019-12-13, FeRD (Frank Dana)
|
|
# - Deprecate COVERAGE_LCOVR_EXCLUDES and COVERAGE_GCOVR_EXCLUDES lists in favor
|
|
# of tool-agnostic COVERAGE_EXCLUDES variable, or EXCLUDE setup arguments.
|
|
# - CMake 3.4+: All excludes can be specified relative to BASE_DIRECTORY
|
|
# - All setup functions: accept BASE_DIRECTORY, EXCLUDE list
|
|
# - Set lcov basedir with -b argument
|
|
# - Add automatic --demangle-cpp in lcovr, if 'c++filt' is available (can be
|
|
# overridden with NO_DEMANGLE option in setup_target_for_coverage_lcovr().)
|
|
# - Delete output dir, .info file on 'make clean'
|
|
# - Remove Python detection, since version mismatches will break gcovr
|
|
# - Minor cleanup (lowercase function names, update examples...)
|
|
#
|
|
# 2019-12-19, FeRD (Frank Dana)
|
|
# - Rename Lcov outputs, make filtered file canonical, fix cleanup for targets
|
|
#
|
|
# 2020-01-19, Bob Apthorpe
|
|
# - Added gfortran support
|
|
#
|
|
# 2020-02-17, FeRD (Frank Dana)
|
|
# - Make all add_custom_target()s VERBATIM to auto-escape wildcard characters
|
|
# in EXCLUDEs, and remove manual escaping from gcovr targets
|
|
#
|
|
# 2021-01-19, Robin Mueller
|
|
# - Add CODE_COVERAGE_VERBOSE option which will allow to print out commands which are run
|
|
# - Added the option for users to set the GCOVR_ADDITIONAL_ARGS variable to supply additional
|
|
# flags to the gcovr command
|
|
#
|
|
# 2020-05-04, Mihchael Davis
|
|
# - Add -fprofile-abs-path to make gcno files contain absolute paths
|
|
# - Fix BASE_DIRECTORY not working when defined
|
|
# - Change BYPRODUCT from folder to index.html to stop ninja from complaining about double defines
|
|
#
|
|
# 2021-05-10, Martin Stump
|
|
# - Check if the generator is multi-config before warning about non-Debug builds
|
|
#
|
|
# 2022-02-22, Marko Wehle
|
|
# - Change gcovr output from -o <filename> for --xml <filename> and --html <filename> output respectively.
|
|
# This will allow for Multiple Output Formats at the same time by making use of GCOVR_ADDITIONAL_ARGS, e.g. GCOVR_ADDITIONAL_ARGS "--txt".
|
|
#
|
|
# 2022-09-28, Sebastian Mueller
|
|
# - fix append_coverage_compiler_flags_to_target to correctly add flags
|
|
# - replace "-fprofile-arcs -ftest-coverage" with "--coverage" (equivalent)
|
|
#
|
|
# 2024-01-04, Bronek Kozicki
|
|
# - remove setup_target_for_coverage_lcov (slow) and setup_target_for_coverage_fastcov (no support for Clang)
|
|
# - fix Clang support by adding find_program( ... llvm-cov )
|
|
# - add Apple Clang support by adding execute_process( COMMAND xcrun -f llvm-cov ... )
|
|
# - add CODE_COVERAGE_GCOV_TOOL to explicitly select gcov tool and disable find_program
|
|
# - replace both functions setup_target_for_coverage_gcovr_* with a single setup_target_for_coverage_gcovr
|
|
# - add support for all gcovr output formats
|
|
#
|
|
# 2024-04-03, Bronek Kozicki
|
|
# - add support for output formats: jacoco, clover, lcov
|
|
#
|
|
# 2025-05-12, Jingchen Wu
|
|
# - add -fprofile-update=atomic to ensure atomic profile generation
|
|
#
|
|
# 2025-08-28, Bronek Kozicki
|
|
# - fix "At least one COMMAND must be given" CMake warning from policy CMP0175
|
|
#
|
|
# 2025-09-03, Jingchen Wu
|
|
# - remove the unused function append_coverage_compiler_flags and append_coverage_compiler_flags_to_target
|
|
# - add a new function add_code_coverage_to_target
|
|
# - remove some unused code
|
|
#
|
|
# 2025-11-11, Bronek Kozicki
|
|
# - make EXECUTABLE and EXECUTABLE_ARGS optional
|
|
#
|
|
# USAGE:
|
|
#
|
|
# 1. Copy this file into your cmake modules path.
|
|
#
|
|
# 2. Add the following line to your CMakeLists.txt (best inside an if-condition
|
|
# using a CMake option() to enable it just optionally):
|
|
# include(CodeCoverage)
|
|
#
|
|
# 3. Append necessary compiler flags and linker flags for all supported source files:
|
|
# add_code_coverage_to_target(<target> <PRIVATE|PUBLIC|INTERFACE>)
|
|
#
|
|
# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og
|
|
#
|
|
# 4. If you need to exclude additional directories from the report, specify them
|
|
# using full paths in the COVERAGE_EXCLUDES variable before calling
|
|
# setup_target_for_coverage_*().
|
|
# Example:
|
|
# set(COVERAGE_EXCLUDES
|
|
# '${PROJECT_SOURCE_DIR}/src/dir1/*'
|
|
# '/path/to/my/src/dir2/*')
|
|
# Or, use the EXCLUDE argument to setup_target_for_coverage_*().
|
|
# Example:
|
|
# setup_target_for_coverage_gcovr(
|
|
# NAME coverage
|
|
# EXECUTABLE testrunner
|
|
# EXCLUDE "${PROJECT_SOURCE_DIR}/src/dir1/*" "/path/to/my/src/dir2/*")
|
|
#
|
|
# 4.a NOTE: With CMake 3.4+, COVERAGE_EXCLUDES or EXCLUDE can also be set
|
|
# relative to the BASE_DIRECTORY (default: PROJECT_SOURCE_DIR)
|
|
# Example:
|
|
# set(COVERAGE_EXCLUDES "dir1/*")
|
|
# setup_target_for_coverage_gcovr(
|
|
# NAME coverage
|
|
# EXECUTABLE testrunner
|
|
# FORMAT html-details
|
|
# BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src"
|
|
# EXCLUDE "dir2/*")
|
|
#
|
|
# 4.b If you need to pass specific options to gcovr, specify them in
|
|
# GCOVR_ADDITIONAL_ARGS variable.
|
|
# Example:
|
|
# set (GCOVR_ADDITIONAL_ARGS --exclude-throw-branches --exclude-noncode-lines -s)
|
|
# setup_target_for_coverage_gcovr(
|
|
# NAME coverage
|
|
# EXECUTABLE testrunner
|
|
# EXCLUDE "src/dir1" "src/dir2")
|
|
#
|
|
# 5. Use the functions described below to create a custom make target which
|
|
# runs your test executable and produces a code coverage report.
|
|
#
|
|
# 6. Build a Debug build:
|
|
# cmake -DCMAKE_BUILD_TYPE=Debug ..
|
|
# make
|
|
# make my_coverage_target
|
|
|
|
include(CMakeParseArguments)
|
|
|
|
option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE)
|
|
|
|
# Check prereqs
|
|
find_program(GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
|
|
|
|
if (DEFINED CODE_COVERAGE_GCOV_TOOL)
|
|
set(GCOV_TOOL "${CODE_COVERAGE_GCOV_TOOL}")
|
|
elseif (DEFINED ENV{CODE_COVERAGE_GCOV_TOOL})
|
|
set(GCOV_TOOL "$ENV{CODE_COVERAGE_GCOV_TOOL}")
|
|
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
if (APPLE)
|
|
execute_process(COMMAND xcrun -f llvm-cov OUTPUT_VARIABLE LLVMCOV_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
else ()
|
|
find_program(LLVMCOV_PATH llvm-cov)
|
|
endif ()
|
|
if (LLVMCOV_PATH)
|
|
set(GCOV_TOOL "${LLVMCOV_PATH} gcov")
|
|
endif ()
|
|
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
|
|
find_program(GCOV_PATH gcov)
|
|
set(GCOV_TOOL "${GCOV_PATH}")
|
|
endif ()
|
|
|
|
# Check supported compiler (Clang, GNU and Flang)
|
|
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
|
foreach (LANG ${LANGUAGES})
|
|
if ("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
|
if ("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3)
|
|
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
|
|
endif ()
|
|
elseif (NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU" AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES
|
|
"(LLVM)?[Ff]lang")
|
|
message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...")
|
|
endif ()
|
|
endforeach ()
|
|
|
|
set(COVERAGE_COMPILER_FLAGS "-g --coverage" CACHE INTERNAL "")
|
|
|
|
set(COVERAGE_CXX_COMPILER_FLAGS "")
|
|
set(COVERAGE_C_COMPILER_FLAGS "")
|
|
set(COVERAGE_CXX_LINKER_FLAGS "")
|
|
set(COVERAGE_C_LINKER_FLAGS "")
|
|
|
|
if (CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
|
include(CheckCXXCompilerFlag)
|
|
include(CheckCCompilerFlag)
|
|
include(CheckLinkerFlag)
|
|
|
|
set(COVERAGE_CXX_COMPILER_FLAGS ${COVERAGE_COMPILER_FLAGS})
|
|
set(COVERAGE_C_COMPILER_FLAGS ${COVERAGE_COMPILER_FLAGS})
|
|
set(COVERAGE_CXX_LINKER_FLAGS ${COVERAGE_COMPILER_FLAGS})
|
|
set(COVERAGE_C_LINKER_FLAGS ${COVERAGE_COMPILER_FLAGS})
|
|
|
|
check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path)
|
|
if (HAVE_cxx_fprofile_abs_path)
|
|
set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-abs-path")
|
|
endif ()
|
|
|
|
check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path)
|
|
if (HAVE_c_fprofile_abs_path)
|
|
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_C_COMPILER_FLAGS} -fprofile-abs-path")
|
|
endif ()
|
|
|
|
check_linker_flag(CXX -fprofile-abs-path HAVE_cxx_linker_fprofile_abs_path)
|
|
if (HAVE_cxx_linker_fprofile_abs_path)
|
|
set(COVERAGE_CXX_LINKER_FLAGS "${COVERAGE_CXX_LINKER_FLAGS} -fprofile-abs-path")
|
|
endif ()
|
|
|
|
check_linker_flag(C -fprofile-abs-path HAVE_c_linker_fprofile_abs_path)
|
|
if (HAVE_c_linker_fprofile_abs_path)
|
|
set(COVERAGE_C_LINKER_FLAGS "${COVERAGE_C_LINKER_FLAGS} -fprofile-abs-path")
|
|
endif ()
|
|
|
|
check_cxx_compiler_flag(-fprofile-update=atomic HAVE_cxx_fprofile_update)
|
|
if (HAVE_cxx_fprofile_update)
|
|
set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-update=atomic")
|
|
endif ()
|
|
|
|
check_c_compiler_flag(-fprofile-update=atomic HAVE_c_fprofile_update)
|
|
if (HAVE_c_fprofile_update)
|
|
set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_C_COMPILER_FLAGS} -fprofile-update=atomic")
|
|
endif ()
|
|
|
|
check_linker_flag(CXX -fprofile-update=atomic HAVE_cxx_linker_fprofile_update)
|
|
if (HAVE_cxx_linker_fprofile_update)
|
|
set(COVERAGE_CXX_LINKER_FLAGS "${COVERAGE_CXX_LINKER_FLAGS} -fprofile-update=atomic")
|
|
endif ()
|
|
|
|
check_linker_flag(C -fprofile-update=atomic HAVE_c_linker_fprofile_update)
|
|
if (HAVE_c_linker_fprofile_update)
|
|
set(COVERAGE_C_LINKER_FLAGS "${COVERAGE_C_LINKER_FLAGS} -fprofile-update=atomic")
|
|
endif ()
|
|
|
|
endif ()
|
|
|
|
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
|
if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG))
|
|
message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
|
|
endif () # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)
|
|
|
|
# Defines a target for running and collection code coverage information
|
|
# Builds dependencies, runs the given executable and outputs reports.
|
|
# NOTE! The executable should always have a ZERO as exit code otherwise
|
|
# the coverage generation will not complete.
|
|
#
|
|
# setup_target_for_coverage_gcovr(
|
|
# NAME ctest_coverage # New target name
|
|
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
|
|
# DEPENDENCIES executable_target # Dependencies to build first
|
|
# BASE_DIRECTORY "../" # Base directory for report
|
|
# # (defaults to PROJECT_SOURCE_DIR)
|
|
# FORMAT "cobertura" # Output format, one of:
|
|
# # xml cobertura sonarqube jacoco clover
|
|
# # json-summary json-details coveralls csv
|
|
# # txt html-single html-nested html-details
|
|
# # lcov (xml is an alias to cobertura;
|
|
# # if no format is set, defaults to xml)
|
|
# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative
|
|
# # to BASE_DIRECTORY, with CMake 3.4+)
|
|
# )
|
|
# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the
|
|
# GCVOR command.
|
|
function (setup_target_for_coverage_gcovr)
|
|
set(options NONE)
|
|
set(oneValueArgs BASE_DIRECTORY NAME FORMAT)
|
|
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
|
|
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
|
|
|
if (NOT GCOV_TOOL)
|
|
message(FATAL_ERROR "Could not find gcov or llvm-cov tool! Aborting...")
|
|
endif ()
|
|
|
|
if (NOT GCOVR_PATH)
|
|
message(FATAL_ERROR "Could not find gcovr tool! Aborting...")
|
|
endif ()
|
|
|
|
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
|
|
if (DEFINED Coverage_BASE_DIRECTORY)
|
|
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
|
|
else ()
|
|
set(BASEDIR ${PROJECT_SOURCE_DIR})
|
|
endif ()
|
|
|
|
if (NOT DEFINED Coverage_FORMAT)
|
|
set(Coverage_FORMAT xml)
|
|
endif ()
|
|
|
|
if (NOT DEFINED Coverage_EXECUTABLE AND DEFINED Coverage_EXECUTABLE_ARGS)
|
|
message(FATAL_ERROR "EXECUTABLE_ARGS must not be set if EXECUTABLE is not set")
|
|
endif ()
|
|
|
|
if ("--output" IN_LIST GCOVR_ADDITIONAL_ARGS)
|
|
message(FATAL_ERROR "Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting...")
|
|
else ()
|
|
if ((Coverage_FORMAT STREQUAL "html-details") OR (Coverage_FORMAT STREQUAL "html-nested"))
|
|
set(GCOVR_OUTPUT_FILE ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html)
|
|
set(GCOVR_CREATE_FOLDER ${PROJECT_BINARY_DIR}/${Coverage_NAME})
|
|
elseif (Coverage_FORMAT STREQUAL "html-single")
|
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.html)
|
|
elseif ((Coverage_FORMAT STREQUAL "json-summary") OR (Coverage_FORMAT STREQUAL "json-details")
|
|
OR (Coverage_FORMAT STREQUAL "coveralls"))
|
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.json)
|
|
elseif (Coverage_FORMAT STREQUAL "txt")
|
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.txt)
|
|
elseif (Coverage_FORMAT STREQUAL "csv")
|
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.csv)
|
|
elseif (Coverage_FORMAT STREQUAL "lcov")
|
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.lcov)
|
|
else ()
|
|
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.xml)
|
|
endif ()
|
|
endif ()
|
|
|
|
if ((Coverage_FORMAT STREQUAL "cobertura") OR (Coverage_FORMAT STREQUAL "xml"))
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura-pretty)
|
|
set(Coverage_FORMAT cobertura) # overwrite xml
|
|
elseif (Coverage_FORMAT STREQUAL "sonarqube")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --sonarqube "${GCOVR_OUTPUT_FILE}")
|
|
elseif (Coverage_FORMAT STREQUAL "jacoco")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco "${GCOVR_OUTPUT_FILE}")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco-pretty)
|
|
elseif (Coverage_FORMAT STREQUAL "clover")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --clover "${GCOVR_OUTPUT_FILE}")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --clover-pretty)
|
|
elseif (Coverage_FORMAT STREQUAL "lcov")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --lcov "${GCOVR_OUTPUT_FILE}")
|
|
elseif (Coverage_FORMAT STREQUAL "json-summary")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary "${GCOVR_OUTPUT_FILE}")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary-pretty)
|
|
elseif (Coverage_FORMAT STREQUAL "json-details")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --json "${GCOVR_OUTPUT_FILE}")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --json-pretty)
|
|
elseif (Coverage_FORMAT STREQUAL "coveralls")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls "${GCOVR_OUTPUT_FILE}")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls-pretty)
|
|
elseif (Coverage_FORMAT STREQUAL "csv")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --csv "${GCOVR_OUTPUT_FILE}")
|
|
elseif (Coverage_FORMAT STREQUAL "txt")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --txt "${GCOVR_OUTPUT_FILE}")
|
|
elseif (Coverage_FORMAT STREQUAL "html-single")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --html "${GCOVR_OUTPUT_FILE}")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --html-self-contained)
|
|
elseif (Coverage_FORMAT STREQUAL "html-nested")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --html-nested "${GCOVR_OUTPUT_FILE}")
|
|
elseif (Coverage_FORMAT STREQUAL "html-details")
|
|
list(APPEND GCOVR_ADDITIONAL_ARGS --html-details "${GCOVR_OUTPUT_FILE}")
|
|
else ()
|
|
message(FATAL_ERROR "Unsupported output style ${Coverage_FORMAT}! Aborting...")
|
|
endif ()
|
|
|
|
# Collect excludes (CMake 3.4+: Also compute absolute paths)
|
|
set(GCOVR_EXCLUDES "")
|
|
foreach (EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
|
|
if (CMAKE_VERSION VERSION_GREATER 3.4)
|
|
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
|
|
endif ()
|
|
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
|
|
endforeach ()
|
|
list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
|
|
|
|
# Combine excludes to several -e arguments
|
|
set(GCOVR_EXCLUDE_ARGS "")
|
|
foreach (EXCLUDE ${GCOVR_EXCLUDES})
|
|
list(APPEND GCOVR_EXCLUDE_ARGS "-e")
|
|
list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
|
|
endforeach ()
|
|
|
|
# Set up commands which will be run to generate coverage data
|
|
# If EXECUTABLE is not set, the user is expected to run the tests manually
|
|
# before running the coverage target NAME
|
|
if (DEFINED Coverage_EXECUTABLE)
|
|
set(GCOVR_EXEC_TESTS_CMD ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS})
|
|
endif ()
|
|
|
|
# Create folder
|
|
if (DEFINED GCOVR_CREATE_FOLDER)
|
|
set(GCOVR_FOLDER_CMD ${CMAKE_COMMAND} -E make_directory ${GCOVR_CREATE_FOLDER})
|
|
endif ()
|
|
|
|
# Running gcovr
|
|
set(GCOVR_CMD
|
|
${GCOVR_PATH}
|
|
--gcov-executable
|
|
${GCOV_TOOL}
|
|
--gcov-ignore-parse-errors=negative_hits.warn_once_per_file
|
|
-r
|
|
${BASEDIR}
|
|
${GCOVR_ADDITIONAL_ARGS}
|
|
${GCOVR_EXCLUDE_ARGS}
|
|
--object-directory=${PROJECT_BINARY_DIR})
|
|
|
|
if (CODE_COVERAGE_VERBOSE)
|
|
message(STATUS "Executed command report")
|
|
|
|
if (NOT "${GCOVR_EXEC_TESTS_CMD}" STREQUAL "")
|
|
message(STATUS "Command to run tests: ")
|
|
string(REPLACE ";" " " GCOVR_EXEC_TESTS_CMD_SPACED "${GCOVR_EXEC_TESTS_CMD}")
|
|
message(STATUS "${GCOVR_EXEC_TESTS_CMD_SPACED}")
|
|
endif ()
|
|
|
|
if (NOT "${GCOVR_FOLDER_CMD}" STREQUAL "")
|
|
message(STATUS "Command to create a folder: ")
|
|
string(REPLACE ";" " " GCOVR_FOLDER_CMD_SPACED "${GCOVR_FOLDER_CMD}")
|
|
message(STATUS "${GCOVR_FOLDER_CMD_SPACED}")
|
|
endif ()
|
|
|
|
message(STATUS "Command to generate gcovr coverage data: ")
|
|
string(REPLACE ";" " " GCOVR_CMD_SPACED "${GCOVR_CMD}")
|
|
message(STATUS "${GCOVR_CMD_SPACED}")
|
|
endif ()
|
|
|
|
add_custom_target(${Coverage_NAME}
|
|
COMMAND ${GCOVR_EXEC_TESTS_CMD}
|
|
COMMAND ${GCOVR_FOLDER_CMD}
|
|
COMMAND ${GCOVR_CMD}
|
|
BYPRODUCTS ${GCOVR_OUTPUT_FILE}
|
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
|
DEPENDS ${Coverage_DEPENDENCIES}
|
|
VERBATIM # Protect arguments to commands
|
|
COMMENT "Running gcovr to produce code coverage report.")
|
|
|
|
# Show info where to find the report
|
|
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD COMMAND echo
|
|
COMMENT "Code coverage report saved in ${GCOVR_OUTPUT_FILE} formatted as ${Coverage_FORMAT}")
|
|
endfunction () # setup_target_for_coverage_gcovr
|
|
|
|
function (add_code_coverage_to_target name scope)
|
|
separate_arguments(COVERAGE_CXX_COMPILER_FLAGS NATIVE_COMMAND "${COVERAGE_CXX_COMPILER_FLAGS}")
|
|
separate_arguments(COVERAGE_C_COMPILER_FLAGS NATIVE_COMMAND "${COVERAGE_C_COMPILER_FLAGS}")
|
|
separate_arguments(COVERAGE_CXX_LINKER_FLAGS NATIVE_COMMAND "${COVERAGE_CXX_LINKER_FLAGS}")
|
|
separate_arguments(COVERAGE_C_LINKER_FLAGS NATIVE_COMMAND "${COVERAGE_C_LINKER_FLAGS}")
|
|
|
|
# Add compiler options to the target
|
|
target_compile_options(${name} ${scope} $<$<COMPILE_LANGUAGE:CXX>:${COVERAGE_CXX_COMPILER_FLAGS}>
|
|
$<$<COMPILE_LANGUAGE:C>:${COVERAGE_C_COMPILER_FLAGS}>)
|
|
|
|
target_link_libraries(${name} ${scope} $<$<LINK_LANGUAGE:CXX>:${COVERAGE_CXX_LINKER_FLAGS}>
|
|
$<$<LINK_LANGUAGE:C>:${COVERAGE_C_LINKER_FLAGS}>)
|
|
endfunction () # add_code_coverage_to_target
|