From 3bdfe5d4faf70778391cb9ae57831b25062cc8b3 Mon Sep 17 00:00:00 2001
From: Stephane Del Pino <stephane.delpino44@gmail.com>
Date: Tue, 23 Jul 2019 18:09:47 +0200
Subject: [PATCH] Add new strategy to detect which gcov tool to use

When dealing with g++-x searches for gcov-x and eventually falls back to gcov

When using clang++ uses the llvm-gcov and generate the appropriate script
---
 CMakeLists.txt | 48 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 39 insertions(+), 9 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ae02ac9d1..418a37dbc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -231,31 +231,61 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "Coverage")
     message(FATAL_ERROR "lcov not found, cannot perform coverage.")
   endif()
 
-  set (LCOV_REMOVE_PATTERN
-    )
+  if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+    string(REGEX MATCH "^[0-9]+" GCC_VERSION
+      "${CMAKE_CXX_COMPILER_VERSION}")
+    find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov
+      HINTS ${COMPILER_PATH})
+  elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+    string(REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION
+      "${CMAKE_CXX_COMPILER_VERSION}")
+
+    if(LLVM_VERSION VERSION_GREATER 7)
+      find_program(LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}"
+        "llvm-cov" HINTS ${COMPILER_PATH})
+      mark_as_advanced(LLVM_COV_BIN)
+
+      if (LLVM_COV_BIN)
+        file(MAKE_DIRECTORY "${PUGS_BINARY_DIR}/tools/tmp")
+
+        file(WRITE "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh" "#! /bin/sh\n")
+        file(APPEND "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh" "'${LLVM_COV_BIN}' gcov \"\$@\"\n")
+
+        file(COPY "${PUGS_BINARY_DIR}/tools/tmp/llvm-cov.sh"
+             DESTINATION "${PUGS_BINARY_DIR}/tools"
+             FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
+
+        set(GCOV_BIN "${PUGS_BINARY_DIR}/tools/llvm-cov.sh")
+      endif()
+    endif()
+  endif()
+
+  if(NOT GCOV_BIN)
+     message(FATAL_ERROR "Cannot find a proper gcov tool, cannot perform coverage.")
+  endif()
 
   add_custom_target(coverage
     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
+    COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --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
+    COMMAND ${LCOV} -q --gcov "${GCOV_BIN}" --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
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" --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
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" -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
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" -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
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" --remove coverage_extract.info  --output-file coverage.info
                                               '${PUGS_SOURCE_DIR}/src/main.cpp'
                                               '${PUGS_SOURCE_DIR}/utils/BacktraceManager.*'
 
-    COMMAND ${LCOV} --list coverage.info
+    COMMAND ${LCOV} --gcov "${GCOV_BIN}" --list coverage.info
 
     DEPENDS unit_tests mpi_unit_tests
     COMMENT "Running test coverage."
-- 
GitLab