diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7a6fd895fdb87adf0b4bfc61a57c8216988938d8..01fe8a1b9b7934830ad7ee100724e8b7313e7697 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,6 +4,7 @@ stages: - build deps - build - test + - report variables: DEPS_SRC_PATH: "${CI_PROJECT_DIR}/deps/src" @@ -60,6 +61,7 @@ compile GekkoFS: -Wdev -Wdeprecate -DCMAKE_BUILD_TYPE=Debug + -DGKFS_ENABLE_CODE_COVERAGE:BOOL=ON -DGKFS_BUILD_TESTS:BOOL=ON -DGKFS_INSTALL_TESTS:BOOL=ON -DGKFS_ENABLE_FORWARDING:BOOL=ON @@ -68,13 +70,18 @@ compile GekkoFS: -DCMAKE_INSTALL_PREFIX=${INSTALL_PATH} ${CI_PROJECT_DIR} - make -j$(nproc) install - # the following commands are intended to reduce artifact size - - rm -rf ${BUILD_PATH}/_deps - find ${BUILD_PATH} -name "*.o" -delete + # cleanup nlohmann_json: it includes around 500MiB of test data + - rm -rf ${BUILD_PATH}/_deps/nlohmann_json-src/test/data + - rm -rf ${BUILD_PATH}/_deps/nlohmann_json-src/benchmarks/data + - rm -rf ${BUILD_PATH}/_deps/nlohmann_json-src/.git artifacts: paths: - ${BUILD_PATH} - ${INSTALL_PATH} + exclude: + # remove object files + - ${BUILD_PATH}/**/*.o compile tests: stage: build @@ -91,23 +98,39 @@ compile tests: integration tests: stage: test script: - - mkdir -p ${INTEGRATION_TESTS_RUN_PATH} - - cd ${INTEGRATION_TESTS_BIN_PATH} - - TMPDIR=${INTEGRATION_TESTS_RUN_PATH} unbuffer ${PYTEST} -v | tee ${INTEGRATION_TESTS_RUN_PATH}/session.log + ## run tests + - cd ${BUILD_PATH}/tests/integration + - unbuffer ${PYTEST} -v | tee session.log + ## capture coverage information + - cd ${BUILD_PATH} + - ${CI_PROJECT_DIR}/scripts/ci/coverage.sh + --capture integration + --root-dir ${CI_PROJECT_DIR} + --build-dir ${BUILD_PATH} + --exclusions "${CI_PROJECT_DIR}/scripts/ci/.coverage-exclusions" artifacts: - when: on_failure + # when: on_failure paths: - - "${INTEGRATION_TESTS_RUN_PATH}" + # - "${INTEGRATION_TESTS_RUN_PATH}" + - ${BUILD_PATH} unit: stage: test script: + ## run actual tests - cd ${BUILD_PATH} - ctest -j $(nproc) -L unit::all + ## capture coverage information + - ${CI_PROJECT_DIR}/scripts/ci/coverage.sh + --capture unit + --root-dir ${CI_PROJECT_DIR} + --build-dir ${BUILD_PATH} + --exclusions "${CI_PROJECT_DIR}/scripts/ci/.coverage-exclusions" artifacts: - when: on_failure + # when: on_failure paths: - - Testing + - ${BUILD_PATH} + # - Testing test wr: stage: test @@ -156,3 +179,25 @@ test lseek: when: on_failure paths: - "${LOG_PATH}" + + +################################################################################ +## Generation of code coverage reports +################################################################################ + +coverage: + stage: report + image: gekkofs/coverage + script: + - cd ${BUILD_PATH} + ## merge the partial coverage files from each test in the pipeline + - ${CI_PROJECT_DIR}/scripts/ci/coverage.sh + --merge + --root-dir ${CI_PROJECT_DIR} + --build-dir ${BUILD_PATH} + artifacts: + reports: + cobertura: ${BUILD_PATH}/.coverage/coverage-cobertura.xml + paths: + - ${BUILD_PATH}/.coverage + expire_in: 2 weeks diff --git a/CMake/gkfs-code-coverage.cmake b/CMake/gkfs-code-coverage.cmake new file mode 100644 index 0000000000000000000000000000000000000000..3c0e82973f59b0308dcf8c1082678b079ed16e86 --- /dev/null +++ b/CMake/gkfs-code-coverage.cmake @@ -0,0 +1,82 @@ +# 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() diff --git a/CMakeLists.txt b/CMakeLists.txt index 52c110217c4f23548a3ef57d9a2eeecae5728731..6e1920cb2f1ec4f9f3176797959652ebff884ef9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/README.md b/README.md index 2caa7409d13bfd1c94c2448ab6363e538229c7d0..b8e81458a055d8c30c0a38650a3a964031572558 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![pipeline status](https://storage.bsc.es/gitlab/hpc/gekkofs/badges/master/pipeline.svg)](https://storage.bsc.es/gitlab/hpc/gekkofs/commits/master) +[![coverage report](https://storage.bsc.es/gitlab/hpc/gekkofs/badges/master/coverage.svg)](https://storage.bsc.es/gitlab/hpc/gekkofs/-/commits/master) GekkoFS is a file system capable of aggregating the local I/O capacity and performance of each compute node in a HPC cluster to produce a high-performance storage space that can be accessed in a distributed manner. diff --git a/docker/debian_build_env.docker b/docker/debian_build_env.docker index db8bc6ca176eca36a612cbb60d6031497a05f4aa..b616be8c67b383748751e25c7702e7b35532f1cd 100644 --- a/docker/debian_build_env.docker +++ b/docker/debian_build_env.docker @@ -8,7 +8,8 @@ ENV SCRIPTS_PATH ${GKFS_PATH}/scripts ENV DEPS_SRC_PATH ${GKFS_PATH}/deps_src ENV INSTALL_PATH ${GKFS_PATH}/build_deps -RUN apt-get update && apt-get install -y --no-install-recommends \ +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ git \ curl \ ca-certificates \ @@ -38,22 +39,28 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ valgrind \ uuid-dev \ python3 \ + python3-pip \ python3-dev \ python3-venv \ + python3-setuptools \ expect \ # clang 10 deps lsb-release \ wget \ software-properties-common \ gnupg2 \ -# add clang-10 repos -&& wget https://apt.llvm.org/llvm.sh -P /tmp && chmod +x /tmp/llvm.sh && /tmp/llvm.sh 10 \ -# install clang-format -&& apt-get update && apt-get install -y --no-install-recommends clang-format-10 \ -# Clean apt cache to reduce image layer size -&& rm -rf /var/lib/apt/lists/* && rm /tmp/llvm.sh \ -# Clean apt caches of packages -&& apt-get clean && apt-get autoclean + # add clang-10 repos + wget https://apt.llvm.org/llvm.sh -P /tmp && chmod +x /tmp/llvm.sh && /tmp/llvm.sh 10 && \ + # install clang-format + apt-get update && apt-get install -y --no-install-recommends clang-format-10 && \ + # install gcovr + # (required for partial coverage reports in parallel runs) + python3 -m pip install --upgrade pip && \ + pip3 install gcovr && \ + # Clean apt cache to reduce image layer size + rm -rf /var/lib/apt/lists/* && rm /tmp/llvm.sh && \ + # Clean apt caches of packages + apt-get clean && apt-get autoclean ## COPY scripts/dl_dep.sh $SCRIPTS_PATH/ ## COPY scripts/compile_dep.sh $SCRIPTS_PATH/ diff --git a/scripts/ci/.coverage-exclusions b/scripts/ci/.coverage-exclusions new file mode 100644 index 0000000000000000000000000000000000000000..4519dbd03f5f038366b20d8de0027a28eaa69f9e --- /dev/null +++ b/scripts/ci/.coverage-exclusions @@ -0,0 +1,4 @@ +/usr/include/* +[[ROOT_DIR]]/external/* +[[ROOT_DIR]]/tests/* +[[BUILD_DIR]]/* diff --git a/scripts/ci/coverage.sh b/scripts/ci/coverage.sh new file mode 100755 index 0000000000000000000000000000000000000000..e55bcb220f2c3cf1112b6231dab9752dd9d75f5f --- /dev/null +++ b/scripts/ci/coverage.sh @@ -0,0 +1,252 @@ +#!/usr/bin/env bash + +################################################################################ +# # +# Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain # +# Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany # +# # +# This software was partially supported by the # +# EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). # +# # +# This software was partially supported by the # +# ADA-FS project under the SPPEXA project funded by the DFG. # +# # +# SPDX-License-Identifier: MIT # +# # +################################################################################ + +# default values +export CCOV_ROOT_DIR="${PWD}" +export CCOV_BUILD_DIR="${PWD}" +export CCOV_MODE="" +export CCOV_CAPTURE_NAME="" +export CCOV_EXCLUSIONS_FILE=".coverage-exclusions" +export GCOVR_EXTRA_OPTIONS=() + +usage() { + +# `cat << EOF` This means that cat should stop reading when EOF is detected +cat << EOF +Usage: coverage.sh MODE [options] -- [extra_gcovr_options] + +A helper script to capture coverage information and generate reports. + +Mode: + -c, --capture NAME Capture coverage data and generate a JSON report for it + in $PWD/.coverage/partial//. + -m, --merge Combine coverage data from several JSON reports and + produce a Cobertura XML report. + +Options: + -h, --help Show this help message, then exit. + -r, --root-dir ROOT_DIR + The root directory of the target source files. + Defaults to '$PWD', the current directory. + -b, --build-dir BUILD_DIR + The build directory for the project. + Defaults to '$PWD', the current directory. + -e, --exclusions EXCLUSIONS_FILE + Exclude any source files that match the filters + contained in EXCLUSIONS_FILE. Each filter must be in a + line of its own and may include optional [[ROOT_DIR]] + and/or [[BUILD_DIR]] tags that will be expanded with the + appropriate values. + Defaults to .coverage-exclusions. +EOF +# EOF is found above and hence cat command stops reading. This is equivalent to +# echo but much neater when printing out. +} + +parse_args() { + + # $@ is all command line parameters passed to the script. + # -o is for short options like -v + # -l is for long options with double dash like --version + # the comma separates different long options + options=$(getopt -l \ + "capture:,merge,help,root-dir:,build-dir:,exclusions:,output:" \ + -o "cmhr:b:e:o:" -- "$@") + + # set --: + # If no arguments follow this option, then the positional parameters are + # unset. Otherwise, the positional parameters are set to the arguments, + # even if some of them begin with a ‘-’. + eval set -- "${options}" + + while true; + do + opt=$1 + case $opt in + -c|--capture) + shift + + if [[ -z $1 ]]; then + echo "Missing mandatory argument for '${opt}'." + exit 1 + fi + + if [[ $1 =~ ^--.* ]]; then + echo "Invalid argument '${1}' for '${opt}'." + exit 1 + fi + + export CCOV_MODE="capture" + export CCOV_CAPTURE_NAME=$1 + ;; + + -m|--merge) + CCOV_MODE="merge" + ;; + + -r|--root-dir) + shift + + if [[ -z $1 ]]; then + echo "Missing mandatory argument for '${opt}'." + exit 1 + fi + + if ! [[ -d $1 ]]; then + echo "directory '${1}' does not exist." + exit 1 + fi + + export CCOV_ROOT_DIR=$1 + ;; + + -b|--build-dir) + shift + if [[ -z $1 ]]; then + echo "Missing mandatory argument for '${opt}'." + exit 1 + fi + + if ! [[ -d $1 ]]; then + echo "directory '${1}' does not exist." + exit 1 + fi + + export CCOV_BUILD_DIR=$1 + ;; + + -e|--exclusions) + shift + + if [[ -z $1 ]]; then + echo "Missing mandatory argument for '${opt}'." + exit 1 + fi + + if [[ $1 =~ ^--.* ]]; then + echo "Invalid argument '${1}' for '${opt}'." + exit 1 + fi + + if ! [[ -n $1 && -f $1 && -r $1 ]]; then + echo "file '${1}' does not exist or cannot be read." + exit 1 + fi + + export CCOV_EXCLUSIONS_FILE=$1 + ;; + + --) + shift + GCOVR_EXTRA_OPTIONS="$@" + break;; + + -h|--help|*) + usage + exit 0 + ;; + esac + shift + done + + if [[ -z "${CCOV_MODE}" ]]; then + echo -e "ERROR: working mode is mandatory.\n" + usage + exit 1 + fi +} + +parse_exclusions_file() { + + if [[ -n ${CCOV_EXCLUSIONS_FILE} ]]; then + mapfile -t tmp < "${CCOV_EXCLUSIONS_FILE}" + fi + + export CCOV_EXCLUSIONS=() + + for exc in "${tmp[@]}"; + do + # expand [[ROOT_DIR]] + exc="${exc/\[\[ROOT_DIR\]\]/${CCOV_ROOT_DIR}}" + + # expand [[BUILD_DIR]] + CCOV_EXCLUSIONS+=( "${exc/\[\[BUILD_DIR\]\]/${CCOV_BUILD_DIR}}" ) + done +} + +capture() { + + COVERAGE_OUTPUT_DIR="${PWD}/.coverage/partial/${CCOV_CAPTURE_NAME}" + + ! [[ -d "${COVERAGE_OUTPUT_DIR}" ]] && mkdir -p "${COVERAGE_OUTPUT_DIR}" + + exclude_args=() + + for p in "${CCOV_EXCLUSIONS[@]}"; + do + exclude_args+=( "--exclude '${p}'" ) + done + + gcovr \ + --root "${CCOV_ROOT_DIR}" \ + "${CCOV_EXCLUSIONS[@]/#/--exclude=/}" \ + --json \ + --output "${COVERAGE_OUTPUT_DIR}/coverage.json" \ + ${GCOVR_EXTRA_OPTIONS[@]} + + echo "Coverage report written to ${COVERAGE_OUTPUT_DIR}/coverage.json" +} + +merge() { + + COVERAGE_OUTPUT_DIR="${PWD}/.coverage" + + ! [[ -d "${COVERAGE_OUTPUT_DIR}" ]] && mkdir -p "${COVERAGE_OUTPUT_DIR}" + + tracefiles=() + + mapfile -d $'\0' tracefiles < \ + <(find "${PWD}/.coverage/partial" -name coverage.json -print0) + + gcovr \ + --root "${CCOV_ROOT_DIR}" \ + "${tracefiles[@]/#/--add-tracefile=}" \ + --html-details "${COVERAGE_OUTPUT_DIR}/coverage.html" \ + --xml \ + --output "${COVERAGE_OUTPUT_DIR}/coverage-cobertura.xml" \ + --print-summary \ + ${GCOVR_EXTRA_OPTIONS[@]} + + echo "Cobertura XML report written to ${COVERAGE_OUTPUT_DIR}/coverage-cobertura.xml" + echo "HTML report written to ${COVERAGE_OUTPUT_DIR}/coverage.html" + + exit 0 +} + +################################################################################ +## MAIN +################################################################################ +parse_args "$@" + +if [[ x"$CCOV_MODE" == x"capture" ]]; then + parse_exclusions_file + capture +else + merge +fi + +exit 0 diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 3cf75472913b872902c3e03a51616359e78c7c32..82f525c05b4891bd8cac1b698a664bfc7d94a0ad 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -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} diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 35730d4d2739e25212e942563004c28492600095..960303ddb4b9050d2fbdb0f0656d3e789ce99817 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -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} ) diff --git a/src/global/CMakeLists.txt b/src/global/CMakeLists.txt index fb611cf9a8c5c5b845d28ce9281b266312bdbdb5..ca78030eb1c479305c76e0d475c51d6f94071fb8 100644 --- a/src/global/CMakeLists.txt +++ b/src/global/CMakeLists.txt @@ -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() diff --git a/src/global/arithmetic/CMakeLists.txt b/src/global/arithmetic/CMakeLists.txt index 16c35079ce4f701ab563ef522d77dda943d096a0..df70a8a5ae34346e1720e7cd40e2408f1a39cdf8 100644 --- a/src/global/arithmetic/CMakeLists.txt +++ b/src/global/arithmetic/CMakeLists.txt @@ -21,3 +21,5 @@ target_include_directories(arithmetic INTERFACE ${INCLUDE_DIR}/global/arithmetic/ ) + +target_code_coverage(arithmetic INTERFACE)