You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

FindGcov.cmake 5.4 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. # This file is part of CMake-codecov.
  2. #
  3. # https://github.com/RWTH-ELP/CMake-codecov
  4. #
  5. # Copyright (c)
  6. # 2015-2016 RWTH Aachen University, Federal Republic of Germany
  7. #
  8. # LICENSE : BSD 3-Clause License
  9. #
  10. # Written by Alexander Haase, alexander.haase@rwth-aachen.de
  11. # Updated by Guillaume Jacquenot, guillaume.jacquenot@gmail.com
  12. # include required Modules
  13. include(FindPackageHandleStandardArgs)
  14. # Search for gcov binary.
  15. set(CMAKE_REQUIRED_QUIET_SAVE ${CMAKE_REQUIRED_QUIET})
  16. set(CMAKE_REQUIRED_QUIET ${codecov_FIND_QUIETLY})
  17. get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
  18. foreach (LANG ${ENABLED_LANGUAGES})
  19. # Gcov evaluation is dependend on the used compiler. Check gcov support for
  20. # each compiler that is used. If gcov binary was already found for this
  21. # compiler, do not try to find it again.
  22. if(NOT GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN)
  23. get_filename_component(COMPILER_PATH "${CMAKE_${LANG}_COMPILER}" PATH)
  24. if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "GNU")
  25. # Some distributions like OSX (homebrew) ship gcov with the compiler
  26. # version appended as gcov-x. To find this binary we'll build the
  27. # suggested binary name with the compiler version.
  28. string(REGEX MATCH "^[0-9]+" GCC_VERSION
  29. "${CMAKE_${LANG}_COMPILER_VERSION}")
  30. find_program(GCOV_BIN NAMES gcov-${GCC_VERSION} gcov
  31. HINTS ${COMPILER_PATH})
  32. elseif("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "Clang")
  33. # Some distributions like Debian ship llvm-cov with the compiler
  34. # version appended as llvm-cov-x.y. To find this binary we'll build
  35. # the suggested binary name with the compiler version.
  36. string(REGEX MATCH "^[0-9]+.[0-9]+" LLVM_VERSION
  37. "${CMAKE_${LANG}_COMPILER_VERSION}")
  38. # llvm-cov prior version 3.5 seems to be not working with coverage
  39. # evaluation tools, but these versions are compatible with the gcc
  40. # gcov tool.
  41. if(LLVM_VERSION VERSION_GREATER 3.4)
  42. find_program(LLVM_COV_BIN NAMES "llvm-cov-${LLVM_VERSION}"
  43. "llvm-cov" HINTS ${COMPILER_PATH})
  44. mark_as_advanced(LLVM_COV_BIN)
  45. if(LLVM_COV_BIN)
  46. find_program(LLVM_COV_WRAPPER "llvm-cov-wrapper" PATHS
  47. ${CMAKE_MODULE_PATH})
  48. if(LLVM_COV_WRAPPER)
  49. set(GCOV_BIN "${LLVM_COV_WRAPPER}" CACHE FILEPATH "")
  50. # set additional parameters
  51. set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV
  52. "LLVM_COV_BIN=${LLVM_COV_BIN}" CACHE STRING
  53. "Environment variables for llvm-cov-wrapper.")
  54. mark_as_advanced(GCOV_${CMAKE_${LANG}_COMPILER_ID}_ENV)
  55. endif()
  56. endif()
  57. endif()
  58. if(NOT GCOV_BIN)
  59. # Fall back to gcov binary if llvm-cov was not found or is
  60. # incompatible. This is the default on OSX, but may crash on
  61. # recent Linux versions.
  62. find_program(GCOV_BIN gcov HINTS ${COMPILER_PATH})
  63. endif()
  64. endif()
  65. if(GCOV_BIN)
  66. set(GCOV_${CMAKE_${LANG}_COMPILER_ID}_BIN "${GCOV_BIN}" CACHE STRING
  67. "${LANG} gcov binary.")
  68. if(NOT CMAKE_REQUIRED_QUIET)
  69. message("-- Found gcov evaluation for "
  70. "${CMAKE_${LANG}_COMPILER_ID}: ${GCOV_BIN}")
  71. endif()
  72. unset(GCOV_BIN CACHE)
  73. endif()
  74. endif()
  75. endforeach ()
  76. # Add a new global target for all gcov targets. This target could be used to
  77. # generate the gcov files for the whole project instead of calling <TARGET>-gcov
  78. # for each target.
  79. if(NOT TARGET coverage)
  80. add_custom_target(coverage)
  81. endif()
  82. # This function will add gcov evaluation for target <TNAME>. Only sources of
  83. # this target will be evaluated and no dependencies will be added. It will call
  84. # Gcov on any source file of <TNAME> once and store the gcov file in the same
  85. # directory.
  86. function (add_gcov_target TNAME)
  87. set(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
  88. # We don't have to check, if the target has support for coverage, thus this
  89. # will be checked by add_coverage_target in Findcoverage.cmake. Instead we
  90. # have to determine which gcov binary to use.
  91. get_target_property(TSOURCES ${TNAME} SOURCES)
  92. set(SOURCES "")
  93. set(TCOMPILER "")
  94. foreach (FILE ${TSOURCES})
  95. codecov_path_of_source(${FILE} FILE)
  96. if(NOT "${FILE}" STREQUAL "")
  97. codecov_lang_of_source(${FILE} LANG)
  98. if(NOT "${LANG}" STREQUAL "")
  99. list(APPEND SOURCES "${FILE}")
  100. set(TCOMPILER ${CMAKE_${LANG}_COMPILER_ID})
  101. endif()
  102. endif()
  103. endforeach()
  104. # If no gcov binary was found, coverage data can't be evaluated.
  105. if(NOT GCOV_${TCOMPILER}_BIN)
  106. message(WARNING "No coverage evaluation binary found for ${TCOMPILER}.")
  107. return()
  108. endif()
  109. set(GCOV_BIN "${GCOV_${TCOMPILER}_BIN}")
  110. set(GCOV_ENV "${GCOV_${TCOMPILER}_ENV}")
  111. set(BUFFER "")
  112. foreach(FILE ${SOURCES})
  113. get_filename_component(FILE_PATH "${TDIR}/${FILE}" PATH)
  114. # call gcov
  115. add_custom_command(OUTPUT ${TDIR}/${FILE}.gcov
  116. COMMAND ${GCOV_ENV} ${GCOV_BIN} ${TDIR}/${FILE}.gcno > /dev/null
  117. DEPENDS ${TNAME} ${TDIR}/${FILE}.gcno
  118. WORKING_DIRECTORY ${FILE_PATH}
  119. )
  120. list(APPEND BUFFER ${TDIR}/${FILE}.gcov)
  121. endforeach()
  122. # add target for gcov evaluation of <TNAME>
  123. add_custom_target(${TNAME}-gcov DEPENDS ${BUFFER})
  124. # add evaluation target to the global gcov target.
  125. add_dependencies(coverage ${TNAME}-gcov)
  126. endfunction()