2018-11-20 06:51:34 +01:00
|
|
|
# DOES NOT SUPPORT RUNNING IN PARALLEL: https://github.com/linux-test-project/lcov/issues/37
|
|
|
|
|
|
|
|
# TODO: macos xcode coverage: works? What dependencies?
|
|
|
|
|
|
|
|
get_filename_component(_CODECOVERAGE_MODDIR ${CMAKE_CURRENT_LIST_FILE} PATH)
|
|
|
|
|
2018-12-18 19:03:05 +01:00
|
|
|
function(codecoverage_enable)
|
2018-11-20 06:51:34 +01:00
|
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
|
|
find_program(GCOV_BIN gcov)
|
|
|
|
if(NOT GCOV_BIN)
|
|
|
|
message(FATAL_ERROR "gcov not found")
|
|
|
|
endif()
|
|
|
|
set(COV_BIN "${GCOV_BIN}")
|
|
|
|
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
|
|
|
find_program(LLVM_COV_BIN llvm-cov)
|
|
|
|
if(NOT LLVM_COV_BIN)
|
|
|
|
message(FATAL_ERROR "llvm-cov not found")
|
|
|
|
endif()
|
|
|
|
configure_file("${_CODECOVERAGE_MODDIR}/llvm-cov-wrapper.in" "${CMAKE_BINARY_DIR}/llvm-cov-wrapper")
|
|
|
|
set(COV_BIN "${CMAKE_BINARY_DIR}/llvm-cov-wrapper")
|
|
|
|
else()
|
|
|
|
message(FATAL_ERROR "Code coverage unsupported for this compiler.")
|
|
|
|
endif()
|
|
|
|
set(COV_BIN "${COV_BIN}" CACHE INTERNAL "Coverage tool")
|
|
|
|
|
|
|
|
find_program(LCOV_BIN lcov)
|
|
|
|
if(NOT LCOV_BIN)
|
|
|
|
message(FATAL_ERROR "lcov not found")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
find_program(GENINFO_BIN geninfo)
|
|
|
|
if(NOT GENINFO_BIN)
|
|
|
|
message(FATAL_ERROR "geninfo not found")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
find_program(GENHTML_BIN genhtml)
|
|
|
|
if(NOT GENHTML_BIN)
|
|
|
|
message(FATAL_ERROR "genhtml not found")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
find_program(CPPFILT_BIN c++filt)
|
|
|
|
if(NOT CPPFILT_BIN)
|
|
|
|
message(FATAL_ERROR "c++filt not found")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
message(STATUS "TEST_COVERAGE enabled. Optimizations are disabled, debug data will be added to targets.")
|
|
|
|
|
|
|
|
# Remove global optimization flags
|
|
|
|
foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES} "")
|
|
|
|
foreach(LANGUAGE C CXX)
|
|
|
|
set(FLAGVARNAME "CMAKE_${LANGUAGE}_FLAGS")
|
|
|
|
if(CONFIG_TYPE)
|
|
|
|
string(TOUPPER "${CONFIG_TYPE}" CONFIG_TYPE)
|
|
|
|
set(FLAGVARNAME "${FLAGVARNAME}_${CONFIG_TYPE}")
|
|
|
|
endif()
|
|
|
|
string(REGEX REPLACE "-O[s0-3]" "" _OUT "${${FLAGVARNAME}}")
|
|
|
|
set("${FLAGVARNAME}" "${_OUT}" PARENT_SCOPE)
|
|
|
|
endforeach()
|
|
|
|
endforeach()
|
|
|
|
|
|
|
|
set(COVERAGE_COMPILE_FLAGS "-O0 -fprofile-arcs -ftest-coverage -g" CACHE STRING "Compile flags for compiling with coverage support")
|
|
|
|
set(COVERAGE_LINK_FLAGS "-O0 -fprofile-arcs -ftest-coverage" CACHE STRING "Link flags for linking with coverage support")
|
|
|
|
|
|
|
|
set(LCOV_DATA_PATH "${CMAKE_BINARY_DIR}/lcov/data")
|
|
|
|
set(LCOV_DATA_PATH_INIT "${LCOV_DATA_PATH}/init" CACHE PATH "Where to put initial coverage")
|
|
|
|
set(LCOV_DATA_PATH_CAPTURE "${LCOV_DATA_PATH}/capture" CACHE PATH "Where to put final coverage")
|
|
|
|
set(LCOV_HTML_PATH "${CMAKE_BINARY_DIR}/lcov/html" CACHE PATH "Where to put html coverage reports")
|
|
|
|
|
|
|
|
file(MAKE_DIRECTORY ${LCOV_DATA_PATH_INIT})
|
|
|
|
file(MAKE_DIRECTORY ${LCOV_DATA_PATH_CAPTURE})
|
|
|
|
|
|
|
|
add_custom_target(gcov)
|
|
|
|
add_custom_target(lcov-capture-init)
|
|
|
|
add_custom_target(lcov-capture)
|
|
|
|
|
|
|
|
define_property(GLOBAL
|
|
|
|
PROPERTY COVERAGE_TARGETS
|
|
|
|
BRIEF_DOCS "List of all coverage targets"
|
|
|
|
FULL_DOCS "All targets that is collected coverage over"
|
|
|
|
)
|
|
|
|
define_property(GLOBAL
|
|
|
|
PROPERTY LCOV_CAPTURE_FILES
|
|
|
|
BRIEF_DOCS "List of all capture files"
|
|
|
|
FULL_DOCS "All capture files which have coverage data included"
|
|
|
|
)
|
|
|
|
define_property(GLOBAL
|
|
|
|
PROPERTY LCOV_CAPTURE_INIT_FILES
|
|
|
|
BRIEF_DOCS "List of all init capture files"
|
|
|
|
FULL_DOCS "Empty capture files for the baseline coverage"
|
|
|
|
)
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(_coverage_path_dest _RETURNVAR PATH)
|
|
|
|
string(REPLACE "${CMAKE_CURRENT_BINARY_DIR}/" "" PATH "${PATH}")
|
|
|
|
if(IS_ABSOLUTE "${PATH}")
|
|
|
|
file(RELATIVE_PATH PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${PATH})
|
|
|
|
endif()
|
|
|
|
string(REPLACE ".." "__" PATH "${PATH}")
|
|
|
|
set("${_RETURNVAR}" "${PATH}" PARENT_SCOPE)
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(_coverage_filter_languages _RETURNVAR)
|
|
|
|
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
|
|
|
|
|
|
|
set(FILTERED_FILES)
|
|
|
|
foreach(FILE ${ARGN})
|
2018-12-18 19:03:05 +01:00
|
|
|
if(FILE MATCHES "^\\$<")
|
|
|
|
#ignore generator expressions
|
|
|
|
continue()
|
|
|
|
endif()
|
2018-11-20 06:51:34 +01:00
|
|
|
get_filename_component(FILE_EXT "${FILE}" EXT)
|
|
|
|
string(TOLOWER "${FILE_EXT}" FILE_EXT)
|
|
|
|
string(SUBSTRING "${FILE_EXT}" 1 -1 FILE_EXT)
|
|
|
|
foreach(LANG ${ENABLED_LANGUAGES})
|
|
|
|
if(FILE_EXT IN_LIST CMAKE_${LANG}_SOURCE_FILE_EXTENSIONS)
|
|
|
|
list(APPEND FILTERED_FILES "${FILE}")
|
|
|
|
endif()
|
|
|
|
endforeach()
|
|
|
|
endforeach()
|
|
|
|
set("${_RETURNVAR}" "${FILTERED_FILES}" PARENT_SCOPE)
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(coverage_add_target _TARGET)
|
|
|
|
cmake_parse_arguments(CAT "" "" "EXCEPT" ${ARGN})
|
|
|
|
|
2018-12-18 19:03:05 +01:00
|
|
|
get_target_property(TARGET_TYPE "${_TARGET}" TYPE)
|
|
|
|
if(TARGET_TYPE STREQUAL "INTERFACE_LIBRARY")
|
|
|
|
return()
|
|
|
|
endif()
|
|
|
|
|
2018-11-20 06:51:34 +01:00
|
|
|
get_property(COMPILE_FLAGS TARGET "${_TARGET}" PROPERTY COMPILE_FLAGS)
|
|
|
|
|
|
|
|
set_property(TARGET "${_TARGET}"
|
|
|
|
APPEND_STRING
|
|
|
|
PROPERTY COMPILE_FLAGS " ${COVERAGE_COMPILE_FLAGS}"
|
|
|
|
)
|
|
|
|
set_property(TARGET "${_TARGET}"
|
|
|
|
APPEND_STRING
|
|
|
|
PROPERTY LINK_FLAGS " ${COVERAGE_LINK_FLAGS}"
|
|
|
|
)
|
|
|
|
|
|
|
|
get_target_property(SOURCES "${_TARGET}" SOURCES)
|
|
|
|
set(COVERAGE_FILES)
|
|
|
|
foreach(SOURCE ${SOURCES})
|
|
|
|
if("${SOURCE}" IN_LIST CAT_EXCEPT)
|
|
|
|
continue()
|
|
|
|
endif()
|
|
|
|
_coverage_path_dest(RELSOURCE "${SOURCE}")
|
|
|
|
list(APPEND COVERAGE_FILES
|
|
|
|
"CMakeFiles/${_TARGET}.dir/${RELSOURCE}.gcno"
|
|
|
|
"CMakeFiles/${_TARGET}.dir/${RELSOURCE}.gcda"
|
|
|
|
)
|
|
|
|
endforeach()
|
|
|
|
|
|
|
|
set_property(GLOBAL
|
|
|
|
APPEND PROPERTY COVERAGE_TARGETS
|
|
|
|
"${_TARGET}"
|
|
|
|
)
|
|
|
|
set_property(DIRECTORY
|
|
|
|
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
|
|
|
|
${COVERAGE_FILES}
|
|
|
|
)
|
|
|
|
coverage_gcov_target(${_TARGET} EXCEPT "${CAT_EXCEPT}")
|
|
|
|
coverage_lcov_target(${_TARGET} EXCEPT "${CAT_EXCEPT}")
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(coverage_collect)
|
|
|
|
codecoverage_lcov_capture_initial()
|
|
|
|
codecoverage_lcov_capture()
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(coverage_gcov_target _TARGET)
|
|
|
|
cmake_parse_arguments(CGT "" "" "EXCEPT" ${ARGN})
|
|
|
|
|
|
|
|
set(GCOV_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_TARGET}.dir")
|
|
|
|
get_target_property(SOURCES "${_TARGET}" SOURCES)
|
|
|
|
_coverage_filter_languages(SOURCES ${SOURCES})
|
|
|
|
foreach(SOURCE ${SOURCES})
|
|
|
|
_coverage_path_dest(RELSOURCE "${SOURCE}")
|
|
|
|
if("${SOURCE}" IN_LIST CGT_EXCEPT)
|
|
|
|
continue()
|
|
|
|
endif()
|
|
|
|
get_filename_component(RELSOURCE_PATH "${RELSOURCE}" PATH)
|
|
|
|
|
|
|
|
add_custom_command(OUTPUT "${GCOV_DIR}/${RELSOURCE}.gcov"
|
|
|
|
COMMAND test -s "${GCOV_DIR}/${RELSOURCE}.gcda"
|
|
|
|
&& "${COV_BIN}" "${GCOV_DIR}/${RELSOURCE}.gcno" > /dev/null
|
|
|
|
|| true
|
|
|
|
DEPENDS "${_TARGET}" "${GCOV_DIR}/${RELSOURCE}.gcno" "${GCOV_DIR}/${RELSOURCE}.gcda"
|
|
|
|
WORKING_DIRECTORY "${GCOV_DIR}/${RELSOURCE_PATH}"
|
|
|
|
COMMENT "Capturing gcov data for source ${SOURCE} of target ${_TARGET}"
|
|
|
|
)
|
|
|
|
|
|
|
|
list(APPEND GCOV_FILES "${GCOV_DIR}/${RELSOURCE}.gcov")
|
|
|
|
endforeach()
|
|
|
|
add_custom_target("${_TARGET}-gcov"
|
|
|
|
DEPENDS ${GCOV_FILES}
|
|
|
|
COMMENT "Capturing gcov data of target ${_TARGET}"
|
|
|
|
)
|
|
|
|
add_dependencies(gcov "${_TARGET}-gcov")
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(coverage_lcov_target _TARGET)
|
|
|
|
coverage_lcov_target_initial("${_TARGET}" ${ARGN})
|
|
|
|
coverage_lcov_capture_target("${_TARGET}" ${ARGN})
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(coverage_lcov_target_initial _TARGET)
|
|
|
|
cmake_parse_arguments(CLTI "" "" "EXCEPT" ${ARGN})
|
|
|
|
|
|
|
|
set(LCOV_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_TARGET}.dir")
|
|
|
|
set(INIT_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_TARGET}-capture-init.dir")
|
|
|
|
get_target_property(SOURCES "${_TARGET}" SOURCES)
|
|
|
|
_coverage_filter_languages(SOURCES ${SOURCES})
|
|
|
|
|
|
|
|
set(GENINFO_FILES)
|
|
|
|
foreach(SOURCE ${SOURCES})
|
|
|
|
if("${SOURCE}" IN_LIST CLTI_EXCEPT)
|
|
|
|
continue()
|
|
|
|
endif()
|
|
|
|
|
|
|
|
# generate empty coverage files
|
|
|
|
_coverage_path_dest(RELSOURCE "${SOURCE}")
|
|
|
|
get_filename_component(RELSOURCE_DIR "${RELSOURCE}" DIRECTORY)
|
|
|
|
file(MAKE_DIRECTORY "${INIT_DIR}/${RELSOURCE_DIR}")
|
|
|
|
set(GENINFO_FILE "${INIT_DIR}/${RELSOURCE}.info.init")
|
|
|
|
list(APPEND GENINFO_FILES "${GENINFO_FILE}")
|
|
|
|
|
|
|
|
add_custom_command(OUTPUT "${GENINFO_FILE}"
|
|
|
|
COMMAND "${GENINFO_BIN}"
|
|
|
|
--quiet --base-directory "${PROJECT_SOURCE_DIR}" --initial
|
|
|
|
--gcov-tool "${COV_BIN}" --output-filename "${GENINFO_FILE}"
|
|
|
|
--no-external "${LCOV_DIR}/${RELSOURCE}.gcno"
|
|
|
|
DEPENDS "${_TARGET}"
|
|
|
|
COMMENT "Capturing initial coverage data for ${SOURCE}"
|
|
|
|
)
|
|
|
|
endforeach()
|
|
|
|
|
|
|
|
set(OUTFILE "${LCOV_DATA_PATH_INIT}/${_TARGET}.info")
|
|
|
|
coverage_lcov_merge_files(
|
|
|
|
OUTFILE "${OUTFILE}"
|
|
|
|
FILES ${GENINFO_FILES}
|
|
|
|
FLAGS "--initial"
|
|
|
|
REMOVE_PATTERNS
|
|
|
|
)
|
|
|
|
add_custom_target("${_TARGET}-capture-init"
|
|
|
|
DEPENDS "${OUTFILE}"
|
|
|
|
COMMENT "Capturing initial coverage data for target ${_TARGET}"
|
|
|
|
)
|
|
|
|
|
|
|
|
add_dependencies(lcov-capture-init "${_TARGET}-capture-init")
|
|
|
|
set_property(GLOBAL APPEND PROPERTY LCOV_CAPTURE_INIT_FILES "${OUTFILE}")
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(coverage_lcov_capture_target _TARGET)
|
|
|
|
cmake_parse_arguments(CLC "" "" "EXCEPT" ${ARGN})
|
|
|
|
|
|
|
|
set(LCOV_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_TARGET}.dir")
|
|
|
|
set(CAP_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_TARGET}-geninfo.dir")
|
|
|
|
set(INIT_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_TARGET}-capture-init.dir")
|
|
|
|
get_target_property(SOURCES "${_TARGET}" SOURCES)
|
|
|
|
_coverage_filter_languages(SOURCES ${SOURCES})
|
|
|
|
|
|
|
|
set(GCDA_FILES)
|
|
|
|
set(GENINFO_FILES)
|
|
|
|
foreach(SOURCE ${SOURCES})
|
|
|
|
if("${SOURCE}" IN_LIST CLC_EXCEPT)
|
|
|
|
continue()
|
|
|
|
endif()
|
|
|
|
|
|
|
|
_coverage_path_dest(RELSOURCE "${SOURCE}")
|
|
|
|
get_filename_component(RELSOURCE_DIR "${RELSOURCE}" DIRECTORY)
|
|
|
|
file(MAKE_DIRECTORY "${CAP_DIR}/${RELSOURCE_DIR}")
|
|
|
|
set(OUTFILE "${CAP_DIR}/${RELSOURCE}.info")
|
|
|
|
|
|
|
|
list(APPEND GENINFO_FILES "${OUTFILE}")
|
|
|
|
list(APPEND GCDA_FILES "${LCOV_DIR}/${RELSOURCE}.gcda")
|
|
|
|
|
|
|
|
add_custom_command(OUTPUT "${LCOV_DIR}/${RELSOURCE}.gcda"
|
|
|
|
COMMAND "${CMAKE_COMMAND}" -E touch "${LCOV_DIR}/${RELSOURCE}.gcda"
|
|
|
|
DEPENDS "${_TARGET}"
|
|
|
|
COMMENT "Touching ${LCOV_DIR}/${RELSOURCE}.gcda"
|
|
|
|
)
|
|
|
|
|
|
|
|
add_custom_command(OUTPUT "${OUTFILE}"
|
|
|
|
COMMAND test -s "${LCOV_DIR}/${RELSOURCE}.gcda"
|
|
|
|
&& "${GENINFO_BIN}" --quiet --base-directory
|
|
|
|
"${PROJECT_SOURCE_DIR}" --gcov-tool "${COV_BIN}"
|
|
|
|
--output-filename "${OUTFILE}" --no-external
|
2018-12-18 19:03:05 +01:00
|
|
|
--rc lcov_branch_coverage=1
|
2018-11-20 06:51:34 +01:00
|
|
|
"${LCOV_DIR}/${RELSOURCE}.gcda"
|
|
|
|
|| cp "${INIT_DIR}/${RELSOURCE}.info.init" "${OUTFILE}"
|
|
|
|
DEPENDS "${_TARGET}" "${_TARGET}-capture-init" "${LCOV_DIR}/${RELSOURCE}.gcda"
|
|
|
|
COMMENT "Capturing coverage data for ${SOURCE}"
|
|
|
|
)
|
|
|
|
endforeach()
|
|
|
|
|
|
|
|
# Concatenate all files generated by geninfo to a single file per target.
|
|
|
|
set(OUTFILE "${LCOV_DATA_PATH_CAPTURE}/${_TARGET}.info")
|
|
|
|
coverage_lcov_merge_files(OUTFILE "${OUTFILE}"
|
|
|
|
FILES ${GENINFO_FILES}
|
|
|
|
)
|
|
|
|
add_custom_target("${_TARGET}-geninfo"
|
|
|
|
DEPENDS "${OUTFILE}"
|
|
|
|
COMMENT "Capturing coverage data for target ${_TARGET}"
|
|
|
|
)
|
|
|
|
|
|
|
|
add_custom_target("${_TARGET}-geninfo-clean"
|
|
|
|
COMMAND "${CMAKE_COMMAND}" -E remove "${OUTFILE}" ${GCDA_FILES}
|
|
|
|
COMMENT "Cleaning coverage data of target ${_TARGET}"
|
|
|
|
)
|
|
|
|
|
|
|
|
add_dependencies(lcov-capture "${_TARGET}-geninfo")
|
|
|
|
set_property(GLOBAL APPEND PROPERTY LCOV_CAPTURE_FILES "${OUTFILE}")
|
|
|
|
|
|
|
|
# Add target for generating html output for this target only.
|
|
|
|
file(MAKE_DIRECTORY "${LCOV_HTML_PATH}/${_TARGET}")
|
|
|
|
add_custom_target("${_TARGET}-lcov"
|
|
|
|
COMMAND "${GENHTML_BIN}" --quiet --sort --prefix "${PROJECT_SOURCE_DIR}"
|
|
|
|
--baseline-file "${LCOV_DATA_PATH_INIT}/${_TARGET}.info"
|
|
|
|
--output-directory "${LCOV_HTML_PATH}/${_TARGET}"
|
2018-12-18 19:03:05 +01:00
|
|
|
--highlight --legend --show-details --branch-coverage --function-coverage
|
|
|
|
--title "${PROJECT_NAME}" --target "${_TARGET}"
|
2018-11-20 06:51:34 +01:00
|
|
|
--demangle-cpp "${OUTFILE}"
|
|
|
|
DEPENDS "${_TARGET}-geninfo" "${_TARGET}-capture-init"
|
|
|
|
COMMENT "Generating coverage report for target ${_TARGET}"
|
|
|
|
)
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(codecoverage_lcov_capture_initial)
|
|
|
|
set(INITCAPTURE_FILE "${LCOV_DATA_PATH_INIT}/all_targets.info")
|
|
|
|
set(INITCAPTURE_FILE_UPLOAD "${INITCAPTURE_FILE}.upload")
|
|
|
|
get_property(LCOV_CAPTURE_INIT_FILES GLOBAL PROPERTY LCOV_CAPTURE_INIT_FILES)
|
|
|
|
coverage_lcov_merge_files(OUTFILE "${INITCAPTURE_FILE}" FILES ${LCOV_CAPTURE_INIT_FILES})
|
|
|
|
add_custom_target(lcov-geninfo-init
|
|
|
|
DEPENDS ${INITCAPTURE_FILE} lcov-capture-init
|
|
|
|
COMMENT "Capturing global initial coverage data"
|
|
|
|
)
|
|
|
|
|
|
|
|
string(REPLACE "/" "\\/" PROJBINDIR_ESCAPED "${PROJECT_BINARY_DIR}/")
|
|
|
|
string(REPLACE "/" "\\/" PROJSRCDIR_ESCAPED "${PROJECT_SOURCE_DIR}/")
|
|
|
|
add_custom_command(OUTPUT "${INITCAPTURE_FILE_UPLOAD}"
|
|
|
|
COMMAND sed -e 's/${PROJBINDIR_ESCAPED}//g' -e 's/${PROJSRCDIR_ESCAPED}//g' "${INITCAPTURE_FILE}" > "${INITCAPTURE_FILE_UPLOAD}"
|
|
|
|
DEPENDS lcov-geninfo-init "${INITCAPTURE_FILE}"
|
|
|
|
COMMENT "Creating ${INITCAPTURE_FILE_UPLOAD}"
|
|
|
|
)
|
|
|
|
add_custom_target(lcov-geninfo-init-upload
|
|
|
|
DEPENDS "${INITCAPTURE_FILE_UPLOAD}"
|
|
|
|
COMMENT "Preparing ${INITCAPTURE_FILE_UPLOAD} for upload"
|
|
|
|
)
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(codecoverage_lcov_capture)
|
|
|
|
set(TOTALCAPTURE_FILE "${LCOV_DATA_PATH_CAPTURE}/all_targets.info")
|
|
|
|
set(TOTALCAPTURE_FILE_UPLOAD "${TOTALCAPTURE_FILE}.upload")
|
|
|
|
get_property(COVERAGE_TARGETS GLOBAL PROPERTY COVERAGE_TARGETS)
|
|
|
|
get_property(LCOV_CAPTURE_FILES GLOBAL PROPERTY LCOV_CAPTURE_FILES)
|
|
|
|
set(GENINFO_CLEAN_TARGETS)
|
|
|
|
set(GENINFO_TARGETS)
|
|
|
|
foreach(COVERAGE_TARGET ${COVERAGE_TARGETS})
|
|
|
|
list(APPEND GENINFO_TARGETS "${COVERAGE_TARGET}-geninfo")
|
|
|
|
list(APPEND GENINFO_CLEAN_TARGETS "${COVERAGE_TARGET}-geninfo-clean")
|
|
|
|
endforeach()
|
|
|
|
|
|
|
|
coverage_lcov_merge_files(OUTFILE "${TOTALCAPTURE_FILE}" FILES ${LCOV_CAPTURE_FILES})
|
|
|
|
add_custom_target(lcov-geninfo
|
|
|
|
DEPENDS ${GENINFO_TARGETS} "${TOTALCAPTURE_FILE}"
|
|
|
|
COMMENT "Capturing global coverage data"
|
|
|
|
)
|
|
|
|
|
|
|
|
string(REPLACE "/" "\\/" PROJBINDIR_ESCAPED "${PROJECT_BINARY_DIR}/")
|
|
|
|
string(REPLACE "/" "\\/" PROJSRCDIR_ESCAPED "${PROJECT_SOURCE_DIR}/")
|
|
|
|
add_custom_command(OUTPUT "${TOTALCAPTURE_FILE_UPLOAD}"
|
2018-11-29 01:35:13 +01:00
|
|
|
COMMAND sed -e 's/^SF:${PROJBINDIR_ESCAPED}/SF:/g' -e 's/^SF:${PROJSRCDIR_ESCAPED}/SF:/g' "${TOTALCAPTURE_FILE}" > "${TOTALCAPTURE_FILE_UPLOAD}"
|
2018-11-20 06:51:34 +01:00
|
|
|
DEPENDS lcov-geninfo "${TOTALCAPTURE_FILE}"
|
|
|
|
COMMENT "Creating ${TOTALCAPTURE_FILE_UPLOAD}"
|
|
|
|
)
|
|
|
|
add_custom_target(lcov-geninfo-upload
|
|
|
|
DEPENDS "${TOTALCAPTURE_FILE_UPLOAD}"
|
|
|
|
COMMENT "Preparing ${TOTALCAPTURE_FILE_UPLOAD} for upload"
|
|
|
|
)
|
|
|
|
|
|
|
|
add_custom_target(lcov-geninfo-clean
|
|
|
|
COMMAND "${CMAKE_COMMAND}" -E remove "${TOTALCAPTURE_FILE}" "${TOTALCAPTURE_FILE_UPLOAD}"
|
|
|
|
COMMENT "Cleaning global coverage data"
|
|
|
|
DEPENDS ${GENINFO_CLEAN_TARGETS}
|
|
|
|
)
|
|
|
|
|
|
|
|
file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/all_targets)
|
|
|
|
add_custom_target(lcov
|
|
|
|
COMMAND "${GENHTML_BIN}" --quiet --sort
|
|
|
|
--baseline-file "${LCOV_DATA_PATH_INIT}/all_targets.info"
|
|
|
|
--output-directory "${LCOV_HTML_PATH}/all_targets"
|
2018-12-18 19:03:05 +01:00
|
|
|
--highlight --legend --show-details --branch-coverage --function-coverage
|
2018-11-20 06:51:34 +01:00
|
|
|
--title "${CMAKE_PROJECT_NAME}" --prefix "${PROJECT_SOURCE_DIR}"
|
|
|
|
--demangle-cpp "${TOTALCAPTURE_FILE}"
|
|
|
|
DEPENDS lcov-geninfo-init lcov-geninfo
|
|
|
|
COMMENT "Generating global coverage report"
|
|
|
|
)
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(coverage_lcov_merge_files)
|
|
|
|
cmake_parse_arguments(CLMF "" "OUTFILE" "FILES;FLAGS;REMOVE_PATTERNS" ${ARGN})
|
|
|
|
set(OUTFILE "${CLMF_OUTFILE}")
|
|
|
|
|
|
|
|
# Generate merged file.
|
|
|
|
string(REPLACE "${CMAKE_BINARY_DIR}/" "" FILE_REL "${OUTFILE}")
|
|
|
|
add_custom_command(OUTPUT "${OUTFILE}.raw"
|
|
|
|
COMMAND cat ${CLMF_FILES} > ${OUTFILE}.raw
|
|
|
|
DEPENDS ${CLMF_FILES}
|
|
|
|
COMMENT "Generating ${FILE_REL}"
|
|
|
|
)
|
|
|
|
|
|
|
|
add_custom_command(OUTPUT "${OUTFILE}"
|
|
|
|
COMMAND "${LCOV_BIN}" --quiet -a "${OUTFILE}.raw" --output-file "${OUTFILE}"
|
2018-12-18 19:03:05 +01:00
|
|
|
--rc lcov_branch_coverage=1
|
2018-11-20 06:51:34 +01:00
|
|
|
--base-directory "${PROJECT_SOURCE_DIR}" ${CLMF_FLAGS}
|
|
|
|
COMMAND "${LCOV_BIN}" --quiet -r "${OUTFILE}" ${CLMF_REMOVE_PATTERNS}
|
2018-12-18 19:03:05 +01:00
|
|
|
--rc lcov_branch_coverage=1
|
2018-11-20 06:51:34 +01:00
|
|
|
--output-file "${OUTFILE}" ${CLMF_FLAGS}
|
|
|
|
DEPENDS "${OUTFILE}.raw"
|
|
|
|
COMMENT "Post-processing ${FILE_REL}"
|
|
|
|
)
|
|
|
|
endfunction()
|
|
|
|
|
|
|
|
function(add_coverage_upload_target_codecov_io)
|
|
|
|
cmake_parse_arguments(CU "" "GITSHA1;GITBRANCH;NAME" "" ${ARGN})
|
|
|
|
set(CAPTURE_FILES "${LCOV_DATA_PATH_INIT}/all_targets.info.upload" "${LCOV_DATA_PATH_CAPTURE}/all_targets.info.upload")
|
|
|
|
|
|
|
|
find_program(CURL_BIN curl)
|
|
|
|
if(NOT CURL_BIN)
|
|
|
|
message(FATAL_ERROR "curl not found")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
find_program(BASH_BIN bash)
|
|
|
|
if(NOT BASH_BIN)
|
|
|
|
message(FATAL_ERROR "bash not found")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
set(CODECOV_PATH "${PROJECT_BINARY_DIR}/codecov.sh")
|
|
|
|
|
|
|
|
set(CODECOV_SCRIPT_URL "https://codecov.io/bash" CACHE STRING "codecov.io bash script url")
|
|
|
|
set(CODECOV_FLAGS "" CACHE STRING "codecov.io flags")
|
|
|
|
string(REPLACE ";" "," CODECOV_FLAGS_ARG "${CODECOV_FLAGS}")
|
|
|
|
add_custom_command(OUTPUT "${CODECOV_PATH}"
|
|
|
|
COMMAND "${CURL_BIN}" "${CODECOV_SCRIPT_URL}" --insecure --output "${CODECOV_PATH}"
|
|
|
|
COMMENT "Fetching codecov.io bash script"
|
|
|
|
)
|
|
|
|
|
|
|
|
set(EXTRA_ARGS)
|
|
|
|
if(CU_GITSHA1)
|
|
|
|
list(APPEND EXTRA_ARGS -C "${CU_GITSHA1}")
|
|
|
|
endif()
|
|
|
|
if(CU_GITBRANCH)
|
|
|
|
list(APPEND EXTRA_ARGS -B "${CU_GITBRANCH}")
|
|
|
|
endif()
|
|
|
|
if(CU_NAME)
|
|
|
|
list(APPEND EXTRA_ARGS -n "${CU_NAME}")
|
|
|
|
endif()
|
|
|
|
foreach(CAPTURE_FILE ${CAPTURE_FILES})
|
|
|
|
list(APPEND EXTRA_ARGS -f "${CAPTURE_FILE}")
|
|
|
|
endforeach()
|
|
|
|
if(CODECOV_FLAG)
|
|
|
|
list(APPEND EXTRA_ARGS -F "${CODECOV_FLAGS_ARG}")
|
|
|
|
endif()
|
|
|
|
|
|
|
|
add_custom_target(coverage_upload
|
|
|
|
COMMAND "${BASH_BIN}" "${CODECOV_PATH}" ${EXTRA_ARGS}
|
|
|
|
-Z -A "--insecure" -U "--insecure"
|
|
|
|
-X gcov -X coveragepy -X search -X fix
|
|
|
|
DEPENDS "${CODECOV_PATH}" lcov-geninfo-upload lcov-geninfo-init-upload
|
|
|
|
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
|
|
|
|
COMMENT "Uploading coverage to codecov.io"
|
|
|
|
)
|
|
|
|
endfunction()
|