From e779fa9a7f82516228f408d98be7b879d2b03d1e Mon Sep 17 00:00:00 2001 From: program-- Date: Tue, 26 Dec 2023 11:20:31 -0800 Subject: [PATCH] cmake: code coverage module; see extended commit message - 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 --- cmake/CodeCoverage.cmake | 51 +++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/cmake/CodeCoverage.cmake b/cmake/CodeCoverage.cmake index 6919b3ad6c..d4aeae3a24 100644 --- a/cmake/CodeCoverage.cmake +++ b/cmake/CodeCoverage.cmake @@ -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. @@ -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) @@ -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) @@ -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 @@ -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 ; @@ -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} @@ -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 ;