From f7f9d972a73593fac5daaa7c7c942762ee54548b Mon Sep 17 00:00:00 2001 From: Guillaume Jacquenot Date: Tue, 21 Feb 2017 21:21:13 +0100 Subject: [coverage] Updated cmake coverage files for Lapack --- CMAKE/FindGcov.cmake | 250 ++++++++++++++++----------------- CMAKE/Findcodecov.cmake | 366 +++++++++++++++++++++--------------------------- 2 files changed, 280 insertions(+), 336 deletions(-) (limited to 'CMAKE') diff --git a/CMAKE/FindGcov.cmake b/CMAKE/FindGcov.cmake index 715da6ed..4807f903 100644 --- a/CMAKE/FindGcov.cmake +++ b/CMAKE/FindGcov.cmake @@ -1,13 +1,14 @@ # This file is part of CMake-codecov. # +# https://github.com/RWTH-ELP/CMake-codecov +# # Copyright (c) # 2015-2016 RWTH Aachen University, Federal Republic of Germany # -# See the LICENSE file in the package base directory for details +# LICENSE : BSD 3-Clause License # # Written by Alexander Haase, alexander.haase@rwth-aachen.de -# - +# Updated by Guillaume Jacquenot, guillaume.jacquenot@gmail.com # include required Modules include(FindPackageHandleStandardArgs) @@ -19,85 +20,82 @@ set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY}) get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) foreach (LANG ${ENABLED_LANGUAGES}) - # Gcov evaluation is dependend on the used compiler. Check gcov support for - # each compiler that is used. If gcov binary was already found for this - # compiler, do not try to find it again. - if (NOT GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN) - get_filename_component(COMPILER_PATH "${CMAKE_${LANG}_COMPILER}" PATH) - - if ("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "GNU") - # Some distributions like OSX (homebrew) ship gcov with the compiler - # version appended as gcov-x. To find this binary we'll build the - # suggested binary name with the compiler version. - string(REGEX MATCH "^[0-9]+" GCC_VERSION - "${CMAKE_${LANG}_COMPILER_VERSION}") - - find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov - HINTS ${COMPILER_PATH}) - - elseif ("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Clang") - # Some distributions like Debian ship llvm-cov with the compiler - # version appended as llvm-cov-x.y. To find this binary we'll build - # the suggested binary name with the compiler version. - string(REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION - "${CMAKE_${LANG}_COMPILER_VERSION}") - - # llvm-cov prior version 3.5 seems to be not working with coverage - # evaluation tools, but these versions are compatible with the gcc - # gcov tool. - if(LLVM_VERSION VERSION_GREATER 3.4) - 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) - find_program(LLVM_COV_WRAPPER "llvm-cov-wrapper" PATHS - ${CMAKE_MODULE_PATH}) - if (LLVM_COV_WRAPPER) - set(GCOV_BIN "${LLVM_COV_WRAPPER}" CACHE FILEPATH "") - - # set additional parameters - set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV - "LLVM_COV_BIN=${LLVM_COV_BIN}" CACHE STRING - "Environment variables for llvm-cov-wrapper.") - mark_as_advanced(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV) - endif () - endif () - endif () - - if (NOT GCOV_BIN) - # Fall back to gcov binary if llvm-cov was not found or is - # incompatible. This is the default on OSX, but may crash on - # recent Linux versions. - find_program(GCOV_BIN gcov HINTS ${COMPILER_PATH}) - endif () - endif () - - - if (GCOV_BIN) - set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN "${GCOV_BIN}" CACHE STRING - "${LANG} gcov binary.") - - if (NOT CMAKE_REQUIRED_QUIET) - message("-- Found gcov evaluation for " - "${CMAKE_${LANG}_COMPILER_ID}: ${GCOV_BIN}") - endif() - - unset(GCOV_BIN CACHE) - endif () - endif () + # Gcov evaluation is dependend on the used compiler. Check gcov support for + # each compiler that is used. If gcov binary was already found for this + # compiler, do not try to find it again. + if(NOT GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN) + get_filename_component(COMPILER_PATH "${CMAKE_${LANG}_COMPILER}" PATH) + + if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "GNU") + # Some distributions like OSX (homebrew) ship gcov with the compiler + # version appended as gcov-x. To find this binary we'll build the + # suggested binary name with the compiler version. + string(REGEX MATCH "^[0-9]+" GCC_VERSION + "${CMAKE_${LANG}_COMPILER_VERSION}") + + find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov + HINTS ${COMPILER_PATH}) + + elseif("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Clang") + # Some distributions like Debian ship llvm-cov with the compiler + # version appended as llvm-cov-x.y. To find this binary we'll build + # the suggested binary name with the compiler version. + string(REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION + "${CMAKE_${LANG}_COMPILER_VERSION}") + + # llvm-cov prior version 3.5 seems to be not working with coverage + # evaluation tools, but these versions are compatible with the gcc + # gcov tool. + if(LLVM_VERSION VERSION_GREATER 3.4) + 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) + find_program(LLVM_COV_WRAPPER "llvm-cov-wrapper" PATHS + ${CMAKE_MODULE_PATH}) + if(LLVM_COV_WRAPPER) + set(GCOV_BIN "${LLVM_COV_WRAPPER}" CACHE FILEPATH "") + + # set additional parameters + set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV + "LLVM_COV_BIN=${LLVM_COV_BIN}" CACHE STRING + "Environment variables for llvm-cov-wrapper.") + mark_as_advanced(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV) + endif() + endif() + endif() + + if(NOT GCOV_BIN) + # Fall back to gcov binary if llvm-cov was not found or is + # incompatible. This is the default on OSX, but may crash on + # recent Linux versions. + find_program(GCOV_BIN gcov HINTS ${COMPILER_PATH}) + endif() + endif() + + + if(GCOV_BIN) + set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN "${GCOV_BIN}" CACHE STRING + "${LANG} gcov binary.") + + if(NOT CMAKE_REQUIRED_QUIET) + message("-- Found gcov evaluation for " + "${CMAKE_${LANG}_COMPILER_ID}: ${GCOV_BIN}") + endif() + + unset(GCOV_BIN CACHE) + endif() + endif() endforeach () - - # Add a new global target for all gcov targets. This target could be used to # generate the gcov files for the whole project instead of calling -gcov # for each target. -if (NOT TARGET gcov) - add_custom_target(gcov) -endif (NOT TARGET gcov) - +if(NOT TARGET coverage) + add_custom_target(coverage) +endif() # This function will add gcov evaluation for target . Only sources of @@ -105,53 +103,53 @@ endif (NOT TARGET gcov) # Gcov on any source file of once and store the gcov file in the same # directory. function (add_gcov_target TNAME) - set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir) - - # We don't have to check, if the target has support for coverage, thus this - # will be checked by add_coverage_target in Findcoverage.cmake. Instead we - # have to determine which gcov binary to use. - get_target_property(TSOURCES ${TNAME} SOURCES) - set(SOURCES "") - set(TCOMPILER "") - foreach (FILE ${TSOURCES}) - codecov_path_of_source(${FILE} FILE) - if (NOT "${FILE}" STREQUAL "") - codecov_lang_of_source(${FILE} LANG) - if (NOT "${LANG}" STREQUAL "") - list(APPEND SOURCES "${FILE}") - set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID}) - endif () - endif () - endforeach () - - # If no gcov binary was found, coverage data can't be evaluated. - if (NOT GCOV_${TCOMPILER}_BIN) - message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.") - return() - endif () - - set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}") - set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}") - - - set(BUFFER "") - foreach(FILE ${SOURCES}) - get_filename_component(FILE_PATH "${TDIR}/${FILE}" PATH) - - # call gcov - add_custom_command(OUTPUT ${TDIR}/${FILE}.gcov - COMMAND ${GCOV_ENV} ${GCOV_BIN} ${TDIR}/${FILE}.gcno > /dev/null - DEPENDS ${TNAME} ${TDIR}/${FILE}.gcno - WORKING_DIRECTORY ${FILE_PATH} - ) - - list(APPEND BUFFER ${TDIR}/${FILE}.gcov) - endforeach() - - - # add target for gcov evaluation of - add_custom_target(${TNAME}-gcov DEPENDS ${BUFFER}) - - # add evaluation target to the global gcov target. - add_dependencies(gcov ${TNAME}-gcov) -endfunction (add_gcov_target) + set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir) + + # We don't have to check, if the target has support for coverage, thus this + # will be checked by add_coverage_target in Findcoverage.cmake. Instead we + # have to determine which gcov binary to use. + get_target_property(TSOURCES ${TNAME} SOURCES) + set(SOURCES "") + set(TCOMPILER "") + foreach (FILE ${TSOURCES}) + codecov_path_of_source(${FILE} FILE) + if(NOT "${FILE}" STREQUAL "") + codecov_lang_of_source(${FILE} LANG) + if(NOT "${LANG}" STREQUAL "") + list(APPEND SOURCES "${FILE}") + set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID}) + endif() + endif() + endforeach() + + # If no gcov binary was found, coverage data can't be evaluated. + if(NOT GCOV_${TCOMPILER}_BIN) + message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.") + return() + endif() + + set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}") + set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}") + + + set(BUFFER "") + foreach(FILE ${SOURCES}) + get_filename_component(FILE_PATH "${TDIR}/${FILE}" PATH) + + # call gcov + add_custom_command(OUTPUT ${TDIR}/${FILE}.gcov + COMMAND ${GCOV_ENV} ${GCOV_BIN} ${TDIR}/${FILE}.gcno > /dev/null + DEPENDS ${TNAME} ${TDIR}/${FILE}.gcno + WORKING_DIRECTORY ${FILE_PATH} + ) + + list(APPEND BUFFER ${TDIR}/${FILE}.gcov) + endforeach() + + + # add target for gcov evaluation of + add_custom_target(${TNAME}-gcov DEPENDS ${BUFFER}) + + # add evaluation target to the global gcov target. + add_dependencies(coverage ${TNAME}-gcov) +endfunction() diff --git a/CMAKE/Findcodecov.cmake b/CMAKE/Findcodecov.cmake index 11250784..1f33b2c0 100644 --- a/CMAKE/Findcodecov.cmake +++ b/CMAKE/Findcodecov.cmake @@ -1,79 +1,39 @@ # This file is part of CMake-codecov. # +# https://github.com/RWTH-ELP/CMake-codecov +# # Copyright (c) # 2015-2016 RWTH Aachen University, Federal Republic of Germany # -# See the LICENSE file in the package base directory for details +# LICENSE : BSD 3-Clause License # # Written by Alexander Haase, alexander.haase@rwth-aachen.de -# - - -# Add an option to choose, if coverage should be enabled or not. If enabled -# marked targets will be build with coverage support and appropriate targets -# will be added. If disabled coverage will be ignored for *ALL* targets. -option(ENABLE_COVERAGE "Enable coverage build." OFF) +# Updated by Guillaume Jacquenot, guillaume.jacquenot@gmail.com set(COVERAGE_FLAG_CANDIDATES - # gcc and clang - "-O0 -g -fprofile-arcs -ftest-coverage" + # gcc and clang + "-O0 -g -fprofile-arcs -ftest-coverage" - # gcc and clang fallback - "-O0 -g --coverage" + # gcc and clang fallback + "-O0 -g --coverage" ) # To avoid error messages about CMP0051, this policy will be set to new. There # will be no problem, as TARGET_OBJECTS generator expressions will be filtered # with a regular expression from the sources. -if (POLICY CMP0051) - cmake_policy(SET CMP0051 NEW) +if(POLICY CMP0051) + cmake_policy(SET CMP0051 NEW) endif() # Add coverage support for target ${TNAME} and register target for coverage -# evaluation. If coverage is disabled or not supported, this function will -# simply do nothing. -# -# Note: This function is only a wrapper to define this function always, even if -# coverage is not supported by the compiler or disabled. This function must -# be defined here, because the module will be exited, if there is no coverage -# support by the compiler or it is disabled by the user. -function (add_coverage TNAME) - # only add coverage for target, if coverage is support and enabled. - if (ENABLE_COVERAGE) - foreach (TNAME ${ARGV}) - add_coverage_target(${TNAME}) - endforeach () - endif () -endfunction (add_coverage) - - -# Add global target to gather coverage information after all targets have been -# added. Other evaluation functions could be added here, after checks for the -# specific module have been passed. -# -# Note: This function is only a wrapper to define this function always, even if -# coverage is not supported by the compiler or disabled. This function must -# be defined here, because the module will be exited, if there is no coverage -# support by the compiler or it is disabled by the user. -function (coverage_evaluate) - # add lcov evaluation - if (LCOV_FOUND) - lcov_capture_initial() - lcov_capture() - endif (LCOV_FOUND) -endfunction () - - -# Exit this module, if coverage is disabled. add_coverage is defined before this -# return, so this module can be exited now safely without breaking any build- -# scripts. -if (NOT ENABLE_COVERAGE) - return() -endif () - - +# evaluation. +function(add_coverage TNAME) + foreach (TNAME ${ARGV}) + add_coverage_target(${TNAME}) + endforeach() +endfunction() # Find the reuired flags foreach language. @@ -82,175 +42,161 @@ set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY}) get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) foreach (LANG ${ENABLED_LANGUAGES}) - # Coverage flags are not dependend on language, but the used compiler. So - # instead of searching flags foreach language, search flags foreach compiler - # used. - set(COMPILER ${CMAKE_${LANG}_COMPILER_ID}) - if (NOT COVERAGE_${COMPILER}_FLAGS) - foreach (FLAG ${COVERAGE_FLAG_CANDIDATES}) - if(NOT CMAKE_REQUIRED_QUIET) - message(STATUS "Try ${COMPILER} code coverage flag = [${FLAG}]") - endif() - - set(CMAKE_REQUIRED_FLAGS "${FLAG}") - unset(COVERAGE_FLAG_DETECTED CACHE) - - if (${LANG} STREQUAL "C") - include(CheckCCompilerFlag) - check_c_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED) - - elseif (${LANG} STREQUAL "CXX") - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED) - - elseif (${LANG} STREQUAL "Fortran") - # CheckFortranCompilerFlag was introduced in CMake 3.x. To be - # compatible with older Cmake versions, we will check if this - # module is present before we use it. Otherwise we will define - # Fortran coverage support as not available. - include(CheckFortranCompilerFlag OPTIONAL - RESULT_VARIABLE INCLUDED) - if (INCLUDED) - check_fortran_compiler_flag("${FLAG}" - COVERAGE_FLAG_DETECTED) - elseif (NOT CMAKE_REQUIRED_QUIET) - message("-- Performing Test COVERAGE_FLAG_DETECTED") - message("-- Performing Test COVERAGE_FLAG_DETECTED - Failed" - " (Check not supported)") - endif () - endif() - - if (COVERAGE_FLAG_DETECTED) - set(COVERAGE_${COMPILER}_FLAGS "${FLAG}" - CACHE STRING "${COMPILER} flags for code coverage.") - mark_as_advanced(COVERAGE_${COMPILER}_FLAGS) - break() - endif () - endforeach () - endif () -endforeach () + # Coverage flags are not dependend on language, but the used compiler. So + # instead of searching flags foreach language, search flags foreach compiler + # used. + set(COMPILER ${CMAKE_${LANG}_COMPILER_ID}) + if(NOT COVERAGE_${COMPILER}_FLAGS) + foreach (FLAG ${COVERAGE_FLAG_CANDIDATES}) + if(NOT CMAKE_REQUIRED_QUIET) + message(STATUS "Try ${COMPILER} code coverage flag = [${FLAG}]") + endif() + + set(CMAKE_REQUIRED_FLAGS "${FLAG}") + unset(COVERAGE_FLAG_DETECTED CACHE) + + if(${LANG} STREQUAL "C") + include(CheckCCompilerFlag) + check_c_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED) + + elseif(${LANG} STREQUAL "CXX") + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag("${FLAG}" COVERAGE_FLAG_DETECTED) + + elseif(${LANG} STREQUAL "Fortran") + # CheckFortranCompilerFlag was introduced in CMake 3.x. To be + # compatible with older Cmake versions, we will check if this + # module is present before we use it. Otherwise we will define + # Fortran coverage support as not available. + include(CheckFortranCompilerFlag OPTIONAL + RESULT_VARIABLE INCLUDED) + if(INCLUDED) + check_fortran_compiler_flag("${FLAG}" + COVERAGE_FLAG_DETECTED) + elseif(NOT CMAKE_REQUIRED_QUIET) + message("-- Performing Test COVERAGE_FLAG_DETECTED") + message("-- Performing Test COVERAGE_FLAG_DETECTED - Failed" + " (Check not supported)") + endif() + endif() + + if(COVERAGE_FLAG_DETECTED) + set(COVERAGE_${COMPILER}_FLAGS "${FLAG}" + CACHE STRING "${COMPILER} flags for code coverage.") + mark_as_advanced(COVERAGE_${COMPILER}_FLAGS) + break() + endif() + endforeach() + endif() +endforeach() set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_SAVE}) - - - # Helper function to get the language of a source file. function (codecov_lang_of_source FILE RETURN_VAR) - get_filename_component(FILE_EXT "${FILE}" EXT) - string(TOLOWER "${FILE_EXT}" FILE_EXT) - string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT) - - get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) - foreach (LANG ${ENABLED_LANGUAGES}) - list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP) - if (NOT ${TEMP} EQUAL -1) - set(${RETURN_VAR} "${LANG}" PARENT_SCOPE) - return() - endif () - endforeach() - - set(${RETURN_VAR} "" PARENT_SCOPE) -endfunction () - + get_filename_component(FILE_EXT "${FILE}" EXT) + string(TOLOWER "${FILE_EXT}" FILE_EXT) + string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT) + + get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + foreach (LANG ${ENABLED_LANGUAGES}) + list(FIND CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS "${FILE_EXT}" TEMP) + if(NOT ${TEMP} EQUAL -1) + set(${RETURN_VAR} "${LANG}" PARENT_SCOPE) + return() + endif() + endforeach() + + set(${RETURN_VAR} "" PARENT_SCOPE) +endfunction() # Helper function to get the relative path of the source file destination path. # This path is needed by FindGcov and FindLcov cmake files to locate the # captured data. function (codecov_path_of_source FILE RETURN_VAR) - string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _source ${FILE}) - - # If expression was found, SOURCEFILE is a generator-expression for an - # object library. Currently we found no way to call this function automatic - # for the referenced target, so it must be called in the directoryso of the - # object library definition. - if (NOT "${_source}" STREQUAL "") - set(${RETURN_VAR} "" PARENT_SCOPE) - return() - endif () - - - string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" FILE "${FILE}") - if(IS_ABSOLUTE ${FILE}) - file(RELATIVE_PATH FILE ${CMAKE_CURRENT_SOURCE_DIR} ${FILE}) - endif() - - # get the right path for file - string(REPLACE ".." "__" PATH "${FILE}") - - set(${RETURN_VAR} "${PATH}" PARENT_SCOPE) + string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _source ${FILE}) + + # If expression was found, SOURCEFILE is a generator-expression for an + # object library. Currently we found no way to call this function automatic + # for the referenced target, so it must be called in the directoryso of the + # object library definition. + if(NOT "${_source}" STREQUAL "") + set(${RETURN_VAR} "" PARENT_SCOPE) + return() + endif() + + string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" FILE "${FILE}") + if(IS_ABSOLUTE ${FILE}) + file(RELATIVE_PATH FILE ${CMAKE_CURRENT_SOURCE_DIR} ${FILE}) + endif() + + # get the right path for file + string(REPLACE ".." "__" PATH "${FILE}") + + set(${RETURN_VAR} "${PATH}" PARENT_SCOPE) endfunction() - - - # Add coverage support for target ${TNAME} and register target for coverage # evaluation. function(add_coverage_target TNAME) - # Check if all sources for target use the same compiler. If a target uses - # e.g. C and Fortran mixed and uses different compilers (e.g. clang and - # gfortran) this can trigger huge problems, because different compilers may - # use different implementations for code coverage. - get_target_property(TSOURCES ${TNAME} SOURCES) - set(TARGET_COMPILER "") - set(ADDITIONAL_FILES "") - foreach (FILE ${TSOURCES}) - # If expression was found, FILE is a generator-expression for an object - # library. Object libraries will be ignored. - string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE}) - if ("${_file}" STREQUAL "") - codecov_lang_of_source(${FILE} LANG) - if (LANG) - list(APPEND TARGET_COMPILER ${CMAKE_${LANG}_COMPILER_ID}) - - list(APPEND ADDITIONAL_FILES "${FILE}.gcno") - list(APPEND ADDITIONAL_FILES "${FILE}.gcda") - endif () - endif () - endforeach () - - list(REMOVE_DUPLICATES TARGET_COMPILER) - list(LENGTH TARGET_COMPILER NUM_COMPILERS) - - if (NUM_COMPILERS GREATER 1) - message(AUTHOR_WARNING "Coverage disabled for target ${TNAME} because " - "it will be compiled by different compilers.") - return() - - elseif ((NUM_COMPILERS EQUAL 0) OR - (NOT DEFINED "COVERAGE_${TARGET_COMPILER}_FLAGS")) - message(AUTHOR_WARNING "Coverage disabled for target ${TNAME} " - "because there is no sanitizer available for target sources.") - return() - endif() - - - # enable coverage for target - set_property(TARGET ${TNAME} APPEND_STRING - PROPERTY COMPILE_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}") - set_property(TARGET ${TNAME} APPEND_STRING - PROPERTY LINK_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}") - - - # Add gcov files generated by compiler to clean target. - set(CLEAN_FILES "") - foreach (FILE ${ADDITIONAL_FILES}) - codecov_path_of_source(${FILE} FILE) - list(APPEND CLEAN_FILES "CMakeFiles/${TNAME}.dir/${FILE}") - endforeach() - - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES - "${CLEAN_FILES}") - - - add_gcov_target(${TNAME}) - add_lcov_target(${TNAME}) -endfunction(add_coverage_target) - - - + # Check if all sources for target use the same compiler. If a target uses + # e.g. C and Fortran mixed and uses different compilers (e.g. clang and + # gfortran) this can trigger huge problems, because different compilers may + # use different implementations for code coverage. + get_target_property(TSOURCES ${TNAME} SOURCES) + set(TARGET_COMPILER "") + set(ADDITIONAL_FILES "") + foreach (FILE ${TSOURCES}) + # If expression was found, FILE is a generator-expression for an object + # library. Object libraries will be ignored. + string(REGEX MATCH "TARGET_OBJECTS:([^ >]+)" _file ${FILE}) + if("${_file}" STREQUAL "") + codecov_lang_of_source(${FILE} LANG) + if(LANG) + list(APPEND TARGET_COMPILER ${CMAKE_${LANG}_COMPILER_ID}) + + list(APPEND ADDITIONAL_FILES "${FILE}.gcno") + list(APPEND ADDITIONAL_FILES "${FILE}.gcda") + endif() + endif() + endforeach () + + list(REMOVE_DUPLICATES TARGET_COMPILER) + list(LENGTH TARGET_COMPILER NUM_COMPILERS) + + if(NUM_COMPILERS GREATER 1) + message(AUTHOR_WARNING "Coverage disabled for target ${TNAME} because " + "it will be compiled by different compilers.") + return() + + elseif((NUM_COMPILERS EQUAL 0) OR + (NOT DEFINED "COVERAGE_${TARGET_COMPILER}_FLAGS")) + message(AUTHOR_WARNING "Coverage disabled for target ${TNAME} " + "because there is no sanitizer available for target sources.") + return() + endif() + + + # enable coverage for target + set_property(TARGET ${TNAME} APPEND_STRING + PROPERTY COMPILE_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}") + set_property(TARGET ${TNAME} APPEND_STRING + PROPERTY LINK_FLAGS " ${COVERAGE_${TARGET_COMPILER}_FLAGS}") + + + # Add gcov files generated by compiler to clean target. + set(CLEAN_FILES "") + foreach (FILE ${ADDITIONAL_FILES}) + codecov_path_of_source(${FILE} FILE) + list(APPEND CLEAN_FILES "CMakeFiles/${TNAME}.dir/${FILE}") + endforeach() + + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES + "${CLEAN_FILES}") + + add_gcov_target(${TNAME}) +endfunction() # Include modules for parsing the collected data and output it in a readable -# format (like gcov and lcov). +# format (like gcov). find_package(Gcov) -find_package(Lcov) -- cgit v1.2.3