Verified Commit 172fe4ce authored by Alberto Miranda's avatar Alberto Miranda ♨️
Browse files

Teach CMake to generate coverage reports

parent 460cabe0
Loading
Loading
Loading
Loading
+82 −0
Original line number Diff line number Diff line
# Variables
option(GKFS_ENABLE_CODE_COVERAGE
  "Builds GekkoFS targets with code coverage instrumentation."
  OFF
  )

# Common initialization/checks
if(GKFS_ENABLE_CODE_COVERAGE AND NOT GKFS_CODE_COVERAGE_ADDED)

  set(GKFS_CODE_COVERAGE_ADDED ON)

  if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang"
     OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")

    message(STATUS "[gekkofs] Building with LLVM Code Coverage Tools")

  elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES
                                              "GNU")

    message(STATUS "[gekkofs] Building with GCC Code Coverage Tools")

    if(CMAKE_BUILD_TYPE)
      string(TOUPPER ${CMAKE_BUILD_TYPE} upper_build_type)
      if(NOT ${upper_build_type} STREQUAL "DEBUG")
        message(
          WARNING
            "Code coverage results with an optimized (non-Debug) build may be misleading"
        )
      endif()
    else()
      message(
        WARNING
          "Code coverage results with an optimized (non-Debug) build may be misleading"
      )
    endif()
  else()
    message(FATAL_ERROR "Code coverage requires Clang or GCC. Aborting.")
  endif()
endif()

# Adds code coverage instrumentation to libraries and executable targets.
# ~~~
# Required:
# TARGET_NAME - Name of the target to generate code coverage for.
# Optional:
# PUBLIC   - Sets the visibility for added compile options to targets to PUBLIC
#            instead of the default of PRIVATE.
# PRIVATE - Sets the visibility for added compile options to targets to
#           INTERFACE instead of the default of PRIVATE.
# ~~~
function(target_code_coverage TARGET_NAME)
  # Argument parsing
  set(options PUBLIC INTERFACE)
  cmake_parse_arguments(target_code_coverage "${options}" "" "" ${ARGN})

  # Set the visibility of target functions to PUBLIC, INTERFACE or default to
  # PRIVATE.
  if(target_code_coverage_PUBLIC)
    set(TARGET_VISIBILITY PUBLIC)
  elseif(target_code_coverage_INTERFACE)
    set(TARGET_VISIBILITY INTERFACE)
  else()
    set(TARGET_VISIBILITY PRIVATE)
  endif()

  if(GKFS_ENABLE_CODE_COVERAGE)

    # Add code coverage instrumentation to the target's linker command
    if(CMAKE_C_COMPILER_ID MATCHES "(Apple)?[Cc]lang"
       OR CMAKE_CXX_COMPILER_ID MATCHES "(Apple)?[Cc]lang")
      target_compile_options(${TARGET_NAME} ${TARGET_VISIBILITY}
                             -fprofile-instr-generate -fcoverage-mapping)
      target_link_options(${TARGET_NAME} ${TARGET_VISIBILITY}
                          -fprofile-instr-generate -fcoverage-mapping)
    elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES
                                                "GNU")
      target_compile_options(${TARGET_NAME} ${TARGET_VISIBILITY} -fprofile-arcs
        -ftest-coverage)
      target_link_libraries(${TARGET_NAME} ${TARGET_VISIBILITY} gcov)
    endif()
  endif()
endfunction()
+10 −0
Original line number Diff line number Diff line
@@ -74,6 +74,16 @@ configure_file(include/version.hpp.in include/version.hpp)

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH})


################################################################################
## Coverage generation support:
## ============================
## 
## The `gkfs-code-coverage' module enables the GKFS_ENABLE_CODE_COVERAGE option
## as well as the target_code_coverage() function.
################################################################################
include(gkfs-code-coverage)

set(CMAKE_EXPORT_COMPILE_COMMANDS 0)

# Rocksdb dependencies
+11 −1
Original line number Diff line number Diff line
@@ -70,11 +70,17 @@ set(PRELOAD_INCLUDE_DIRS
add_library(gkfs_intercept SHARED ${PRELOAD_SRC} ${PRELOAD_HEADERS})

target_link_libraries(gkfs_intercept
  PRIVATE
    arithmetic
    ${PRELOAD_LINK_LIBRARIES})

target_include_directories(gkfs_intercept PRIVATE ${PRELOAD_INCLUDE_DIRS})

if(GKFS_ENABLE_CODE_COVERAGE)
  target_code_coverage(gkfs_intercept AUTO)
endif()


install(TARGETS gkfs_intercept
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
@@ -107,10 +113,14 @@ if (GKFS_ENABLE_FORWARDING)
    message(STATUS "[gekkofs] Forwarding mode: ${GKFS_ENABLE_FORWARDING}")
    message(STATUS "[gekkofs] AGIOS scheduling: ${GKFS_ENABLE_AGIOS}")

    target_link_libraries(gkfwd_intercept ${PRELOAD_LINK_LIBRARIES})
    target_link_libraries(gkfwd_intercept PRIVATE ${PRELOAD_LINK_LIBRARIES})

    target_include_directories(gkfwd_intercept PRIVATE ${PRELOAD_INCLUDE_DIRS})

    if(GKFS_ENABLE_CODE_COVERAGE)
      target_code_coverage(gkfwd_intercept AUTO)
    endif()

    install(TARGETS gkfwd_intercept
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+10 −1
Original line number Diff line number Diff line
@@ -56,10 +56,14 @@ set(DAEMON_INCLUDE_DIRS
    )

add_executable(gkfs_daemon ${DAEMON_SRC} ${DAEMON_HEADERS})
target_link_libraries(gkfs_daemon ${DAEMON_LINK_LIBRARIES})
target_link_libraries(gkfs_daemon PRIVATE ${DAEMON_LINK_LIBRARIES})

target_include_directories(gkfs_daemon PRIVATE ${DAEMON_INCLUDE_DIRS})

if(GKFS_ENABLE_CODE_COVERAGE)
  target_code_coverage(gkfs_daemon AUTO)
endif()

install(TARGETS gkfs_daemon
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
    )
@@ -92,6 +96,7 @@ if (GKFS_ENABLE_FORWARDING)
    message(STATUS "[gekkofs] AGIOS scheduling: ${GKFS_ENABLE_AGIOS}")

    target_link_libraries(gkfwd_daemon
      PRIVATE
        ${DAEMON_LINK_LIBRARIES}
        ${AGIOS_LIBRARIES}
        )
@@ -102,6 +107,10 @@ if (GKFS_ENABLE_FORWARDING)
        ${AGIOS_INCLUDE_DIRS}
        )

    if(GKFS_ENABLE_CODE_COVERAGE)
      target_code_coverage(gkfwd_daemon AUTO)
    endif()

    install(TARGETS gkfwd_daemon
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
        )
+18 −0
Original line number Diff line number Diff line
@@ -9,6 +9,10 @@ target_sources(distributor
    ${CMAKE_CURRENT_LIST_DIR}/rpc/distributor.cpp
    )

if(GKFS_ENABLE_CODE_COVERAGE)
  target_code_coverage(distributor AUTO)
endif()

add_library(log_util STATIC)
set_property(TARGET log_util PROPERTY POSITION_INDEPENDENT_CODE ON)
target_sources(log_util
@@ -18,9 +22,14 @@ target_sources(log_util
    ${CMAKE_CURRENT_LIST_DIR}/log_util.cpp
    )
target_link_libraries(log_util
  PRIVATE
    spdlog
    )

if(GKFS_ENABLE_CODE_COVERAGE)
  target_code_coverage(log_util AUTO)
endif()

add_library(env_util STATIC)
set_property(TARGET env_util PROPERTY POSITION_INDEPENDENT_CODE ON)
target_sources(env_util
@@ -31,6 +40,10 @@ target_sources(env_util
    ${CMAKE_CURRENT_LIST_DIR}/env_util.cpp
    )

if(GKFS_ENABLE_CODE_COVERAGE)
  target_code_coverage(env_util AUTO)
endif()

add_library(metadata STATIC)
set_property(TARGET metadata PROPERTY POSITION_INDEPENDENT_CODE ON)
target_sources(metadata
@@ -40,5 +53,10 @@ target_sources(metadata
    ${CMAKE_CURRENT_LIST_DIR}/metadata.cpp
    )
target_link_libraries(metadata
  PRIVATE
    fmt::fmt
    )

if(GKFS_ENABLE_CODE_COVERAGE)
  target_code_coverage(metadata AUTO)
endif()
Loading