diff --git a/Help/release/dev/CTestCoverageCollectGCOV-refinements.rst b/Help/release/dev/CTestCoverageCollectGCOV-refinements.rst new file mode 100644 index 000000000..afa0a52fd --- /dev/null +++ b/Help/release/dev/CTestCoverageCollectGCOV-refinements.rst @@ -0,0 +1,6 @@ +CTestCoverageCollectGCOV-refinements +------------------------------------ + +* The :module:`CTestCoverageCollectGCOV` module was introduced as an + alternative to the :command:`ctest_coverage` command for collecting + ``gcov`` results for submission to CDash. diff --git a/Modules/CTestCoverageCollectGCOV.cmake b/Modules/CTestCoverageCollectGCOV.cmake index f6616e0df..a607c529a 100644 --- a/Modules/CTestCoverageCollectGCOV.cmake +++ b/Modules/CTestCoverageCollectGCOV.cmake @@ -19,6 +19,7 @@ # ctest_coverage_collect_gcov(TARBALL # [SOURCE ][BUILD ] # [GCOV_COMMAND ] +# [GCOV_OPTIONS ...] # ) # # Run gcov and package a tar file for CDash. The options are: @@ -39,6 +40,11 @@ # ``GCOV_COMMAND `` # Specify the full path to the ``gcov`` command on the machine. # Default is the value of :variable:`CTEST_COVERAGE_COMMAND`. +# +# ``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``. #============================================================================= # Copyright 2014-2015 Kitware, Inc. @@ -56,7 +62,7 @@ include(CMakeParseArguments) function(ctest_coverage_collect_gcov) set(options "") set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND) - set(multiValueArgs "") + set(multiValueArgs GCOV_OPTIONS) cmake_parse_arguments(GCOV "${options}" "${oneValueArgs}" "${multiValueArgs}" "" ${ARGN} ) if(NOT DEFINED GCOV_TARBALL) @@ -84,7 +90,8 @@ function(ctest_coverage_collect_gcov) # look for gcda files in the target directories # could do a glob from the top of the binary tree but # this will be faster and only look where the files will be - file(STRINGS "${binary_dir}/CMakeFiles/TargetDirectories.txt" target_dirs) + 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") list(LENGTH gfiles len) @@ -113,11 +120,18 @@ function(ctest_coverage_collect_gcov) 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} -b -o ${gcov_dir} ${gcda_file} + ${gcov_command} ${GCOV_GCOV_OPTIONS} -o ${gcov_dir} ${gcda_file} OUTPUT_VARIABLE out + RESULT_VARIABLE res WORKING_DIRECTORY ${coverage_dir}) endforeach() + if(NOT "${res}" EQUAL 0) + message(STATUS "Error running gcov: ${res} ${out}") + endif() # create json file with project information file(WRITE ${coverage_dir}/data.json "{ @@ -130,9 +144,16 @@ function(ctest_coverage_collect_gcov) # tar up the coverage info with the same date so that the md5 # sum will be the same for the tar file independent of file time # stamps + string(REPLACE ";" "\n" gcov_files "${gcov_files}") + string(REPLACE ";" "\n" label_files "${label_files}") + file(WRITE "${coverage_dir}/coverage_file_list.txt" + "${gcov_files} +${coverage_dir}/data.json +${label_files} +") execute_process(COMMAND ${CMAKE_COMMAND} -E tar cvfj ${GCOV_TARBALL} - "--mtime=1970-01-01 0:0:0 UTC" ${gcov_files} - ${coverage_dir}/data.json ${label_files} + "--mtime=1970-01-01 0:0:0 UTC" + --files-from=${coverage_dir}/coverage_file_list.txt WORKING_DIRECTORY ${binary_dir}) endfunction() diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 035f161a9..7e7aa2ec8 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2268,6 +2268,18 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release set_tests_properties(CTestTestUpload PROPERTIES PASS_REGULAR_EXPRESSION "Upload\\.xml") + configure_file( + "${CMake_SOURCE_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake.in" + "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake" + @ONLY ESCAPE_QUOTES) + add_test(CTestCoverageCollectGCOV ${CMAKE_CTEST_COMMAND} + -S "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/test.cmake" -VV + --output-log "${CMake_BINARY_DIR}/Tests/CTestCoverageCollectGCOV/testOut.log" + ) + set_tests_properties(CTestCoverageCollectGCOV PROPERTIES + PASS_REGULAR_EXPRESSION + "PASSED with correct output.*Testing/CoverageInfo/echoargs.gcov") + configure_file( "${CMake_SOURCE_DIR}/Tests/CTestTestEmptyBinaryDirectory/test.cmake.in" "${CMake_BINARY_DIR}/Tests/CTestTestEmptyBinaryDirectory/test.cmake" diff --git a/Tests/CTestCoverageCollectGCOV/fakegcov.cmake b/Tests/CTestCoverageCollectGCOV/fakegcov.cmake new file mode 100644 index 000000000..e704f14ca --- /dev/null +++ b/Tests/CTestCoverageCollectGCOV/fakegcov.cmake @@ -0,0 +1,8 @@ +foreach(I RANGE 0 ${CMAKE_ARGC}) + if("${CMAKE_ARGV${I}}" MATCHES ".*\\.gcda") + set(gcda_file "${CMAKE_ARGV${I}}") + endif() +endforeach() +get_filename_component(gcda_file ${gcda_file} NAME_WE) +file(WRITE "${CMAKE_SOURCE_DIR}/${gcda_file}.gcov" +"fake gcov file") diff --git a/Tests/CTestCoverageCollectGCOV/test.cmake.in b/Tests/CTestCoverageCollectGCOV/test.cmake.in new file mode 100644 index 000000000..4bdcb10e4 --- /dev/null +++ b/Tests/CTestCoverageCollectGCOV/test.cmake.in @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 2.8.12) +set(CTEST_PROJECT_NAME "SmallAndFast") +set(CTEST_SOURCE_DIRECTORY "@CMake_SOURCE_DIR@/Tests/CTestTest/SmallAndFast") +set(CTEST_BINARY_DIRECTORY "@CMake_BINARY_DIR@/Tests/CTestCoverageCollectGCOV") +set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@") +ctest_start(Experimental) +ctest_configure() +ctest_build() +ctest_test() + +file(WRITE ${CTEST_BINARY_DIRECTORY}/CMakeFiles/echoargs.dir/echoargs.gcda +"dummy +") + +include(CTestCoverageCollectGCOV) +set(tar_file ${CTEST_BINARY_DIRECTORY}/gcov.tar) +ctest_coverage_collect_gcov( + TARBALL "${tar_file}" + SOURCE "${CTEST_SOURCE_DIRECTORY}" + BUILD "${CTEST_BINARY_DIRECTORY}" + GCOV_COMMAND "${CMAKE_COMMAND}" + GCOV_OPTIONS -P "@CMake_SOURCE_DIR@/Tests/CTestCoverageCollectGCOV/fakegcov.cmake") + +execute_process(COMMAND + ${CMAKE_COMMAND} -E tar tf ${tar_file} + OUTPUT_VARIABLE out + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + +set(expected_out +"Testing/CoverageInfo/echoargs.gcov +Testing/CoverageInfo/data.json +CMakeFiles/echoargs.dir/Labels.json +") + +if("${out}" STREQUAL "${expected_out}") + message("PASSED with correct output: ${out}") +else() + message(FATAL_ERROR "FAILED: expected:\n${expected_out}\nGot:\n${out}") +endif()