From 0f4d3b79bd3501b9ddc1afa8b0ec24a53d7ec5fe Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Wed, 17 Jul 2019 00:08:23 +0200
Subject: [PATCH] Code transition from gcovr to the more classical lcov
 interface

This is freely inspired/adapted from https://github.com/MASCOTNUM/libKriging
Thanks @hpwfx
---
 CMakeLists.txt | 73 +++++++++++++++++++++++++++++---------------------
 1 file changed, 42 insertions(+), 31 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 352b13ed8..ae02ac9d1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -226,45 +226,56 @@ add_custom_target(run_unit_tests
 # unit tests coverage
 
 if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
-  find_program(GCOVR gcovr)
-  if(NOT GCOVR)
-    message(FATAL_ERROR "gcovr not found, cannot perform coverage.")
+  find_program(LCOV lcov)
+  if(NOT LCOV)
+    message(FATAL_ERROR "lcov not found, cannot perform coverage.")
   endif()
 
-  if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
-    string(REPLACE "clang++" "llvm-cov" LLVM_COV "${CMAKE_CXX_COMPILER}")
-    if(NOT EXISTS "${LLVM_COV}")
-      message(FATAL_ERROR "could not find ${LLVM_COV}, cannot perform coverage (using g++ for coverage is recommended).")
-    endif()
-
-    set(GCOVR_EXTRA "--gcov-executable=${LLVM_COV} gcov")
-  endif()
-
-  set (GCOVR_EXCLUDE
-    -e "${PUGS_SOURCE_DIR}/src/main.cpp"
-    -e "${PUGS_SOURCE_DIR}/src/utils/BacktraceManager.cpp"
-    -e "${PUGS_SOURCE_DIR}/src/utils/BacktraceManager.hpp"
+  set (LCOV_REMOVE_PATTERN
     )
 
-  set(GCOVR_OPTIONS --object-directory="${PUGS_BINARY_DIR}" -r "${PUGS_SOURCE_DIR}/src" ${GCOVR_EXCLUDE} ${GCOVR_EXTRA})
-
   add_custom_target(coverage
-    ALL
-    COMMAND ${GCOVR} ${GCOVR_OPTIONS} --exclude-unreachable-branches --sort-percentage
-    DEPENDS run_unit_tests pugs
-    COMMENT "Running gcovr to build coverage report."
-    )
-
-  add_custom_target(coverage-report
-    ALL
-    COMMAND ${CMAKE_COMMAND} -E remove_directory "${PUGS_BINARY_DIR}/coverage"
-    COMMAND ${CMAKE_COMMAND} -E make_directory "${PUGS_BINARY_DIR}/coverage"
-    COMMAND ${GCOVR} ${GCOVR_OPTIONS} --delete --html --html-details -o "${PUGS_BINARY_DIR}/coverage/index.html"
-    DEPENDS coverage
-    COMMENT "Building coverage html report."
+    ALL # in coverage mode we do coverage!
+    # Cleanup previously generated profiling data
+    COMMAND ${LCOV} -q --base-directory "${PUGS_SOURCE_DIR}/src" --directory "${PUGS_BINARY_DIR}" --zerocounters
+    # Initialize profiling data with zero coverage for every instrumented line of the project
+    # This way the percentage of total lines covered will always be correct, even when not all source code files were loaded during the test(s)
+    COMMAND ${LCOV} -q --base-directory "${PUGS_SOURCE_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --initial --output-file coverage_base.info
+    # Run tests
+    COMMAND ${CMAKE_CTEST_COMMAND} -j ${PROCESSOR_COUNT}
+    # Collect data from executions
+    COMMAND ${LCOV} --base-directory "${PUGS_SOURCE_DIR}/src" --directory "${PUGS_BINARY_DIR}" --capture --output-file coverage_ctest.info
+    # Combine base and ctest results
+    COMMAND ${LCOV} -q --add-tracefile coverage_base.info --add-tracefile coverage_ctest.info --output-file coverage_full.info
+    # Extract only project data (--no-capture or --remove options may be used to select collected data)
+    COMMAND ${LCOV} -q --extract coverage_full.info "'${PUGS_SOURCE_DIR}/src/*'" --output-file coverage_extract.info
+
+    # Remove unwanted stuff
+    COMMAND ${LCOV} --remove coverage_extract.info  --output-file coverage.info
+                                              '${PUGS_SOURCE_DIR}/src/main.cpp'
+                                              '${PUGS_SOURCE_DIR}/utils/BacktraceManager.*'
+
+    COMMAND ${LCOV} --list coverage.info
+
+    DEPENDS unit_tests mpi_unit_tests
+    COMMENT "Running test coverage."
     WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
     )
 
+  find_program(GENHTML genhtml)
+  if(NOT GENHTML)
+    message(WARNING "genhtml not found, cannot perform report-coverage.")
+  else()
+    add_custom_target(coverage-report
+      ALL
+      COMMAND ${CMAKE_COMMAND} -E remove_directory "${PUGS_BINARY_DIR}/coverage"
+      COMMAND ${CMAKE_COMMAND} -E make_directory "${PUGS_BINARY_DIR}/coverage"
+      COMMAND ${GENHTML} -q -o coverage -t "${CMAKE_PROJECT_NAME} test coverage" --ignore-errors source --legend --num-spaces 4 coverage.info
+      DEPENDS coverage
+      COMMENT "Building coverage html report."
+      WORKING_DIRECTORY "${PUGS_BINARY_DIR}"
+      )
+  endif()
 endif()
 
 #------------------------------------------------------
-- 
GitLab