Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

251 lines
8.8 KiB
CMake

# Copyright (c) Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT
# ----------------------------------------------------------------------------------------#
#
# Code Coverage Support
#
# This module provides code coverage functionality using gcov/lcov or gcovr.
#
# Usage:
# cmake -DPROFILER_HUB_ENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug ..
# make
# make coverage # Run tests and generate HTML report
# make coverage-xml # Run tests and generate Cobertura XML (for CI)
# make coverage-clean # Clean coverage data
#
# ----------------------------------------------------------------------------------------#
include_guard(DIRECTORY)
if(NOT PROFILER_HUB_ENABLE_COVERAGE)
return()
endif()
# Coverage requires Debug build for accurate line information
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(
WARNING
"[profiler-hub] Code coverage works best with CMAKE_BUILD_TYPE=Debug. "
"Current build type: ${CMAKE_BUILD_TYPE}"
)
endif()
# Only GCC and Clang support gcov-compatible coverage
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
message(
FATAL_ERROR
"[profiler-hub] Code coverage requires GCC or Clang. "
"Current compiler: ${CMAKE_CXX_COMPILER_ID}"
)
endif()
message(STATUS "[profiler-hub] Code coverage enabled")
# ----------------------------------------------------------------------------------------#
# Find coverage tools
# ----------------------------------------------------------------------------------------#
find_program(GCOV_PATH gcov)
find_program(LCOV_PATH lcov)
find_program(GENHTML_PATH genhtml)
find_program(GCOVR_PATH gcovr)
if(NOT GCOV_PATH)
message(FATAL_ERROR "[profiler-hub] gcov not found, required for coverage")
endif()
# Prefer lcov/genhtml, fall back to gcovr
set(PROFILER_HUB_COVERAGE_USE_LCOV FALSE)
set(PROFILER_HUB_COVERAGE_USE_GCOVR FALSE)
if(LCOV_PATH AND GENHTML_PATH)
set(PROFILER_HUB_COVERAGE_USE_LCOV TRUE)
message(
STATUS
"[profiler-hub] Using lcov for coverage reports: ${LCOV_PATH}"
)
elseif(GCOVR_PATH)
set(PROFILER_HUB_COVERAGE_USE_GCOVR TRUE)
message(
STATUS
"[profiler-hub] Using gcovr for coverage reports: ${GCOVR_PATH}"
)
else()
message(
FATAL_ERROR
"[profiler-hub] Coverage report generation requires either:\n"
" - lcov and genhtml (apt install lcov)\n"
" - gcovr (pip install gcovr)"
)
endif()
# ----------------------------------------------------------------------------------------#
# Coverage compiler and linker flags
# ----------------------------------------------------------------------------------------#
set(PROFILER_HUB_COVERAGE_COMPILE_FLAGS -fprofile-arcs -ftest-coverage)
set(PROFILER_HUB_COVERAGE_LINK_FLAGS --coverage)
# For Clang, we may need to specify the gcov tool
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
list(
APPEND PROFILER_HUB_COVERAGE_COMPILE_FLAGS
-fprofile-instr-generate
-fcoverage-mapping
)
set(PROFILER_HUB_COVERAGE_LINK_FLAGS -fprofile-instr-generate)
endif()
# ----------------------------------------------------------------------------------------#
# Function to add coverage flags to a target
# ----------------------------------------------------------------------------------------#
function(profiler_hub_add_coverage_flags target)
target_compile_options(
${target}
PRIVATE ${PROFILER_HUB_COVERAGE_COMPILE_FLAGS}
)
target_link_options(${target} PRIVATE ${PROFILER_HUB_COVERAGE_LINK_FLAGS})
endfunction()
# ----------------------------------------------------------------------------------------#
# Coverage output directory
# ----------------------------------------------------------------------------------------#
set(PROFILER_HUB_COVERAGE_DIR ${CMAKE_BINARY_DIR}/coverage)
file(MAKE_DIRECTORY ${PROFILER_HUB_COVERAGE_DIR})
# ----------------------------------------------------------------------------------------#
# Coverage targets using lcov
# ----------------------------------------------------------------------------------------#
if(PROFILER_HUB_COVERAGE_USE_LCOV)
# Clean coverage data
add_custom_target(
coverage-clean
COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --zerocounters
COMMAND ${CMAKE_COMMAND} -E rm -rf ${PROFILER_HUB_COVERAGE_DIR}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Cleaning coverage data..."
)
# Generate HTML coverage report
add_custom_target(
coverage
# Reset counters
COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --zerocounters
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
# Capture coverage data
COMMAND
${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --capture --output-file
${PROFILER_HUB_COVERAGE_DIR}/coverage.info --ignore-errors mismatch
# Remove external dependencies from coverage
COMMAND
${LCOV_PATH} --remove ${PROFILER_HUB_COVERAGE_DIR}/coverage.info
'/usr/*' '${CMAKE_BINARY_DIR}/_deps/*' '${CMAKE_SOURCE_DIR}/tests/*'
--output-file ${PROFILER_HUB_COVERAGE_DIR}/coverage.info
--ignore-errors unused
# Generate HTML report
COMMAND
${GENHTML_PATH} ${PROFILER_HUB_COVERAGE_DIR}/coverage.info
--output-directory ${PROFILER_HUB_COVERAGE_DIR}/html --title
"profiler-hub Code Coverage" --legend --show-details
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating code coverage report..."
)
add_custom_command(
TARGET coverage
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E echo
"Coverage report: file://${PROFILER_HUB_COVERAGE_DIR}/html/index.html"
)
endif()
# ----------------------------------------------------------------------------------------#
# Coverage targets using gcovr
# ----------------------------------------------------------------------------------------#
if(PROFILER_HUB_COVERAGE_USE_GCOVR)
# Clean coverage data
add_custom_target(
coverage-clean
COMMAND find ${CMAKE_BINARY_DIR} -name "*.gcda" -delete
COMMAND ${CMAKE_COMMAND} -E rm -rf ${PROFILER_HUB_COVERAGE_DIR}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Cleaning coverage data..."
)
# Generate HTML coverage report
add_custom_target(
coverage
# Clean old data
COMMAND find ${CMAKE_BINARY_DIR} -name "*.gcda" -delete
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
# Generate HTML report
COMMAND
${GCOVR_PATH} --root ${CMAKE_SOURCE_DIR} --filter
${CMAKE_SOURCE_DIR}/source --filter ${CMAKE_SOURCE_DIR}/include
--exclude ${CMAKE_SOURCE_DIR}/tests --html-details
${PROFILER_HUB_COVERAGE_DIR}/html/index.html --print-summary
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating code coverage report..."
)
add_custom_command(
TARGET coverage
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E echo
"Coverage report: file://${PROFILER_HUB_COVERAGE_DIR}/html/index.html"
)
# Generate Cobertura XML report (for CI integration)
add_custom_target(
coverage-xml
# Clean old data
COMMAND find ${CMAKE_BINARY_DIR} -name "*.gcda" -delete
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
# Generate XML report
COMMAND
${GCOVR_PATH} --root ${CMAKE_SOURCE_DIR} --filter
${CMAKE_SOURCE_DIR}/source --filter ${CMAKE_SOURCE_DIR}/include
--exclude ${CMAKE_SOURCE_DIR}/tests --xml
${PROFILER_HUB_COVERAGE_DIR}/coverage.xml --print-summary
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating Cobertura XML coverage report..."
)
add_custom_command(
TARGET coverage-xml
POST_BUILD
COMMAND
${CMAKE_COMMAND} -E echo
"Coverage XML: ${PROFILER_HUB_COVERAGE_DIR}/coverage.xml"
)
endif()
# XML target for lcov (using lcov's cobertura output if available)
if(PROFILER_HUB_COVERAGE_USE_LCOV AND GCOVR_PATH)
add_custom_target(
coverage-xml
# Reset counters
COMMAND ${LCOV_PATH} --directory ${CMAKE_BINARY_DIR} --zerocounters
# Run tests
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
# Generate XML using gcovr
COMMAND
${GCOVR_PATH} --root ${CMAKE_SOURCE_DIR} --filter
${CMAKE_SOURCE_DIR}/source --filter ${CMAKE_SOURCE_DIR}/include
--exclude ${CMAKE_SOURCE_DIR}/tests --xml
${PROFILER_HUB_COVERAGE_DIR}/coverage.xml --print-summary
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Generating Cobertura XML coverage report..."
)
endif()