timescaledb/codecov/CMakeLists.txt
Erik Nordström e1b9e02e12 Cleanup code coverage and make it work locally
The code coverage options for CMake have been cleaned up and fixed
where they were broken. Build targets for local coverage reports now
work. The option to enable code coverage has been changed to
`-DCODECOVERAGE=ON` and local HTML-based reports can be generated
using the `lcov` program through the following steps:

1. `make install`
2. `make installcheck`
3. `make coverage`

The previous CMake options and targets didn't properly work, and often
included redundant and confusing options.

For instance, the only compiler option needed for code coverage is
`--coverage` as this is an alias for `-fprofile-arcs
-ftest-coverage`. Previously, however, these options were added
multiple times in various places, often all of them, but sometimes
only a subset for no apparent reason. They were also added using the
wrong CMake commands, for instance `add_definitions`, which is
deprecated and reserved for preprocessor definitions and not compiler
options.

The `lcov` program is used to generate local HTML-based code coverage
reports. Although CMake was setup to look for `lcov`, it didn't check
for failure cases in case it wasn't found and further had incomplete
target configurations that really didn't do much. No additional
documentation was provided on how to generate local coverage
reports. All of this has been fixed, including documentation in
`codecov/README.md`.
2020-05-19 22:08:23 +02:00

116 lines
3.8 KiB
CMake

# CMake targets for generating code coverage reports
#
# Note that the targets in here are not needed to enable code coverage
# on builds. To have builds generate code coverage metadata, one only
# has to enable the --coverage option for the compiler and this is
# done in the top-level CMakeLists.txt so that the option covers all
# build targets in the project.
#
# Given that all dependencies (lcov, genhtml) are installed, and CMake
# is initialized with -DCODECOVERAGE=ON, it should be
# possible to generate a code coverage report by running:
#
# $ make coverage
#
# The report is generated in REPORT_DIR and can be viewed in a web
# browser.
# Find lcov for html output
find_program(LCOV lcov)
if (LCOV)
# Final tracefile for code coverage
set(OUTPUT_FILE "timescaledb-codecov.info")
# Directory where to generate the HTML report
set(REPORT_DIR "codecov-report")
# The baseline run needs to run before tests to learn what zero
# coverage looks like
add_custom_command(
OUTPUT ${OUTPUT_FILE}.base
COMMENT "Generating code coverage base file"
COMMAND ${LCOV}
--capture
--initial # Initial run
--no-external # Do not include external source files
--base-directory ${CMAKE_SOURCE_DIR}
--directory ${CMAKE_BINARY_DIR}
--output-file ${OUTPUT_FILE}.base
DEPENDS timescaledb-tsl timescaledb timescaledb-loader)
add_custom_target(coverage_base
DEPENDS
timescaledb-tsl
timescaledb
timescaledb-loader
${OUTPUT_FILE}.base)
# Ensure baseline file is generated before tests
add_dependencies(installcheck coverage_base)
# The test run needs to run after tests to analyze the test coverage
add_custom_command(
OUTPUT ${OUTPUT_FILE}.test
COMMENT "Generating code coverage test file"
COMMAND ${LCOV}
--capture
--no-external
--base-directory ${CMAKE_SOURCE_DIR}
--directory ${CMAKE_BINARY_DIR}
--output-file ${OUTPUT_FILE}.test
DEPENDS ${OUTPUT_FILE}.base coverage_base)
# Make sure coverage_test runs after tests (installcheck) finish
add_custom_target(coverage_test DEPENDS ${OUTPUT_FILE}.test)
add_dependencies(installcheck-post-hook coverage_test)
# Generate the final coverage file by combining the pre and post
# test tracefiles
add_custom_command(
OUTPUT ${OUTPUT_FILE}
COMMENT "Generating final code coverage file"
COMMAND ${LCOV}
--add-tracefile ${OUTPUT_FILE}.base
--add-tracefile ${OUTPUT_FILE}.test
--output-file ${OUTPUT_FILE}
DEPENDS ${OUTPUT_FILE}.test coverage_test)
add_custom_target(coverage_final DEPENDS ${OUTPUT_FILE})
add_dependencies(coverage_final coverage_test)
# Look for genhtml to produce HTML report. This tool is part of the
# lcov suite, so should be installed if lcov is installed. Thus,
# this is an over-cautious check just in case some distributions
# break these tools up in separate packages.
find_program(GENHTML genhtml)
if (GENHTML)
message(STATUS "Generate a code coverage report using the 'coverage' target after tests have run.")
add_custom_command(
OUTPUT ${REPORT_DIR}/index.html
COMMENT "Generating HTML code coverage report in ${CMAKE_CURRENT_BINARY_DIR}/${REPORT_DIR}"
COMMAND ${GENHTML}
--prefix ${CMAKE_SOURCE_DIR}
--ignore-errors source
--legend
--title "TimescaleDB"
--output-directory ${REPORT_DIR}
${OUTPUT_FILE}
DEPENDS ${OUTPUT_FILE})
add_custom_target(coverage DEPENDS ${REPORT_DIR}/index.html)
add_dependencies(coverage coverage_final)
add_custom_command(
TARGET coverage
POST_BUILD
COMMENT "Open file://${CMAKE_CURRENT_BINARY_DIR}/${REPORT_DIR}/index.html in a browser to view the report")
else ()
message(STATUS "Install genhtml to generate code coverage reports")
endif (GENHTML)
else ()
message(STATUS "Install lcov to generate code coverage reports")
endif (LCOV)