Skip to content

Commit

Permalink
cmake: code coverage module; see extended commit message
Browse files Browse the repository at this point in the history
- add changelog comments to coverage model
- modify gcovr functions to ignore test failures
- fix logic in selecting llvm-cov or gcov
- change coverage compiler flags from -O0 to -Og
  • Loading branch information
program-- authored and PhilMiller committed Dec 27, 2023
1 parent 88e77b8 commit e779fa9
Showing 1 changed file with 40 additions and 11 deletions.
51 changes: 40 additions & 11 deletions cmake/CodeCoverage.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@
# - fix append_coverage_compiler_flags_to_target to correctly add flags
# - replace "-fprofile-arcs -ftest-coverage" with "--coverage" (equivalent)
#
# 2023-12-26, Justin Singh-Mohudpur (NOAA-OWP/ngen)
# - Remove lcov and fastcov functions for simplicity
# - Add support for llvm-cov with gcov emulation
# - Modify gcovr functions to allow generating coverage even if tests fail
#
# USAGE:
#
# 1. Copy this file into your cmake modules path.
Expand Down Expand Up @@ -142,18 +147,22 @@ option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE)
# Check prereqs
find_program( GCOV_PATH gcov )
find_program( LLVM_COV_PATH llvm-cov )
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
find_program( FASTCOV_PATH NAMES fastcov fastcov.py )
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
find_program( CPPFILT_PATH NAMES c++filt )

if(NOT GCOV_PATH OR NOT LLVM_COV_PATH)
message(FATAL_ERROR "gcov/llvm-cov not found! Aborting...")
endif() # NOT GCOV_PATH

if(${CMAKE_CXX_COMPILER_ID} MATCHES "LLVM|Clang")
# LLVM-based compiler is being used, so we need to set
# GCOV_PATH to be the LLVM_COV_PATH executable with gcov emulation
# i.e. `llvm-cov gcov`
if(NOT LLVM_COV_PATH)
message(FATAL_ERROR "llvm-cov not found! Aborting...")
endif()
set(GCOV_PATH "${LLVM_COV_PATH} gcov")
else()
# Current compiler is set to a non-LLVM compiler,
# so we assume it's GNU-based, and requires `gcov`.
if(NOT GCOV_PATH)
message(FATAL_ERROR "gcov not found! Aborting...")
endif()
endif()

# Check supported compiler (Clang, GNU and Flang)
Expand All @@ -169,7 +178,7 @@ foreach(LANG ${LANGUAGES})
endif()
endforeach()

set(COVERAGE_COMPILER_FLAGS "-g --coverage -O0"
set(COVERAGE_COMPILER_FLAGS "--coverage -Og"
CACHE INTERNAL "")
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCXXCompilerFlag)
Expand Down Expand Up @@ -291,7 +300,6 @@ function(setup_target_for_coverage_gcovr_xml)
endif()

add_custom_target(${Coverage_NAME}
COMMAND ${GCOVR_XML_EXEC_TESTS_CMD}
COMMAND ${GCOVR_XML_CMD}

BYPRODUCTS ${Coverage_NAME}.xml
Expand All @@ -301,6 +309,17 @@ function(setup_target_for_coverage_gcovr_xml)
COMMENT "Running gcovr to produce Cobertura code coverage report."
)

# Run executable separately so we can ignore errors
add_custom_command(
TARGET ${Coverage_NAME} PRE_BUILD

COMMAND ${GCOVR_XML_EXEC_TESTS_CMD} || exit 0

WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
COMMENT "Running test executable."
)

# Show info where to find the report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
Expand Down Expand Up @@ -391,7 +410,6 @@ function(setup_target_for_coverage_gcovr_html)
endif()

add_custom_target(${Coverage_NAME}
COMMAND ${GCOVR_HTML_EXEC_TESTS_CMD}
COMMAND ${GCOVR_HTML_FOLDER_CMD}
COMMAND ${GCOVR_HTML_CMD}

Expand All @@ -402,6 +420,17 @@ function(setup_target_for_coverage_gcovr_html)
COMMENT "Running gcovr to produce HTML code coverage report."
)

# Run executable separately so we can ignore errors
add_custom_command(
TARGET ${Coverage_NAME} PRE_BUILD

COMMAND ${GCOVR_HTML_EXEC_TESTS_CMD} || exit 0

WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
COMMENT "Running test executable."
)

# Show info where to find the report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
Expand Down

0 comments on commit e779fa9

Please sign in to comment.