From 911b97867b72226df7cfab95374a6c2b89d9ffa3 Mon Sep 17 00:00:00 2001 From: Cristian Morales Vega Date: Tue, 23 Apr 2019 17:12:11 +0100 Subject: CTestCoverageCollectGCOV: run gcov only once Running gcov once per .gcda file is not only inefficient, it also generates wrong data since .gcov files can get overwritten and in general gcov works with less information. fakegcov.cmake needs to be able to handle multiple .gcda files for the test to be meaningful. --- Modules/CTestCoverageCollectGCOV.cmake | 38 +++++++++++---------------- Tests/CTestCoverageCollectGCOV/fakegcov.cmake | 21 ++++++++------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake index 2258271..8b029ee 100644 --- a/Modules/CTestCoverageCollectGCOV.cmake +++ b/Modules/CTestCoverageCollectGCOV.cmake @@ -95,7 +95,7 @@ function(ctest_coverage_collect_gcov) set(gcda_files) set(label_files) if (GCOV_GLOB) - file(GLOB_RECURSE gfiles RELATIVE ${binary_dir} "${binary_dir}/*.gcda") + file(GLOB_RECURSE gfiles "${binary_dir}/*.gcda") list(LENGTH gfiles len) # if we have gcda files then also grab the labels file for that target if(${len} GREATER 0) @@ -109,7 +109,7 @@ function(ctest_coverage_collect_gcov) file(STRINGS "${binary_dir}/CMakeFiles/TargetDirectories.txt" target_dirs ENCODING UTF-8) foreach(target_dir ${target_dirs}) - file(GLOB_RECURSE gfiles RELATIVE ${binary_dir} "${target_dir}/*.gcda") + file(GLOB_RECURSE gfiles "${target_dir}/*.gcda") list(LENGTH gfiles len) # if we have gcda files then also grab the labels file for that target if(${len} GREATER 0) @@ -132,27 +132,21 @@ function(ctest_coverage_collect_gcov) # setup the dir for the coverage files set(coverage_dir "${binary_dir}/Testing/CoverageInfo") file(MAKE_DIRECTORY "${coverage_dir}") - # call gcov on each .gcda file - foreach (gcda_file ${gcda_files}) - # get the directory of the gcda file - get_filename_component(gcda_file ${binary_dir}/${gcda_file} ABSOLUTE) - get_filename_component(gcov_dir ${gcda_file} DIRECTORY) - # run gcov, this will produce the .gcov file in the current - # working directory - if(NOT DEFINED GCOV_GCOV_OPTIONS) - set(GCOV_GCOV_OPTIONS -b) - endif() - execute_process(COMMAND - ${gcov_command} ${GCOV_GCOV_OPTIONS} -o ${gcov_dir} ${gcda_file} - OUTPUT_VARIABLE out - RESULT_VARIABLE res - WORKING_DIRECTORY ${coverage_dir}) - - if (GCOV_DELETE) - file(REMOVE ${gcda_file}) - endif() + # run gcov, this will produce the .gcov files in the current + # working directory + if(NOT DEFINED GCOV_GCOV_OPTIONS) + set(GCOV_GCOV_OPTIONS -b) + endif() + execute_process(COMMAND + ${gcov_command} ${GCOV_GCOV_OPTIONS} ${gcda_files} + OUTPUT_VARIABLE out + RESULT_VARIABLE res + WORKING_DIRECTORY ${coverage_dir}) + + if (GCOV_DELETE) + file(REMOVE ${gcda_files}) + endif() - endforeach() if(NOT "${res}" EQUAL 0) if (NOT GCOV_QUIET) message(STATUS "Error running gcov: ${res} ${out}") diff --git a/Tests/CTestCoverageCollectGCOV/fakegcov.cmake b/Tests/CTestCoverageCollectGCOV/fakegcov.cmake index b0c3a9b..6df4292 100644 --- a/Tests/CTestCoverageCollectGCOV/fakegcov.cmake +++ b/Tests/CTestCoverageCollectGCOV/fakegcov.cmake @@ -1,14 +1,17 @@ +function(create_gcov_file gcda_full_path) + get_filename_component(gcda_name ${gcda_full_path} NAME) + string(REPLACE ".gcda" ".gcov" gcov_name "${gcda_name}") + + file(STRINGS "${gcda_full_path}" source_file LIMIT_COUNT 1 ENCODING UTF-8) + + file(WRITE "${CMAKE_SOURCE_DIR}/${gcov_name}" + " -: 0:Source:${source_file}" + ) +endfunction() + foreach(I RANGE 0 ${CMAKE_ARGC}) if("${CMAKE_ARGV${I}}" MATCHES ".*\\.gcda") set(gcda_file "${CMAKE_ARGV${I}}") + create_gcov_file(${gcda_file}) endif() endforeach() - -get_filename_component(gcda_name ${gcda_file} NAME) -string(REPLACE ".gcda" ".gcov" gcov_name "${gcda_name}") - -file(STRINGS "${gcda_file}" source_file LIMIT_COUNT 1 ENCODING UTF-8) - -file(WRITE "${CMAKE_SOURCE_DIR}/${gcov_name}" - " -: 0:Source:${source_file}" -) -- cgit v0.12 From 41d262bd3ddf752a28f8e926b19bcc24224f8303 Mon Sep 17 00:00:00 2001 From: Cristian Morales Vega Date: Tue, 23 Apr 2019 17:17:26 +0100 Subject: CTestCoverageCollectGCOV: run gcov with -x Using "-x" we avoid overwriting .gcov files from source files in different paths which happen to have the same name. It's similar to "-p", but it produces shorter file names, reducing the risk of reaching the file system limit. --- Modules/CTestCoverageCollectGCOV.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake index 8b029ee..655827a 100644 --- a/Modules/CTestCoverageCollectGCOV.cmake +++ b/Modules/CTestCoverageCollectGCOV.cmake @@ -52,7 +52,7 @@ After generating this tar file, it can be sent to CDash for display with the ``GCOV_OPTIONS ...`` Specify options to be passed to gcov. The ``gcov`` command is run as ``gcov ... -o .gcda``. - If not specified, the default option is just ``-b``. + If not specified, the default option is just ``-b -x``. ``GLOB`` Recursively search for .gcda files in build_dir rather than @@ -135,7 +135,7 @@ function(ctest_coverage_collect_gcov) # run gcov, this will produce the .gcov files in the current # working directory if(NOT DEFINED GCOV_GCOV_OPTIONS) - set(GCOV_GCOV_OPTIONS -b) + set(GCOV_GCOV_OPTIONS -b -x) endif() execute_process(COMMAND ${gcov_command} ${GCOV_GCOV_OPTIONS} ${gcda_files} -- cgit v0.12