| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 | 
							- # This file is part of CMake-codecov.
 
- #
 
- # Copyright (c)
 
- #   2015-2017 RWTH Aachen University, Federal Republic of Germany
 
- #
 
- # See the LICENSE file in the package base directory for details
 
- #
 
- # Written by Alexander Haase, alexander.haase@rwth-aachen.de
 
- #
 
- # configuration
 
- set(LCOV_DATA_PATH "${CMAKE_BINARY_DIR}/lcov/data")
 
- set(LCOV_DATA_PATH_INIT "${LCOV_DATA_PATH}/init")
 
- set(LCOV_DATA_PATH_CAPTURE "${LCOV_DATA_PATH}/capture")
 
- set(LCOV_HTML_PATH "${CMAKE_BINARY_DIR}/lcov/html")
 
- # Search for Gcov which is used by Lcov.
 
- find_package(Gcov)
 
- # This function will add lcov evaluation for target <TNAME>. Only sources of
 
- # this target will be evaluated and no dependencies will be added. It will call
 
- # geninfo on any source file of <TNAME> once and store the info file in the same
 
- # directory.
 
- #
 
- # 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_lcov_target TNAME)
 
- 	if (LCOV_FOUND)
 
- 		# capture initial coverage data
 
- 		lcov_capture_initial_tgt(${TNAME})
 
- 		# capture coverage data after execution
 
- 		lcov_capture_tgt(${TNAME})
 
- 	endif ()
 
- endfunction (add_lcov_target)
 
- # include required Modules
 
- include(FindPackageHandleStandardArgs)
 
- # Search for required lcov binaries.
 
- find_program(LCOV_BIN lcov)
 
- find_program(GENINFO_BIN geninfo)
 
- find_program(GENHTML_BIN genhtml)
 
- find_package_handle_standard_args(lcov
 
- 	REQUIRED_VARS LCOV_BIN GENINFO_BIN GENHTML_BIN
 
- )
 
- # enable genhtml C++ demangeling, if c++filt is found.
 
- set(GENHTML_CPPFILT_FLAG "")
 
- find_program(CPPFILT_BIN c++filt)
 
- if (NOT CPPFILT_BIN STREQUAL "")
 
- 	set(GENHTML_CPPFILT_FLAG "--demangle-cpp")
 
- endif (NOT CPPFILT_BIN STREQUAL "")
 
- # enable no-external flag for lcov, if available.
 
- if (GENINFO_BIN AND NOT DEFINED GENINFO_EXTERN_FLAG)
 
- 	set(FLAG "")
 
- 	execute_process(COMMAND ${GENINFO_BIN} --help OUTPUT_VARIABLE GENINFO_HELP)
 
- 	string(REGEX MATCH "external" GENINFO_RES "${GENINFO_HELP}")
 
- 	if (GENINFO_RES)
 
- 		set(FLAG "--no-external")
 
- 	endif ()
 
- 	set(GENINFO_EXTERN_FLAG "${FLAG}"
 
- 		CACHE STRING "Geninfo flag to exclude system sources.")
 
- endif ()
 
- # If Lcov was not found, exit module now.
 
- if (NOT LCOV_FOUND)
 
- 	return()
 
- endif (NOT LCOV_FOUND)
 
- # Create directories to be used.
 
- file(MAKE_DIRECTORY ${LCOV_DATA_PATH_INIT})
 
- file(MAKE_DIRECTORY ${LCOV_DATA_PATH_CAPTURE})
 
- set(LCOV_REMOVE_PATTERNS "")
 
- # This function will merge lcov files to a single target file. Additional lcov
 
- # flags may be set with setting LCOV_EXTRA_FLAGS before calling this function.
 
- function (lcov_merge_files OUTFILE ...)
 
- 	# Remove ${OUTFILE} from ${ARGV} and generate lcov parameters with files.
 
- 	list(REMOVE_AT ARGV 0)
 
- 	# Generate merged file.
 
- 	string(REPLACE "${CMAKE_BINARY_DIR}/" "" FILE_REL "${OUTFILE}")
 
- 	add_custom_command(OUTPUT "${OUTFILE}.raw"
 
- 		COMMAND cat ${ARGV} > ${OUTFILE}.raw
 
- 		DEPENDS ${ARGV}
 
- 		COMMENT "Generating ${FILE_REL}"
 
- 	)
 
- 	add_custom_command(OUTPUT "${OUTFILE}"
 
- 		COMMAND ${LCOV_BIN} --quiet -a ${OUTFILE}.raw --output-file ${OUTFILE}
 
- 			--base-directory ${PROJECT_SOURCE_DIR} ${LCOV_EXTRA_FLAGS}
 
- 		COMMAND ${LCOV_BIN} --quiet -r ${OUTFILE} ${LCOV_REMOVE_PATTERNS}
 
- 			--output-file ${OUTFILE} ${LCOV_EXTRA_FLAGS}
 
- 		DEPENDS ${OUTFILE}.raw
 
- 		COMMENT "Post-processing ${FILE_REL}"
 
- 	)
 
- endfunction ()
 
- # Add a new global target to generate initial coverage reports for all targets.
 
- # This target will be used to generate the global initial info file, which is
 
- # used to gather even empty report data.
 
- if (NOT TARGET lcov-capture-init)
 
- 	add_custom_target(lcov-capture-init)
 
- 	set(LCOV_CAPTURE_INIT_FILES "" CACHE INTERNAL "")
 
- endif (NOT TARGET lcov-capture-init)
 
- # This function will add initial capture of coverage data for target <TNAME>,
 
- # which is needed to get also data for objects, which were not loaded at
 
- # execution time. It will call geninfo for every source file of <TNAME> once and
 
- # store the info file in the same directory.
 
- function (lcov_capture_initial_tgt TNAME)
 
- 	# 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(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
 
- 	set(GENINFO_FILES "")
 
- 	foreach(FILE ${SOURCES})
 
- 		# generate empty coverage files
 
- 		set(OUTFILE "${TDIR}/${FILE}.info.init")
 
- 		list(APPEND GENINFO_FILES ${OUTFILE})
 
- 		add_custom_command(OUTPUT ${OUTFILE} COMMAND ${GCOV_ENV} ${GENINFO_BIN}
 
- 				--quiet --base-directory ${PROJECT_SOURCE_DIR} --initial
 
- 				--gcov-tool ${GCOV_BIN} --output-filename ${OUTFILE}
 
- 				${GENINFO_EXTERN_FLAG} ${TDIR}/${FILE}.gcno
 
- 			DEPENDS ${TNAME}
 
- 			COMMENT "Capturing initial coverage data for ${FILE}"
 
- 		)
 
- 	endforeach()
 
- 	# Concatenate all files generated by geninfo to a single file per target.
 
- 	set(OUTFILE "${LCOV_DATA_PATH_INIT}/${TNAME}.info")
 
- 	set(LCOV_EXTRA_FLAGS "--initial")
 
- 	lcov_merge_files("${OUTFILE}" ${GENINFO_FILES})
 
- 	add_custom_target(${TNAME}-capture-init ALL DEPENDS ${OUTFILE})
 
- 	# add geninfo file generation to global lcov-geninfo target
 
- 	add_dependencies(lcov-capture-init ${TNAME}-capture-init)
 
- 	set(LCOV_CAPTURE_INIT_FILES "${LCOV_CAPTURE_INIT_FILES}"
 
- 		"${OUTFILE}" CACHE INTERNAL ""
 
- 	)
 
- endfunction (lcov_capture_initial_tgt)
 
- # This function will generate the global info file for all targets. It has to be
 
- # called after all other CMake functions in the root CMakeLists.txt file, to get
 
- # a full list of all targets that generate coverage data.
 
- function (lcov_capture_initial)
 
- 	# Skip this function (and do not create the following targets), if there are
 
- 	# no input files.
 
- 	if ("${LCOV_CAPTURE_INIT_FILES}" STREQUAL "")
 
- 		return()
 
- 	endif ()
 
- 	# Add a new target to merge the files of all targets.
 
- 	set(OUTFILE "${LCOV_DATA_PATH_INIT}/all_targets.info")
 
- 	lcov_merge_files("${OUTFILE}" ${LCOV_CAPTURE_INIT_FILES})
 
- 	add_custom_target(lcov-geninfo-init ALL	DEPENDS ${OUTFILE}
 
- 		lcov-capture-init
 
- 	)
 
- endfunction (lcov_capture_initial)
 
- # Add a new global target to generate coverage reports for all targets. This
 
- # target will be used to generate the global info file.
 
- if (NOT TARGET lcov-capture)
 
- 	add_custom_target(lcov-capture)
 
- 	set(LCOV_CAPTURE_FILES "" CACHE INTERNAL "")
 
- endif (NOT TARGET lcov-capture)
 
- # This function will add capture of coverage data for target <TNAME>, which is
 
- # needed to get also data for objects, which were not loaded at execution time.
 
- # It will call geninfo for every source file of <TNAME> once and store the info
 
- # file in the same directory.
 
- function (lcov_capture_tgt TNAME)
 
- 	# 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(TDIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TNAME}.dir)
 
- 	set(GENINFO_FILES "")
 
- 	foreach(FILE ${SOURCES})
 
- 		# Generate coverage files. If no .gcda file was generated during
 
- 		# execution, the empty coverage file will be used instead.
 
- 		set(OUTFILE "${TDIR}/${FILE}.info")
 
- 		list(APPEND GENINFO_FILES ${OUTFILE})
 
- 		add_custom_command(OUTPUT ${OUTFILE}
 
- 			COMMAND test -f "${TDIR}/${FILE}.gcda"
 
- 				&& ${GCOV_ENV} ${GENINFO_BIN} --quiet --base-directory
 
- 					${PROJECT_SOURCE_DIR} --gcov-tool ${GCOV_BIN}
 
- 					--output-filename ${OUTFILE} ${GENINFO_EXTERN_FLAG}
 
- 					${TDIR}/${FILE}.gcda
 
- 				|| cp ${OUTFILE}.init ${OUTFILE}
 
- 			DEPENDS ${TNAME} ${TNAME}-capture-init
 
- 			COMMENT "Capturing coverage data for ${FILE}"
 
- 		)
 
- 	endforeach()
 
- 	# Concatenate all files generated by geninfo to a single file per target.
 
- 	set(OUTFILE "${LCOV_DATA_PATH_CAPTURE}/${TNAME}.info")
 
- 	lcov_merge_files("${OUTFILE}" ${GENINFO_FILES})
 
- 	add_custom_target(${TNAME}-geninfo DEPENDS ${OUTFILE})
 
- 	# add geninfo file generation to global lcov-capture target
 
- 	add_dependencies(lcov-capture ${TNAME}-geninfo)
 
- 	set(LCOV_CAPTURE_FILES "${LCOV_CAPTURE_FILES}" "${OUTFILE}" CACHE INTERNAL
 
- 		""
 
- 	)
 
- 	# Add target for generating html output for this target only.
 
- 	file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/${TNAME})
 
- 	add_custom_target(${TNAME}-genhtml
 
- 		COMMAND ${GENHTML_BIN} --quiet --sort --prefix ${PROJECT_SOURCE_DIR}
 
- 			--baseline-file ${LCOV_DATA_PATH_INIT}/${TNAME}.info
 
- 			--output-directory ${LCOV_HTML_PATH}/${TNAME}
 
- 			--title "${CMAKE_PROJECT_NAME} - target ${TNAME}"
 
- 			${GENHTML_CPPFILT_FLAG} ${OUTFILE}
 
- 		DEPENDS ${TNAME}-geninfo ${TNAME}-capture-init
 
- 	)
 
- endfunction (lcov_capture_tgt)
 
- # This function will generate the global info file for all targets. It has to be
 
- # called after all other CMake functions in the root CMakeLists.txt file, to get
 
- # a full list of all targets that generate coverage data.
 
- function (lcov_capture)
 
- 	# Skip this function (and do not create the following targets), if there are
 
- 	# no input files.
 
- 	if ("${LCOV_CAPTURE_FILES}" STREQUAL "")
 
- 		return()
 
- 	endif ()
 
- 	# Add a new target to merge the files of all targets.
 
- 	set(OUTFILE "${LCOV_DATA_PATH_CAPTURE}/all_targets.info")
 
- 	lcov_merge_files("${OUTFILE}" ${LCOV_CAPTURE_FILES})
 
- 	add_custom_target(lcov-geninfo DEPENDS ${OUTFILE} lcov-capture)
 
- 	# Add a new global target for all lcov targets. This target could be used to
 
- 	# generate the lcov html output for the whole project instead of calling
 
- 	# <TARGET>-geninfo and <TARGET>-genhtml for each target. It will also be
 
- 	# used to generate a html site for all project data together instead of one
 
- 	# for each target.
 
- 	if (NOT TARGET lcov)
 
- 		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
 
- 				--title "${CMAKE_PROJECT_NAME}" --prefix "${PROJECT_SOURCE_DIR}"
 
- 				${GENHTML_CPPFILT_FLAG} ${OUTFILE}
 
- 			DEPENDS lcov-geninfo-init lcov-geninfo
 
- 		)
 
- 	endif ()
 
- endfunction (lcov_capture)
 
- # Add a new global target to generate the lcov html report for the whole project
 
- # instead of calling <TARGET>-genhtml for each target (to create an own report
 
- # for each target). Instead of the lcov target it does not require geninfo for
 
- # all targets, so you have to call <TARGET>-geninfo to generate the info files
 
- # the targets you'd like to have in your report or lcov-geninfo for generating
 
- # info files for all targets before calling lcov-genhtml.
 
- file(MAKE_DIRECTORY ${LCOV_HTML_PATH}/selected_targets)
 
- if (NOT TARGET lcov-genhtml)
 
- 	add_custom_target(lcov-genhtml
 
- 		COMMAND ${GENHTML_BIN}
 
- 			--quiet
 
- 			--output-directory ${LCOV_HTML_PATH}/selected_targets
 
- 			--title \"${CMAKE_PROJECT_NAME} - targets  `find
 
- 				${LCOV_DATA_PATH_CAPTURE} -name \"*.info\" ! -name
 
- 				\"all_targets.info\" -exec basename {} .info \\\;`\"
 
- 			--prefix ${PROJECT_SOURCE_DIR}
 
- 			--sort
 
- 			${GENHTML_CPPFILT_FLAG}
 
- 			`find ${LCOV_DATA_PATH_CAPTURE} -name \"*.info\" ! -name
 
- 				\"all_targets.info\"`
 
- 	)
 
- endif (NOT TARGET lcov-genhtml)
 
 
  |