diff --git a/.codecov.yml b/.codecov.yml index b2bc67814e3..191144aae16 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,5 +1,6 @@ - -codecov: - ci: - - !appveyor - - travis +coverage: + status: + project: + default: + target: 60% + threshold: 2% diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml index d7a92b3b409..79bbe9af075 100644 --- a/.github/actions/build/action.yml +++ b/.github/actions/build/action.yml @@ -6,6 +6,8 @@ inputs: required: true cmake-args: default: null + cmake-target: + default: all # An implicit input is the environment variable `build_dir`. runs: using: composite @@ -26,4 +28,5 @@ runs: cmake \ --build ${build_dir} \ --config ${{ inputs.configuration }} \ - --parallel ${NUM_PROCESSORS:-$(nproc)} + --parallel ${NUM_PROCESSORS:-$(nproc)} \ + --target ${{ inputs.cmake-target }} diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index e43ae1379c9..02fcc742b6c 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -49,7 +49,7 @@ jobs: cc: /usr/bin/clang-14 cxx: /usr/bin/clang++-14 runs-on: [self-hosted, heavy] - container: thejohnfreeman/rippled-build-ubuntu:12e19cd9034b + container: rippleci/rippled-build-ubuntu:aaf5e3e env: build_dir: .build steps: @@ -125,7 +125,7 @@ jobs: - "-Dunity=ON" needs: dependencies runs-on: [self-hosted, heavy] - container: thejohnfreeman/rippled-build-ubuntu:12e19cd9034b + container: rippleci/rippled-build-ubuntu:aaf5e3e env: build_dir: .build steps: @@ -159,3 +159,72 @@ jobs: - name: test run: | ${build_dir}/rippled --unittest --unittest-jobs $(nproc) + + + coverage: + strategy: + fail-fast: false + matrix: + platform: + - linux + compiler: + - gcc + configuration: + - Debug + needs: dependencies + runs-on: [self-hosted, heavy] + container: rippleci/rippled-build-ubuntu:aaf5e3e + env: + build_dir: .build + steps: + - name: download cache + uses: actions/download-artifact@v3 + with: + name: ${{ matrix.platform }}-${{ matrix.compiler }}-${{ matrix.configuration }} + - name: extract cache + run: | + mkdir -p ~/.conan + tar -xzf conan.tar -C ~/.conan + - name: check environment + run: | + echo ${PATH} | tr ':' '\n' + conan --version + cmake --version + gcovr --version + env | sort + ls ~/.conan + - name: checkout + uses: actions/checkout@v3 + - name: dependencies + uses: ./.github/actions/dependencies + with: + configuration: ${{ matrix.configuration }} + - name: build + uses: ./.github/actions/build + with: + generator: Ninja + configuration: ${{ matrix.configuration }} + cmake-args: >- + -Dcoverage=ON + -Dcoverage_format=xml + -DCODE_COVERAGE_VERBOSE=ON + -DCMAKE_CXX_FLAGS="-O0" + -DCMAKE_C_FLAGS="-O0" + cmake-target: coverage + - name: build + shell: bash + run: | + mv "${build_dir}/coverage.xml" ./ + - name: archive coverage report + uses: actions/upload-artifact@v3 + with: + name: coverage.xml + path: coverage.xml + retention-days: 30 + - name: upload coverage report + uses: codecov/codecov-action@v3 + with: + files: coverage.xml + fail_ci_if_error: true + verbose: true + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 1d2b5bb5583..7286d2f1f34 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -90,6 +90,7 @@ jobs: configuration: ${{ matrix.configuration }} # Hard code for now. Move to the matrix if varied options are needed cmake-args: '-Dassert=ON -Dreporting=OFF -Dunity=ON' + cmake-target: install - name: test (permitted to silently fail) shell: bash # Github runners are resource limited, which causes unit tests to fail diff --git a/BUILD.md b/BUILD.md index 21341ae9a71..5217e0947b8 100644 --- a/BUILD.md +++ b/BUILD.md @@ -262,12 +262,72 @@ It patches their CMake to correctly import its dependencies. generator. Pass `--help` to see the rest of the command line options. +## Coverage report + +The coverage report is intended for developers using compilers GCC +or Clang (including Apple Clang). It is generated by the build target `coverage`, +which is only enabled when the `coverage` option is set, e.g. with +`--options coverage=True` in `conan` or `-Dcoverage=ON` variable in `cmake` + +Prerequisites for the coverage report: + +- [gcovr tool][gcovr] (can be installed e.g. with [pip][python-pip]) +- `gcov` for GCC (installed with the compiler by default) or +- `llvm-cov` for Clang (installed with the compiler by default) +- `Debug` build type + +A coverage report is created when the following steps are completed, in order: + +1. `rippled` binary built with instrumentation data, enabled by the `coverage` + option mentioned above +2. completed run of unit tests, which populates coverage capture data +3. completed run of the `gcovr` tool (which internally invokes either `gcov` or `llvm-cov`) + to assemble both instrumentation data and the coverage capture data into a coverage report + +The above steps are automated into a single target `coverage`. The instrumented +`rippled` binary can also be used for regular development or testing work, at +the cost of extra disk space utilization and a small performance hit +(to store coverage capture). In case of a spurious failure of unit tests, it is +possible to re-run the `coverage` target without rebuilding the `rippled` binary +(since it is simply a dependency of the coverage report target). It is also possible +to select only specific tests for the purpose of the coverage report, by setting +the `coverage_test` variable in `cmake` + +The default coverage report format is `html-details`, but the user +can override it to any of the formats listed in `Builds/CMake/CodeCoverage.cmake` +by setting the `coverage_format` variable in `cmake`. It is also possible +to generate more than one format at a time by setting the `coverage_extra_args` +variable in `cmake`. The specific command line used to run the `gcovr` tool will be +displayed if the `CODE_COVERAGE_VERBOSE` variable is set. + +By default, the code coverage tool runs parallel unit tests with `--unittest-jobs` + set to the number of available CPU cores. This may cause spurious test +errors on Apple. Developers can override the number of unit test jobs with +the `coverage_test_parallelism` variable in `cmake`. + +Example use with some cmake variables set: + +``` +cd .build +conan install .. --output-folder . --build missing --settings build_type=Debug +cmake -DCMAKE_BUILD_TYPE=Debug -Dcoverage=ON -Dcoverage_test_parallelism=2 -Dcoverage_format=html-details -Dcoverage_extra_args="--json coverage.json" -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake .. +cmake --build . --target coverage +``` + +After the `coverage` target is completed, the generated coverage report will be +stored inside the build directory, as either of: + +- file named `coverage.`_extension_ , with a suitable extension for the report format, or +- directory named `coverage`, with the `index.html` and other files inside, for the `html-details` or `html-nested` report formats. + + ## Options | Option | Default Value | Description | | --- | ---| ---| | `assert` | OFF | Enable assertions. | `reporting` | OFF | Build the reporting mode feature. | +| `coverage` | OFF | Prepare the coverage report. | | `tests` | ON | Build tests. | | `unity` | ON | Configure a unity build. | | `san` | N/A | Enable a sanitizer with Clang. Choices are `thread` and `address`. | @@ -362,6 +422,8 @@ If you want to experiment with a new package, follow these steps: [5]: https://en.wikipedia.org/wiki/Unity_build [6]: https://github.com/boostorg/beast/issues/2648 [7]: https://github.com/boostorg/beast/issues/2661 +[gcovr]: https://gcovr.com/en/stable/getting-started.html +[python-pip]: https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/ [build_type]: https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html [runtime]: https://cmake.org/cmake/help/latest/variable/CMAKE_MSVC_RUNTIME_LIBRARY.html [toolchain]: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html diff --git a/Builds/CMake/CodeCoverage.cmake b/Builds/CMake/CodeCoverage.cmake new file mode 100644 index 00000000000..d2af481d8a3 --- /dev/null +++ b/Builds/CMake/CodeCoverage.cmake @@ -0,0 +1,440 @@ +# Copyright (c) 2012 - 2017, Lars Bilke +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# CHANGES: +# +# 2012-01-31, Lars Bilke +# - Enable Code Coverage +# +# 2013-09-17, Joakim Söderberg +# - Added support for Clang. +# - Some additional usage instructions. +# +# 2016-02-03, Lars Bilke +# - Refactored functions to use named parameters +# +# 2017-06-02, Lars Bilke +# - Merged with modified version from github.com/ufz/ogs +# +# 2019-05-06, Anatolii Kurotych +# - Remove unnecessary --coverage flag +# +# 2019-12-13, FeRD (Frank Dana) +# - Deprecate COVERAGE_LCOVR_EXCLUDES and COVERAGE_GCOVR_EXCLUDES lists in favor +# of tool-agnostic COVERAGE_EXCLUDES variable, or EXCLUDE setup arguments. +# - CMake 3.4+: All excludes can be specified relative to BASE_DIRECTORY +# - All setup functions: accept BASE_DIRECTORY, EXCLUDE list +# - Set lcov basedir with -b argument +# - Add automatic --demangle-cpp in lcovr, if 'c++filt' is available (can be +# overridden with NO_DEMANGLE option in setup_target_for_coverage_lcovr().) +# - Delete output dir, .info file on 'make clean' +# - Remove Python detection, since version mismatches will break gcovr +# - Minor cleanup (lowercase function names, update examples...) +# +# 2019-12-19, FeRD (Frank Dana) +# - Rename Lcov outputs, make filtered file canonical, fix cleanup for targets +# +# 2020-01-19, Bob Apthorpe +# - Added gfortran support +# +# 2020-02-17, FeRD (Frank Dana) +# - Make all add_custom_target()s VERBATIM to auto-escape wildcard characters +# in EXCLUDEs, and remove manual escaping from gcovr targets +# +# 2021-01-19, Robin Mueller +# - Add CODE_COVERAGE_VERBOSE option which will allow to print out commands which are run +# - Added the option for users to set the GCOVR_ADDITIONAL_ARGS variable to supply additional +# flags to the gcovr command +# +# 2020-05-04, Mihchael Davis +# - Add -fprofile-abs-path to make gcno files contain absolute paths +# - Fix BASE_DIRECTORY not working when defined +# - Change BYPRODUCT from folder to index.html to stop ninja from complaining about double defines +# +# 2021-05-10, Martin Stump +# - Check if the generator is multi-config before warning about non-Debug builds +# +# 2022-02-22, Marko Wehle +# - Change gcovr output from -o for --xml and --html output respectively. +# This will allow for Multiple Output Formats at the same time by making use of GCOVR_ADDITIONAL_ARGS, e.g. GCOVR_ADDITIONAL_ARGS "--txt". +# +# 2022-09-28, Sebastian Mueller +# - fix append_coverage_compiler_flags_to_target to correctly add flags +# - replace "-fprofile-arcs -ftest-coverage" with "--coverage" (equivalent) +# +# 2024-01-04, Bronek Kozicki +# - remove setup_target_for_coverage_lcov (slow) and setup_target_for_coverage_fastcov (no support for Clang) +# - fix Clang support by adding find_program( ... llvm-cov ) +# - add Apple Clang support by adding execute_process( COMMAND xcrun -f llvm-cov ... ) +# - add CODE_COVERAGE_GCOV_TOOL to explicitly select gcov tool and disable find_program +# - replace both functions setup_target_for_coverage_gcovr_* with a single setup_target_for_coverage_gcovr +# - add support for all gcovr output formats +# +# USAGE: +# +# 1. Copy this file into your cmake modules path. +# +# 2. Add the following line to your CMakeLists.txt (best inside an if-condition +# using a CMake option() to enable it just optionally): +# include(CodeCoverage) +# +# 3. Append necessary compiler flags for all supported source files: +# append_coverage_compiler_flags() +# Or for specific target: +# append_coverage_compiler_flags_to_target(YOUR_TARGET_NAME) +# +# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og +# +# 4. If you need to exclude additional directories from the report, specify them +# using full paths in the COVERAGE_EXCLUDES variable before calling +# setup_target_for_coverage_*(). +# Example: +# set(COVERAGE_EXCLUDES +# '${PROJECT_SOURCE_DIR}/src/dir1/*' +# '/path/to/my/src/dir2/*') +# Or, use the EXCLUDE argument to setup_target_for_coverage_*(). +# Example: +# setup_target_for_coverage_gcovr( +# NAME coverage +# EXECUTABLE testrunner +# EXCLUDE "${PROJECT_SOURCE_DIR}/src/dir1/*" "/path/to/my/src/dir2/*") +# +# 4.a NOTE: With CMake 3.4+, COVERAGE_EXCLUDES or EXCLUDE can also be set +# relative to the BASE_DIRECTORY (default: PROJECT_SOURCE_DIR) +# Example: +# set(COVERAGE_EXCLUDES "dir1/*") +# setup_target_for_coverage_gcovr( +# NAME coverage +# EXECUTABLE testrunner +# FORMAT html-details +# BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src" +# EXCLUDE "dir2/*") +# +# 4.b If you need to pass specific options to gcovr, specify them in +# GCOVR_ADDITIONAL_ARGS variable. +# Example: +# set (GCOVR_ADDITIONAL_ARGS --exclude-throw-branches --exclude-noncode-lines -s) +# setup_target_for_coverage_gcovr( +# NAME coverage +# EXECUTABLE testrunner +# EXCLUDE "src/dir1" "src/dir2") +# +# 5. Use the functions described below to create a custom make target which +# runs your test executable and produces a code coverage report. +# +# 6. Build a Debug build: +# cmake -DCMAKE_BUILD_TYPE=Debug .. +# make +# make my_coverage_target + +include(CMakeParseArguments) + +option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE) + +# Check prereqs +find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) + +if(DEFINED CODE_COVERAGE_GCOV_TOOL) + set(GCOV_TOOL "${CODE_COVERAGE_GCOV_TOOL}") +elseif(DEFINED ENV{CODE_COVERAGE_GCOV_TOOL}) + set(GCOV_TOOL "$ENV{CODE_COVERAGE_GCOV_TOOL}") +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") + if(APPLE) + execute_process( COMMAND xcrun -f llvm-cov + OUTPUT_VARIABLE LLVMCOV_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + else() + find_program( LLVMCOV_PATH llvm-cov ) + endif() + if(LLVMCOV_PATH) + set(GCOV_TOOL "${LLVMCOV_PATH} gcov") + endif() +elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + find_program( GCOV_PATH gcov ) + set(GCOV_TOOL "${GCOV_PATH}") +endif() + +# Check supported compiler (Clang, GNU and Flang) +get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) +foreach(LANG ${LANGUAGES}) + if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") + if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3) + message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") + endif() + elseif(NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU" + AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(LLVM)?[Ff]lang") + message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...") + endif() +endforeach() + +set(COVERAGE_COMPILER_FLAGS "-g --coverage" + CACHE INTERNAL "") +if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path) + if(HAVE_cxx_fprofile_abs_path) + set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path") + endif() + include(CheckCCompilerFlag) + check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path) + if(HAVE_c_fprofile_abs_path) + set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path") + endif() +endif() + +set(CMAKE_Fortran_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the Fortran compiler during coverage builds." + FORCE ) +set(CMAKE_CXX_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the C++ compiler during coverage builds." + FORCE ) +set(CMAKE_C_FLAGS_COVERAGE + ${COVERAGE_COMPILER_FLAGS} + CACHE STRING "Flags used by the C compiler during coverage builds." + FORCE ) +set(CMAKE_EXE_LINKER_FLAGS_COVERAGE + "" + CACHE STRING "Flags used for linking binaries during coverage builds." + FORCE ) +set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE + "" + CACHE STRING "Flags used by the shared libraries linker during coverage builds." + FORCE ) +mark_as_advanced( + CMAKE_Fortran_FLAGS_COVERAGE + CMAKE_CXX_FLAGS_COVERAGE + CMAKE_C_FLAGS_COVERAGE + CMAKE_EXE_LINKER_FLAGS_COVERAGE + CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) + +get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)) + message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") +endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + link_libraries(gcov) +endif() + +# Defines a target for running and collection code coverage information +# Builds dependencies, runs the given executable and outputs reports. +# NOTE! The executable should always have a ZERO as exit code otherwise +# the coverage generation will not complete. +# +# setup_target_for_coverage_gcovr( +# NAME ctest_coverage # New target name +# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR +# DEPENDENCIES executable_target # Dependencies to build first +# BASE_DIRECTORY "../" # Base directory for report +# # (defaults to PROJECT_SOURCE_DIR) +# FORMAT "cobertura" # Output format, one of: +# # xml cobertura sonarqube json-summary +# # json-details coveralls csv txt +# # html-single html-nested html-details +# # (xml is an alias to cobertura; +# # if no format is set, defaults to xml) +# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative +# # to BASE_DIRECTORY, with CMake 3.4+) +# ) +# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the +# GCVOR command. +function(setup_target_for_coverage_gcovr) + set(options NONE) + set(oneValueArgs BASE_DIRECTORY NAME FORMAT) + set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) + cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT GCOV_TOOL) + message(FATAL_ERROR "Could not find gcov or llvm-cov tool! Aborting...") + endif() + + if(NOT GCOVR_PATH) + message(FATAL_ERROR "Could not find gcovr tool! Aborting...") + endif() + + # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR + if(DEFINED Coverage_BASE_DIRECTORY) + get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) + else() + set(BASEDIR ${PROJECT_SOURCE_DIR}) + endif() + + if(NOT DEFINED Coverage_FORMAT) + set(Coverage_FORMAT xml) + endif() + + if("--output" IN_LIST GCOVR_ADDITIONAL_ARGS) + message(FATAL_ERROR "Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting...") + else() + if((Coverage_FORMAT STREQUAL "html-details") + OR (Coverage_FORMAT STREQUAL "html-nested")) + set(GCOVR_OUTPUT_FILE ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html) + set(GCOVR_CREATE_FOLDER ${PROJECT_BINARY_DIR}/${Coverage_NAME}) + elseif(Coverage_FORMAT STREQUAL "html-single") + set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.html) + elseif((Coverage_FORMAT STREQUAL "json-summary") + OR (Coverage_FORMAT STREQUAL "json-details") + OR (Coverage_FORMAT STREQUAL "coveralls")) + set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.json) + elseif(Coverage_FORMAT STREQUAL "txt") + set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.txt) + elseif(Coverage_FORMAT STREQUAL "csv") + set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.csv) + else() + set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.xml) + endif() + endif() + + if((Coverage_FORMAT STREQUAL "cobertura") + OR (Coverage_FORMAT STREQUAL "xml")) + list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}" ) + list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura-pretty ) + set(Coverage_FORMAT cobertura) # overwrite xml + elseif(Coverage_FORMAT STREQUAL "sonarqube") + list(APPEND GCOVR_ADDITIONAL_ARGS --sonarqube "${GCOVR_OUTPUT_FILE}" ) + elseif(Coverage_FORMAT STREQUAL "json-summary") + list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary "${GCOVR_OUTPUT_FILE}" ) + list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary-pretty) + elseif(Coverage_FORMAT STREQUAL "json-details") + list(APPEND GCOVR_ADDITIONAL_ARGS --json "${GCOVR_OUTPUT_FILE}" ) + list(APPEND GCOVR_ADDITIONAL_ARGS --json-pretty) + elseif(Coverage_FORMAT STREQUAL "coveralls") + list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls "${GCOVR_OUTPUT_FILE}" ) + list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls-pretty) + elseif(Coverage_FORMAT STREQUAL "csv") + list(APPEND GCOVR_ADDITIONAL_ARGS --csv "${GCOVR_OUTPUT_FILE}" ) + elseif(Coverage_FORMAT STREQUAL "txt") + list(APPEND GCOVR_ADDITIONAL_ARGS --txt "${GCOVR_OUTPUT_FILE}" ) + elseif(Coverage_FORMAT STREQUAL "html-single") + list(APPEND GCOVR_ADDITIONAL_ARGS --html "${GCOVR_OUTPUT_FILE}" ) + list(APPEND GCOVR_ADDITIONAL_ARGS --html-self-contained) + elseif(Coverage_FORMAT STREQUAL "html-nested") + list(APPEND GCOVR_ADDITIONAL_ARGS --html-nested "${GCOVR_OUTPUT_FILE}" ) + elseif(Coverage_FORMAT STREQUAL "html-details") + list(APPEND GCOVR_ADDITIONAL_ARGS --html-details "${GCOVR_OUTPUT_FILE}" ) + else() + message(FATAL_ERROR "Unsupported output style ${Coverage_FORMAT}! Aborting...") + endif() + + # Collect excludes (CMake 3.4+: Also compute absolute paths) + set(GCOVR_EXCLUDES "") + foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES}) + if(CMAKE_VERSION VERSION_GREATER 3.4) + get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR}) + endif() + list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") + endforeach() + list(REMOVE_DUPLICATES GCOVR_EXCLUDES) + + # Combine excludes to several -e arguments + set(GCOVR_EXCLUDE_ARGS "") + foreach(EXCLUDE ${GCOVR_EXCLUDES}) + list(APPEND GCOVR_EXCLUDE_ARGS "-e") + list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}") + endforeach() + + # Set up commands which will be run to generate coverage data + # Run tests + set(GCOVR_EXEC_TESTS_CMD + ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS} + ) + + # Create folder + if(DEFINED GCOVR_CREATE_FOLDER) + set(GCOVR_FOLDER_CMD + ${CMAKE_COMMAND} -E make_directory ${GCOVR_CREATE_FOLDER}) + else() + set(GCOVR_FOLDER_CMD echo) # dummy + endif() + + # Running gcovr + set(GCOVR_CMD + ${GCOVR_PATH} + --gcov-executable ${GCOV_TOOL} + --gcov-ignore-parse-errors=negative_hits.warn_once_per_file + -r ${BASEDIR} + ${GCOVR_ADDITIONAL_ARGS} + ${GCOVR_EXCLUDE_ARGS} + --object-directory=${PROJECT_BINARY_DIR} + ) + + if(CODE_COVERAGE_VERBOSE) + message(STATUS "Executed command report") + + message(STATUS "Command to run tests: ") + string(REPLACE ";" " " GCOVR_EXEC_TESTS_CMD_SPACED "${GCOVR_EXEC_TESTS_CMD}") + message(STATUS "${GCOVR_EXEC_TESTS_CMD_SPACED}") + + if(NOT GCOVR_FOLDER_CMD STREQUAL "echo") + message(STATUS "Command to create a folder: ") + string(REPLACE ";" " " GCOVR_FOLDER_CMD_SPACED "${GCOVR_FOLDER_CMD}") + message(STATUS "${GCOVR_FOLDER_CMD_SPACED}") + endif() + + message(STATUS "Command to generate gcovr coverage data: ") + string(REPLACE ";" " " GCOVR_CMD_SPACED "${GCOVR_CMD}") + message(STATUS "${GCOVR_CMD_SPACED}") + endif() + + add_custom_target(${Coverage_NAME} + COMMAND ${GCOVR_EXEC_TESTS_CMD} + COMMAND ${GCOVR_FOLDER_CMD} + COMMAND ${GCOVR_CMD} + + BYPRODUCTS ${GCOVR_OUTPUT_FILE} + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS ${Coverage_DEPENDENCIES} + VERBATIM # Protect arguments to commands + COMMENT "Running gcovr to produce code coverage report." + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Code coverage report saved in ${GCOVR_OUTPUT_FILE} formatted as ${Coverage_FORMAT}" + ) +endfunction() # setup_target_for_coverage_gcovr + +function(append_coverage_compiler_flags) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) + message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}") +endfunction() # append_coverage_compiler_flags + +# Setup coverage for specific library +function(append_coverage_compiler_flags_to_target name) + separate_arguments(_flag_list NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}") + target_compile_options(${name} PRIVATE ${_flag_list}) + if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + target_link_libraries(${name} PRIVATE gcov) + endif() +endfunction() diff --git a/Builds/CMake/RippledCov.cmake b/Builds/CMake/RippledCov.cmake index e177aa52ae2..ce7536e8eeb 100644 --- a/Builds/CMake/RippledCov.cmake +++ b/Builds/CMake/RippledCov.cmake @@ -2,97 +2,37 @@ coverage report target #]===================================================================] -if (coverage) - if (is_clang) - if (APPLE) - execute_process (COMMAND xcrun -f llvm-profdata - OUTPUT_VARIABLE LLVM_PROFDATA - OUTPUT_STRIP_TRAILING_WHITESPACE) - else () - find_program (LLVM_PROFDATA llvm-profdata) - endif () - if (NOT LLVM_PROFDATA) - message (WARNING "unable to find llvm-profdata - skipping coverage_report target") - endif () +if(NOT coverage) + message(FATAL_ERROR "Code coverage not enabled! Aborting ...") +endif() - if (APPLE) - execute_process (COMMAND xcrun -f llvm-cov - OUTPUT_VARIABLE LLVM_COV - OUTPUT_STRIP_TRAILING_WHITESPACE) - else () - find_program (LLVM_COV llvm-cov) - endif () - if (NOT LLVM_COV) - message (WARNING "unable to find llvm-cov - skipping coverage_report target") - endif () +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + message(WARNING "Code coverage on Windows is not supported, ignoring 'coverage' flag") + return() +endif() - set (extract_pattern "") - if (coverage_core_only) - set (extract_pattern "${CMAKE_CURRENT_SOURCE_DIR}/src/ripple/") - endif () +include(CodeCoverage) - if (LLVM_COV AND LLVM_PROFDATA) - add_custom_target (coverage_report - USES_TERMINAL - COMMAND ${CMAKE_COMMAND} -E echo "Generating coverage - results will be in ${CMAKE_BINARY_DIR}/coverage/index.html." - COMMAND ${CMAKE_COMMAND} -E echo "Running rippled tests." - COMMAND rippled --unittest$<$:=${coverage_test}> --quiet --unittest-log - COMMAND ${LLVM_PROFDATA} - merge -sparse default.profraw -o rip.profdata - COMMAND ${CMAKE_COMMAND} -E echo "Summary of coverage:" - COMMAND ${LLVM_COV} - report -instr-profile=rip.profdata - $ ${extract_pattern} - # generate html report - COMMAND ${LLVM_COV} - show -format=html -output-dir=${CMAKE_BINARY_DIR}/coverage - -instr-profile=rip.profdata - $ ${extract_pattern} - BYPRODUCTS coverage/index.html) - endif () - elseif (is_gcc) - find_program (LCOV lcov) - if (NOT LCOV) - message (WARNING "unable to find lcov - skipping coverage_report target") - endif () +# The instructions for these commands come from the `CodeCoverage` module, +# which was copied from https://github.com/bilke/cmake-modules, commit fb7d2a3, +# then locally changed (see CHANGES: section in `CodeCoverage.cmake`) - find_program (GENHTML genhtml) - if (NOT GENHTML) - message (WARNING "unable to find genhtml - skipping coverage_report target") - endif () +set(GCOVR_ADDITIONAL_ARGS ${coverage_extra_args}) +if(NOT GCOVR_ADDITIONAL_ARGS STREQUAL "") + separate_arguments(GCOVR_ADDITIONAL_ARGS) +endif() - set (extract_pattern "*") - if (coverage_core_only) - set (extract_pattern "*/src/ripple/*") - endif () +list(APPEND GCOVR_ADDITIONAL_ARGS + --exclude-throw-branches + --exclude-noncode-lines + --exclude-unreachable-branches -s + -j ${coverage_test_parallelism}) - if (LCOV AND GENHTML) - add_custom_target (coverage_report - USES_TERMINAL - COMMAND ${CMAKE_COMMAND} -E echo "Generating coverage- results will be in ${CMAKE_BINARY_DIR}/coverage/index.html." - # create baseline info file - COMMAND ${LCOV} - --no-external -d "${CMAKE_CURRENT_SOURCE_DIR}" -c -d . -i -o baseline.info - | grep -v "ignoring data for external file" - # run tests - COMMAND ${CMAKE_COMMAND} -E echo "Running rippled tests for coverage report." - COMMAND rippled --unittest$<$:=${coverage_test}> --quiet --unittest-log - # Create test coverage data file - COMMAND ${LCOV} - --no-external -d "${CMAKE_CURRENT_SOURCE_DIR}" -c -d . -o tests.info - | grep -v "ignoring data for external file" - # Combine baseline and test coverage data - COMMAND ${LCOV} - -a baseline.info -a tests.info -o lcov-all.info - # extract our files - COMMAND ${LCOV} - -e lcov-all.info "${extract_pattern}" -o lcov.info - COMMAND ${CMAKE_COMMAND} -E echo "Summary of coverage:" - COMMAND ${LCOV} --summary lcov.info - # generate HTML report - COMMAND ${GENHTML} - -o ${CMAKE_BINARY_DIR}/coverage lcov.info - BYPRODUCTS coverage/index.html) - endif () - endif () -endif () +setup_target_for_coverage_gcovr( + NAME coverage + FORMAT ${coverage_format} + EXECUTABLE rippled + EXECUTABLE_ARGS --unittest$<$:=${coverage_test}> --unittest-jobs ${coverage_test_parallelism} --quiet --unittest-log + EXCLUDE "src/test" "${CMAKE_BINARY_DIR}/proto_gen" "${CMAKE_BINARY_DIR}/proto_gen_grpc" + DEPENDENCIES rippled +) diff --git a/Builds/CMake/RippledInterface.cmake b/Builds/CMake/RippledInterface.cmake index dfb57a52f46..56d36a528ff 100644 --- a/Builds/CMake/RippledInterface.cmake +++ b/Builds/CMake/RippledInterface.cmake @@ -23,15 +23,15 @@ target_compile_options (opts INTERFACE $<$,$>:-Wsuggest-override> $<$:-fno-omit-frame-pointer> - $<$,$>:-fprofile-arcs -ftest-coverage> - $<$,$>:-fprofile-instr-generate -fcoverage-mapping> + $<$,$>:-g --coverage -fprofile-abs-path> + $<$,$>:-g --coverage> $<$:-pg> $<$,$>:-p>) target_link_libraries (opts INTERFACE - $<$,$>:-fprofile-arcs -ftest-coverage> - $<$,$>:-fprofile-instr-generate -fcoverage-mapping> + $<$,$>:-g --coverage -fprofile-abs-path> + $<$,$>:-g --coverage> $<$:-pg> $<$,$>:-p>) diff --git a/Builds/CMake/RippledSanity.cmake b/Builds/CMake/RippledSanity.cmake index 1d217196e75..3dd5fb782fd 100644 --- a/Builds/CMake/RippledSanity.cmake +++ b/Builds/CMake/RippledSanity.cmake @@ -2,6 +2,8 @@ convenience variables and sanity checks #]===================================================================] +include(ProcessorCount) + if (NOT ep_procs) ProcessorCount(ep_procs) if (ep_procs GREATER 1) diff --git a/Builds/CMake/RippledSettings.cmake b/Builds/CMake/RippledSettings.cmake index c8195c7b922..fae09cc5d3f 100644 --- a/Builds/CMake/RippledSettings.cmake +++ b/Builds/CMake/RippledSettings.cmake @@ -2,123 +2,129 @@ declare user options/settings #]===================================================================] -option (assert "Enables asserts, even in release builds" OFF) +include(ProcessorCount) -option (reporting "Build rippled with reporting mode enabled" OFF) +ProcessorCount(PROCESSOR_COUNT) -option (tests "Build tests" ON) +option(assert "Enables asserts, even in release builds" OFF) -option (unity "Creates a build using UNITY support in cmake. This is the default" ON) -if (unity) - if (NOT is_ci) - set (CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "") - endif () -endif () -if (is_gcc OR is_clang) - option (coverage "Generates coverage info." OFF) - option (profile "Add profiling flags" OFF) - set (coverage_test "" CACHE STRING +option(reporting "Build rippled with reporting mode enabled" OFF) + +option(tests "Build tests" ON) + +option(unity "Creates a build using UNITY support in cmake. This is the default" ON) +if(unity) + if(NOT is_ci) + set(CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "") + endif() +endif() +if(is_gcc OR is_clang) + option(coverage "Generates coverage info." OFF) + option(profile "Add profiling flags" OFF) + set(coverage_test_parallelism "${PROCESSOR_COUNT}" CACHE STRING + "Unit tests parallelism for the purpose of coverage report.") + set(coverage_format "html-details" CACHE STRING + "Output format of the coverage report.") + set(coverage_extra_args "" CACHE STRING + "Additional arguments to pass to gcovr.") + set(coverage_test "" CACHE STRING "On gcc & clang, the specific unit test(s) to run for coverage. Default is all tests.") - if (coverage_test AND NOT coverage) - set (coverage ON CACHE BOOL "gcc/clang only" FORCE) - endif () - option (coverage_core_only - "Include only src/ripple files when generating coverage report. \ - Set to OFF to include all sources in coverage report." - ON) - option (wextra "compile with extra gcc/clang warnings enabled" ON) -else () - set (profile OFF CACHE BOOL "gcc/clang only" FORCE) - set (coverage OFF CACHE BOOL "gcc/clang only" FORCE) - set (wextra OFF CACHE BOOL "gcc/clang only" FORCE) -endif () -if (is_linux) - option (BUILD_SHARED_LIBS "build shared ripple libraries" OFF) - option (static "link protobuf, openssl, libc++, and boost statically" ON) - option (perf "Enables flags that assist with perf recording" OFF) - option (use_gold "enables detection of gold (binutils) linker" ON) - option (use_mold "enables detection of mold (binutils) linker" ON) -else () + if(coverage_test AND NOT coverage) + set(coverage ON CACHE BOOL "gcc/clang only" FORCE) + endif() + option(wextra "compile with extra gcc/clang warnings enabled" ON) +else() + set(profile OFF CACHE BOOL "gcc/clang only" FORCE) + set(coverage OFF CACHE BOOL "gcc/clang only" FORCE) + set(wextra OFF CACHE BOOL "gcc/clang only" FORCE) +endif() +if(is_linux) + option(BUILD_SHARED_LIBS "build shared ripple libraries" OFF) + option(static "link protobuf, openssl, libc++, and boost statically" ON) + option(perf "Enables flags that assist with perf recording" OFF) + option(use_gold "enables detection of gold (binutils) linker" ON) + option(use_mold "enables detection of mold (binutils) linker" ON) +else() # we are not ready to allow shared-libs on windows because it would require # export declarations. On macos it's more feasible, but static openssl # produces odd linker errors, thus we disable shared lib builds for now. - set (BUILD_SHARED_LIBS OFF CACHE BOOL "build shared ripple libraries - OFF for win/macos" FORCE) - set (static ON CACHE BOOL "static link, linux only. ON for WIN/macos" FORCE) - set (perf OFF CACHE BOOL "perf flags, linux only" FORCE) - set (use_gold OFF CACHE BOOL "gold linker, linux only" FORCE) - set (use_mold OFF CACHE BOOL "mold linker, linux only" FORCE) -endif () -if (is_clang) - option (use_lld "enables detection of lld linker" ON) -else () - set (use_lld OFF CACHE BOOL "try lld linker, clang only" FORCE) -endif () -option (jemalloc "Enables jemalloc for heap profiling" OFF) -option (werr "treat warnings as errors" OFF) -option (local_protobuf + set(BUILD_SHARED_LIBS OFF CACHE BOOL "build shared ripple libraries - OFF for win/macos" FORCE) + set(static ON CACHE BOOL "static link, linux only. ON for WIN/macos" FORCE) + set(perf OFF CACHE BOOL "perf flags, linux only" FORCE) + set(use_gold OFF CACHE BOOL "gold linker, linux only" FORCE) + set(use_mold OFF CACHE BOOL "mold linker, linux only" FORCE) +endif() +if(is_clang) + option(use_lld "enables detection of lld linker" ON) +else() + set(use_lld OFF CACHE BOOL "try lld linker, clang only" FORCE) +endif() +option(jemalloc "Enables jemalloc for heap profiling" OFF) +option(werr "treat warnings as errors" OFF) +option(local_protobuf "Force a local build of protobuf instead of looking for an installed version." OFF) -option (local_grpc +option(local_grpc "Force a local build of gRPC instead of looking for an installed version." OFF) # this one is a string and therefore can't be an option -set (san "" CACHE STRING "On gcc & clang, add sanitizer instrumentation") -set_property (CACHE san PROPERTY STRINGS ";undefined;memory;address;thread") -if (san) - string (TOLOWER ${san} san) - set (SAN_FLAG "-fsanitize=${san}") - set (SAN_LIB "") - if (is_gcc) - if (san STREQUAL "address") - set (SAN_LIB "asan") - elseif (san STREQUAL "thread") - set (SAN_LIB "tsan") - elseif (san STREQUAL "memory") - set (SAN_LIB "msan") - elseif (san STREQUAL "undefined") - set (SAN_LIB "ubsan") - endif () - endif () - set (_saved_CRL ${CMAKE_REQUIRED_LIBRARIES}) - set (CMAKE_REQUIRED_LIBRARIES "${SAN_FLAG};${SAN_LIB}") - check_cxx_compiler_flag (${SAN_FLAG} COMPILER_SUPPORTS_SAN) - set (CMAKE_REQUIRED_LIBRARIES ${_saved_CRL}) - if (NOT COMPILER_SUPPORTS_SAN) - message (FATAL_ERROR "${san} sanitizer does not seem to be supported by your compiler") - endif () -endif () -set (container_label "" CACHE STRING "tag to use for package building containers") -option (packages_only +set(san "" CACHE STRING "On gcc & clang, add sanitizer instrumentation") +set_property(CACHE san PROPERTY STRINGS ";undefined;memory;address;thread") +if(san) + string(TOLOWER ${san} san) + set(SAN_FLAG "-fsanitize=${san}") + set(SAN_LIB "") + if(is_gcc) + if(san STREQUAL "address") + set(SAN_LIB "asan") + elseif(san STREQUAL "thread") + set(SAN_LIB "tsan") + elseif(san STREQUAL "memory") + set(SAN_LIB "msan") + elseif(san STREQUAL "undefined") + set(SAN_LIB "ubsan") + endif() + endif() + set(_saved_CRL ${CMAKE_REQUIRED_LIBRARIES}) + set(CMAKE_REQUIRED_LIBRARIES "${SAN_FLAG};${SAN_LIB}") + check_cxx_compiler_flag(${SAN_FLAG} COMPILER_SUPPORTS_SAN) + set(CMAKE_REQUIRED_LIBRARIES ${_saved_CRL}) + if(NOT COMPILER_SUPPORTS_SAN) + message(FATAL_ERROR "${san} sanitizer does not seem to be supported by your compiler") + endif() +endif() +set(container_label "" CACHE STRING "tag to use for package building containers") +option(packages_only "ONLY generate package building targets. This is special use-case and almost \ certainly not what you want. Use with caution as you won't be able to build \ any compiled targets locally." OFF) -option (have_package_container +option(have_package_container "Sometimes you already have the tagged container you want to use for package \ building and you don't want docker to rebuild it. This flag will detach the \ dependency of the package build from the container build. It's an advanced \ use case and most likely you should not be touching this flag." OFF) # the remaining options are obscure and rarely used -option (beast_no_unit_test_inline +option(beast_no_unit_test_inline "Prevents unit test definitions from being inserted into global table" OFF) -option (single_io_service_thread +option(single_io_service_thread "Restricts the number of threads calling io_service::run to one. \ This can be useful when debugging." OFF) -option (boost_show_deprecated +option(boost_show_deprecated "Allow boost to fail on deprecated usage. Only useful if you're trying\ to find deprecated calls." OFF) -option (beast_hashers +option(beast_hashers "Use local implementations for sha/ripemd hashes (experimental, not recommended)" OFF) -if (WIN32) - option (beast_disable_autolink "Disables autolinking of system libraries on WIN32" OFF) -else () - set (beast_disable_autolink OFF CACHE BOOL "WIN32 only" FORCE) -endif () -if (coverage) - message (STATUS "coverage build requested - forcing Debug build") - set (CMAKE_BUILD_TYPE Debug CACHE STRING "build type" FORCE) -endif () +if(WIN32) + option(beast_disable_autolink "Disables autolinking of system libraries on WIN32" OFF) +else() + set(beast_disable_autolink OFF CACHE BOOL "WIN32 only" FORCE) +endif() +if(coverage) + message(STATUS "coverage build requested - forcing Debug build") + set(CMAKE_BUILD_TYPE Debug CACHE STRING "build type" FORCE) +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bbde549602..d324008ac40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,7 +38,6 @@ include (CheckCXXCompilerFlag) include (FetchContent) include (ExternalProject) include (CMakeFuncs) # must come *after* ExternalProject b/c it overrides one function in EP -include (ProcessorCount) if (target) message (FATAL_ERROR "The target option has been removed - use native cmake options to control build") endif () @@ -126,12 +125,15 @@ if(reporting) ) endif() +if(coverage) + include(RippledCov) +endif() + ### include(RippledCore) include(deps/Protobuf) include(deps/gRPC) include(RippledInstall) -include(RippledCov) include(RippledMultiConfig) include(RippledValidatorKeys) diff --git a/bin/ci/ubuntu/build-and-test.sh b/bin/ci/ubuntu/build-and-test.sh index 7ae75f2b16a..2c1734863fb 100755 --- a/bin/ci/ubuntu/build-and-test.sh +++ b/bin/ci/ubuntu/build-and-test.sh @@ -44,7 +44,7 @@ if [[ ${NINJA_BUILD:-} == true ]]; then fi coverage=false -if [[ "${TARGET}" == "coverage_report" ]] ; then +if [[ "${TARGET}" == "coverage" ]] ; then echo "coverage option detected." coverage=true fi