From 36c1eb6975827e89a906e2dae90e92ee4a0f2bfb Mon Sep 17 00:00:00 2001 From: Matt Clarkson Date: Thu, 30 Apr 2015 14:28:04 +0100 Subject: [PATCH] Coverage support with LCOV and GCOV This patch adds a `coverage` target that allows coverage statisitics to be retrieved for the project. It requires that lcov and gcov is installed and that the generator is unix makefiles but this can be improved upon in future releases. To make it work use the coverage build type: ``` cmake -DCMAKE_BUILD_TYPE=Coverage . make coverage ``` --- .gitignore | 4 ++++ CMakeLists.txt | 21 +++++++++++++++++++++ test/CMakeLists.txt | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/.gitignore b/.gitignore index f7dcf8f3..3c1b4f21 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,10 @@ *.pyc __pycache__ +# lcov +*.lcov +/lcov + # cmake files. /Testing CMakeCache.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f09ceae..20aec17e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,27 @@ if (BENCHMARK_ENABLE_LTO) endif() endif() +# Coverage build type +set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING + "Flags used by the C++ compiler during coverage builds." + FORCE) +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE STRING + "Flags used for linking binaries during coverage builds." + FORCE) +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING + "Flags used by the shared libraries linker during coverage builds." + FORCE) +mark_as_advanced( + CMAKE_CXX_FLAGS_COVERAGE + CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE) +set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING + "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage." + FORCE) +add_cxx_compiler_flag(--coverage COVERAGE) + # C++ feature checks cxx_feature_check(STD_REGEX) cxx_feature_check(GNU_POSIX_REGEX) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7c4eae19..5a63b170 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -43,3 +43,45 @@ compile_benchmark_test(cxx03_test) set_target_properties(cxx03_test PROPERTIES COMPILE_FLAGS "${CXX03_FLAGS}") add_test(cxx03 cxx03_test --benchmark_min_time=0.01) + +# Add the coverage command(s) +string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER) +if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage") + find_program(GCOV gcov) + find_program(LCOV lcov) + find_program(GENHTML genhtml) + find_program(CTEST ctest) + if (GCOV AND LCOV AND GENHTML AND CTEST AND HAVE_CXX_FLAG_COVERAGE) + add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/lcov/index.html + COMMAND ${LCOV} -q -z -d . + COMMAND ${LCOV} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o before.lcov -i + COMMAND ${CTEST} --force-new-ctest-process + COMMAND ${LCOV} -q --no-external -c -b "${CMAKE_SOURCE_DIR}" -d . -o after.lcov + COMMAND ${LCOV} -q -a before.lcov -a after.lcov --output-file final.lcov + COMMAND ${LCOV} -q -r final.lcov "'${CMAKE_SOURCE_DIR}/test/*'" -o final.lcov + COMMAND ${GENHTML} final.lcov -o lcov --demangle-cpp --sort -p "${CMAKE_BINARY_DIR}" -t benchmark + DEPENDS filter_test benchmark_test options_test basic_test fixture_test cxx03_test + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Running LCOV" + ) + add_custom_target(coverage + DEPENDS ${CMAKE_BINARY_DIR}/lcov/index.html + COMMENT "LCOV report at lcov/index.html" + ) + message(STATUS "Coverage command added") + else() + if (HAVE_CXX_FLAG_COVERAGE) + set(CXX_FLAG_COVERAGE_MESSAGE supported) + else() + set(CXX_FLAG_COVERAGE_MESSAGE unavailable) + endif() + message(WARNING + "Coverage not available:\n" + " gcov: ${GCOV}\n" + " lcov: ${LCOV}\n" + " genhtml: ${GENHTML}\n" + " ctest: ${CTEST}\n" + " --coverage flag: ${CXX_FLAG_COVERAGE_MESSAGE}") + endif() +endif()