Compare commits

..

2 Commits

Author SHA1 Message Date
Ayaz Salikhov
b11c1c9987 Up build 2025-06-23 22:11:37 +00:00
Ayaz Salikhov
43a4d15d2d fix: Don't cancel ci image builds 2025-06-23 21:40:56 +01:00
845 changed files with 29978 additions and 51993 deletions

View File

@@ -22,7 +22,7 @@ BreakBeforeBinaryOperators: false
BreakBeforeBraces: WebKit BreakBeforeBraces: WebKit
BreakBeforeTernaryOperators: true BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true BreakConstructorInitializersBeforeComma: true
ColumnLimit: 100 ColumnLimit: 120
CommentPragmas: "^ IWYU pragma:" CommentPragmas: "^ IWYU pragma:"
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4 ConstructorInitializerIndentWidth: 4
@@ -49,7 +49,6 @@ IndentFunctionDeclarationAfterType: false
IndentWidth: 4 IndentWidth: 4
IndentWrappedFunctionNames: false IndentWrappedFunctionNames: false
IndentRequiresClause: true IndentRequiresClause: true
InsertNewlineAtEOF: true
RequiresClausePosition: OwnLine RequiresClausePosition: OwnLine
KeepEmptyLinesAtTheStartOfBlocks: false KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1

245
.cmake-format.yaml Normal file
View File

@@ -0,0 +1,245 @@
_help_parse: Options affecting listfile parsing
parse:
_help_additional_commands:
- Specify structure for custom cmake functions
additional_commands:
foo:
flags:
- BAR
- BAZ
kwargs:
HEADERS: "*"
SOURCES: "*"
DEPENDS: "*"
_help_override_spec:
- Override configurations per-command where available
override_spec: {}
_help_vartags:
- Specify variable tags.
vartags: []
_help_proptags:
- Specify property tags.
proptags: []
_help_format: Options affecting formatting.
format:
_help_disable:
- Disable formatting entirely, making cmake-format a no-op
disable: false
_help_line_width:
- How wide to allow formatted cmake files
line_width: 120
_help_tab_size:
- How many spaces to tab for indent
tab_size: 2
_help_use_tabchars:
- If true, lines are indented using tab characters (utf-8
- 0x09) instead of <tab_size> space characters (utf-8 0x20).
- In cases where the layout would require a fractional tab
- character, the behavior of the fractional indentation is
- governed by <fractional_tab_policy>
use_tabchars: false
_help_fractional_tab_policy:
- If <use_tabchars> is True, then the value of this variable
- indicates how fractional indentions are handled during
- whitespace replacement. If set to 'use-space', fractional
- indentation is left as spaces (utf-8 0x20). If set to
- "`round-up` fractional indentation is replaced with a single"
- tab character (utf-8 0x09) effectively shifting the column
- to the next tabstop
fractional_tab_policy: use-space
_help_max_subgroups_hwrap:
- If an argument group contains more than this many sub-groups
- (parg or kwarg groups) then force it to a vertical layout.
max_subgroups_hwrap: 4
_help_max_pargs_hwrap:
- If a positional argument group contains more than this many
- arguments, then force it to a vertical layout.
max_pargs_hwrap: 6
_help_max_rows_cmdline:
- If a cmdline positional group consumes more than this many
- lines without nesting, then invalidate the layout (and nest)
max_rows_cmdline: 2
_help_separate_ctrl_name_with_space:
- If true, separate flow control names from their parentheses
- with a space
separate_ctrl_name_with_space: true
_help_separate_fn_name_with_space:
- If true, separate function names from parentheses with a
- space
separate_fn_name_with_space: false
_help_dangle_parens:
- If a statement is wrapped to more than one line, than dangle
- the closing parenthesis on its own line.
dangle_parens: true
_help_dangle_align:
- If the trailing parenthesis must be 'dangled' on its on
- "line, then align it to this reference: `prefix`: the start"
- "of the statement, `prefix-indent`: the start of the"
- "statement, plus one indentation level, `child`: align to"
- the column of the arguments
dangle_align: prefix
_help_min_prefix_chars:
- If the statement spelling length (including space and
- parenthesis) is smaller than this amount, then force reject
- nested layouts.
min_prefix_chars: 4
_help_max_prefix_chars:
- If the statement spelling length (including space and
- parenthesis) is larger than the tab width by more than this
- amount, then force reject un-nested layouts.
max_prefix_chars: 10
_help_max_lines_hwrap:
- If a candidate layout is wrapped horizontally but it exceeds
- this many lines, then reject the layout.
max_lines_hwrap: 2
_help_line_ending:
- What style line endings to use in the output.
line_ending: unix
_help_command_case:
- Format command names consistently as 'lower' or 'upper' case
command_case: canonical
_help_keyword_case:
- Format keywords consistently as 'lower' or 'upper' case
keyword_case: unchanged
_help_always_wrap:
- A list of command names which should always be wrapped
always_wrap: []
_help_enable_sort:
- If true, the argument lists which are known to be sortable
- will be sorted lexicographicall
enable_sort: true
_help_autosort:
- If true, the parsers may infer whether or not an argument
- list is sortable (without annotation).
autosort: true
_help_require_valid_layout:
- By default, if cmake-format cannot successfully fit
- everything into the desired linewidth it will apply the
- last, most aggressive attempt that it made. If this flag is
- True, however, cmake-format will print error, exit with non-
- zero status code, and write-out nothing
require_valid_layout: false
_help_layout_passes:
- A dictionary mapping layout nodes to a list of wrap
- decisions. See the documentation for more information.
layout_passes: {}
_help_markup: Options affecting comment reflow and formatting.
markup:
_help_bullet_char:
- What character to use for bulleted lists
bullet_char: "*"
_help_enum_char:
- What character to use as punctuation after numerals in an
- enumerated list
enum_char: .
_help_first_comment_is_literal:
- If comment markup is enabled, don't reflow the first comment
- block in each listfile. Use this to preserve formatting of
- your copyright/license statements.
first_comment_is_literal: false
_help_literal_comment_pattern:
- If comment markup is enabled, don't reflow any comment block
- which matches this (regex) pattern. Default is `None`
- (disabled).
literal_comment_pattern: null
_help_fence_pattern:
- Regular expression to match preformat fences in comments
- default= ``r'^\s*([`~]{3}[`~]*)(.*)$'``
fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
_help_ruler_pattern:
- Regular expression to match rulers in comments default=
- '``r''^\s*[^\w\s]{3}.*[^\w\s]{3}$''``'
ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
_help_explicit_trailing_pattern:
- If a comment line matches starts with this pattern then it
- is explicitly a trailing comment for the preceding
- argument. Default is '#<'
explicit_trailing_pattern: "#<"
_help_hashruler_min_length:
- If a comment line starts with at least this many consecutive
- hash characters, then don't lstrip() them off. This allows
- for lazy hash rulers where the first hash char is not
- separated by space
hashruler_min_length: 10
_help_canonicalize_hashrulers:
- If true, then insert a space between the first hash char and
- remaining hash chars in a hash ruler, and normalize its
- length to fill the column
canonicalize_hashrulers: true
_help_enable_markup:
- enable comment markup parsing and reflow
enable_markup: true
_help_lint: Options affecting the linter
lint:
_help_disabled_codes:
- a list of lint codes to disable
disabled_codes: []
_help_function_pattern:
- regular expression pattern describing valid function names
function_pattern: "[0-9a-z_]+"
_help_macro_pattern:
- regular expression pattern describing valid macro names
macro_pattern: "[0-9A-Z_]+"
_help_global_var_pattern:
- regular expression pattern describing valid names for
- variables with global (cache) scope
global_var_pattern: "[A-Z][0-9A-Z_]+"
_help_internal_var_pattern:
- regular expression pattern describing valid names for
- variables with global scope (but internal semantic)
internal_var_pattern: _[A-Z][0-9A-Z_]+
_help_local_var_pattern:
- regular expression pattern describing valid names for
- variables with local scope
local_var_pattern: "[a-z][a-z0-9_]+"
_help_private_var_pattern:
- regular expression pattern describing valid names for
- privatedirectory variables
private_var_pattern: _[0-9a-z_]+
_help_public_var_pattern:
- regular expression pattern describing valid names for public
- directory variables
public_var_pattern: "[A-Z][0-9A-Z_]+"
_help_argument_var_pattern:
- regular expression pattern describing valid names for
- function/macro arguments and loop variables.
argument_var_pattern: "[a-z][a-z0-9_]+"
_help_keyword_pattern:
- regular expression pattern describing valid names for
- keywords used in functions or macros
keyword_pattern: "[A-Z][0-9A-Z_]+"
_help_max_conditionals_custom_parser:
- In the heuristic for C0201, how many conditionals to match
- within a loop in before considering the loop a parser.
max_conditionals_custom_parser: 2
_help_min_statement_spacing:
- Require at least this many newlines between statements
min_statement_spacing: 1
_help_max_statement_spacing:
- Require no more than this many newlines between statements
max_statement_spacing: 2
max_returns: 6
max_branches: 12
max_arguments: 5
max_localvars: 15
max_statements: 50
_help_encode: Options affecting file encoding
encode:
_help_emit_byteorder_mark:
- If true, emit the unicode byte-order mark (BOM) at the start
- of the file
emit_byteorder_mark: false
_help_input_encoding:
- Specify the encoding of the input file. Defaults to utf-8
input_encoding: utf-8
_help_output_encoding:
- Specify the encoding of the output file. Defaults to utf-8.
- Note that cmake only claims to support utf-8 so be careful
- when using anything else
output_encoding: utf-8
_help_misc: Miscellaneous configurations options.
misc:
_help_per_command:
- A dictionary containing any per-command configuration
- overrides. Currently only `command_case` is supported.
per_command: {}

View File

@@ -16,7 +16,6 @@ coverage:
# #
# More info: https://github.com/XRPLF/clio/pull/2066 # More info: https://github.com/XRPLF/clio/pull/2066
ignore: ignore:
- "benchmarks"
- "tests" - "tests"
- "src/data/cassandra/" - "src/data/cassandra/"
- "src/data/CassandraBackend.hpp" - "src/data/CassandraBackend.hpp"

View File

@@ -1,31 +0,0 @@
name: Build clio
description: Build clio in build directory
inputs:
targets:
description: Space-separated build target names
default: all
nproc_subtract:
description: The number of processors to subtract when calculating parallelism.
required: true
default: "0"
runs:
using: composite
steps:
- name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf
id: nproc
with:
subtract: ${{ inputs.nproc_subtract }}
- name: Build targets
shell: bash
env:
CMAKE_TARGETS: ${{ inputs.targets }}
run: |
cd build
cmake \
--build . \
--parallel "${{ steps.nproc.outputs.nproc }}" \
--target ${CMAKE_TARGETS}

29
.github/actions/build_clio/action.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Build clio
description: Build clio in build directory
inputs:
targets:
description: Space-separated build target names
default: all
subtract_threads:
description: An option for the action get_number_of_threads. See get_number_of_threads
required: true
default: "0"
runs:
using: composite
steps:
- name: Get number of threads
uses: ./.github/actions/get_number_of_threads
id: number_of_threads
with:
subtract_threads: ${{ inputs.subtract_threads }}
- name: Build targets
shell: bash
run: |
cd build
cmake \
--build . \
--parallel "${{ steps.number_of_threads.outputs.threads_number }}" \
--target ${{ inputs.targets }}

View File

@@ -17,14 +17,10 @@ inputs:
platforms: platforms:
description: Platforms to build the image for (e.g. linux/amd64,linux/arm64) description: Platforms to build the image for (e.g. linux/amd64,linux/arm64)
required: true required: true
build_args:
description: List of build-time variables
required: false
dockerhub_repo: dockerhub_repo:
description: DockerHub repository name description: DockerHub repository name
required: false required: false
default: ""
dockerhub_description: dockerhub_description:
description: Short description of the image description: Short description of the image
required: false required: false
@@ -34,25 +30,25 @@ runs:
steps: steps:
- name: Login to DockerHub - name: Login to DockerHub
if: ${{ inputs.push_image == 'true' && inputs.dockerhub_repo != '' }} if: ${{ inputs.push_image == 'true' && inputs.dockerhub_repo != '' }}
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with: with:
username: ${{ env.DOCKERHUB_USER }} username: ${{ env.DOCKERHUB_USER }}
password: ${{ env.DOCKERHUB_PW }} password: ${{ env.DOCKERHUB_PW }}
- name: Login to GitHub Container Registry - name: Login to GitHub Container Registry
if: ${{ inputs.push_image == 'true' }} if: ${{ inputs.push_image == 'true' }}
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0 uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.repository_owner }} username: ${{ github.repository_owner }}
password: ${{ env.GITHUB_TOKEN }} password: ${{ env.GITHUB_TOKEN }}
- uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3.7.0 - uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0
with: with:
cache-image: false cache-image: false
- uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0 - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
- uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5.10.0 - uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
id: meta id: meta
with: with:
images: ${{ inputs.images }} images: ${{ inputs.images }}
@@ -65,4 +61,13 @@ runs:
platforms: ${{ inputs.platforms }} platforms: ${{ inputs.platforms }}
push: ${{ inputs.push_image == 'true' }} push: ${{ inputs.push_image == 'true' }}
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
build-args: ${{ inputs.build_args }}
- name: Update DockerHub description
if: ${{ inputs.push_image == 'true' && inputs.dockerhub_repo != '' }}
uses: peter-evans/dockerhub-description@432a30c9e07499fd01da9f8a49f0faf9e0ca5b77 # v4.0.2
with:
username: ${{ env.DOCKERHUB_USER }}
password: ${{ env.DOCKERHUB_PW }}
repository: ${{ inputs.dockerhub_repo }}
short-description: ${{ inputs.dockerhub_description }}
readme-filepath: ${{ inputs.directory }}/README.md

View File

@@ -1,41 +0,0 @@
name: Cache key
description: Generate cache key for ccache
inputs:
conan_profile:
description: Conan profile name
required: true
build_type:
description: Current build type (e.g. Release, Debug)
required: true
default: Release
code_coverage:
description: Whether code coverage is on
required: true
default: "false"
outputs:
key:
description: Generated cache key for ccache
value: ${{ steps.key_without_commit.outputs.key }}-${{ steps.git_common_ancestor.outputs.commit }}
restore_keys:
description: Cache restore keys for fallback
value: ${{ steps.key_without_commit.outputs.key }}
runs:
using: composite
steps:
- name: Find common commit
id: git_common_ancestor
uses: ./.github/actions/git-common-ancestor
- name: Set cache key without commit
id: key_without_commit
shell: bash
env:
RUNNER_OS: ${{ runner.os }}
BUILD_TYPE: ${{ inputs.build_type }}
CODE_COVERAGE: ${{ inputs.code_coverage == 'true' && '-code_coverage' || '' }}
CONAN_PROFILE: ${{ inputs.conan_profile }}
run: |
echo "key=clio-ccache-${RUNNER_OS}-${BUILD_TYPE}${CODE_COVERAGE}-${CONAN_PROFILE}-develop" >> "${GITHUB_OUTPUT}"

View File

@@ -1,91 +0,0 @@
name: Run CMake
description: Run CMake to generate build files
inputs:
build_dir:
description: Build directory
required: false
default: "build"
conan_profile:
description: Conan profile name
required: true
build_type:
description: Build type for third-party libraries and clio. Could be 'Release', 'Debug'
required: true
default: "Release"
integration_tests:
description: Whether to generate target integration tests
required: true
default: "true"
benchmark:
description: Whether to generate targets for benchmarks
required: true
default: "true"
code_coverage:
description: Whether to enable code coverage
required: true
default: "false"
static:
description: Whether Clio is to be statically linked
required: true
default: "false"
time_trace:
description: Whether to enable compiler trace reports
required: true
default: "false"
package:
description: Whether to generate Debian package
required: true
default: "false"
version:
description: Version of the clio_server binary
required: false
default: ""
runs:
using: composite
steps:
- name: Run cmake
shell: bash
env:
BUILD_DIR: "${{ inputs.build_dir }}"
BUILD_TYPE: "${{ inputs.build_type }}"
SANITIZER_OPTION: |-
${{ endsWith(inputs.conan_profile, '.asan') && '-Dsan=address' ||
endsWith(inputs.conan_profile, '.tsan') && '-Dsan=thread' ||
endsWith(inputs.conan_profile, '.ubsan') && '-Dsan=undefined' ||
'' }}
INTEGRATION_TESTS: "${{ inputs.integration_tests == 'true' && 'ON' || 'OFF' }}"
BENCHMARK: "${{ inputs.benchmark == 'true' && 'ON' || 'OFF' }}"
COVERAGE: "${{ inputs.code_coverage == 'true' && 'ON' || 'OFF' }}"
STATIC: "${{ inputs.static == 'true' && 'ON' || 'OFF' }}"
TIME_TRACE: "${{ inputs.time_trace == 'true' && 'ON' || 'OFF' }}"
PACKAGE: "${{ inputs.package == 'true' && 'ON' || 'OFF' }}"
# GitHub creates a merge commit for a PR
# https://www.kenmuse.com/blog/the-many-shas-of-a-github-pull-request/
#
# We:
# - explicitly provide branch name
# - use `github.head_ref` to get the SHA of last commit in the PR branch
#
# This way it works both for PRs and pushes to branches.
GITHUB_BRANCH_NAME: "${{ github.head_ref || github.ref_name }}"
GITHUB_HEAD_SHA: "${{ github.event.pull_request.head.sha || github.sha }}"
#
# If tag is being pushed, or it's a nightly release, we use that version.
FORCE_CLIO_VERSION: ${{ inputs.version }}
run: |
cmake \
-B "${BUILD_DIR}" \
-S . \
-G Ninja \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
"${SANITIZER_OPTION}" \
-Dtests=ON \
-Dintegration_tests="${INTEGRATION_TESTS}" \
-Dbenchmark="${BENCHMARK}" \
-Dcoverage="${COVERAGE}" \
-Dstatic="${STATIC}" \
-Dtime_trace="${TIME_TRACE}" \
-Dpackage="${PACKAGE}"

View File

@@ -15,7 +15,6 @@ runs:
shell: bash shell: bash
run: | run: |
gcovr \ gcovr \
-e benchmarks \
-e tests \ -e tests \
-e src/data/cassandra \ -e src/data/cassandra \
-e src/data/CassandraBackend.hpp \ -e src/data/CassandraBackend.hpp \
@@ -24,7 +23,7 @@ runs:
-j8 --exclude-throw-branches -j8 --exclude-throw-branches
- name: Archive coverage report - name: Archive coverage report
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@v4
with: with:
name: coverage-report.xml name: coverage-report.xml
path: build/coverage_report.xml path: build/coverage_report.xml

View File

@@ -1,37 +0,0 @@
name: Run Conan
description: Run conan to install dependencies
inputs:
build_dir:
description: Build directory
required: false
default: "build"
conan_profile:
description: Conan profile name
required: true
force_conan_source_build:
description: Whether conan should build all dependencies from source
required: true
default: "false"
build_type:
description: Build type for third-party libraries and clio. Could be 'Release', 'Debug'
required: true
default: "Release"
runs:
using: composite
steps:
- name: Run conan
shell: bash
env:
BUILD_DIR: "${{ inputs.build_dir }}"
CONAN_BUILD_OPTION: "${{ inputs.force_conan_source_build == 'true' && '*' || 'missing' }}"
BUILD_TYPE: "${{ inputs.build_type }}"
CONAN_PROFILE: "${{ inputs.conan_profile }}"
run: |
conan \
install . \
-of "${BUILD_DIR}" \
-b "${CONAN_BUILD_OPTION}" \
-s "build_type=${BUILD_TYPE}" \
--profile:all "${CONAN_PROFILE}"

View File

@@ -28,17 +28,12 @@ runs:
- name: Create an issue - name: Create an issue
id: create_issue id: create_issue
shell: bash shell: bash
env:
ISSUE_BODY: ${{ inputs.body }}
ISSUE_ASSIGNEES: ${{ inputs.assignees }}
ISSUE_LABELS: ${{ inputs.labels }}
ISSUE_TITLE: ${{ inputs.title }}
run: | run: |
echo -e "${ISSUE_BODY}" > issue.md echo -e '${{ inputs.body }}' > issue.md
gh issue create \ gh issue create \
--assignee "${ISSUE_ASSIGNEES}" \ --assignee '${{ inputs.assignees }}' \
--label "${ISSUE_LABELS}" \ --label '${{ inputs.labels }}' \
--title "${ISSUE_TITLE}" \ --title '${{ inputs.title }}' \
--body-file ./issue.md \ --body-file ./issue.md \
> create_issue.log > create_issue.log
created_issue="$(sed 's|.*/||' create_issue.log)" created_issue="$(sed 's|.*/||' create_issue.log)"

79
.github/actions/generate/action.yml vendored Normal file
View File

@@ -0,0 +1,79 @@
name: Run conan and cmake
description: Run conan and cmake
inputs:
conan_profile:
description: Conan profile name
required: true
force_conan_source_build:
description: Whether conan should build all dependencies from source
required: true
default: "false"
build_type:
description: Build type for third-party libraries and clio. Could be 'Release', 'Debug'
required: true
default: "Release"
build_integration_tests:
description: Whether to build integration tests
required: true
default: "true"
code_coverage:
description: Whether conan's coverage option should be on or not
required: true
default: "false"
static:
description: Whether Clio is to be statically linked
required: true
default: "false"
time_trace:
description: Whether to enable compiler trace reports
required: true
default: "false"
runs:
using: composite
steps:
- name: Create build directory
shell: bash
run: mkdir -p build
- name: Run conan
shell: bash
env:
CONAN_BUILD_OPTION: "${{ inputs.force_conan_source_build == 'true' && '*' || 'missing' }}"
CODE_COVERAGE: "${{ inputs.code_coverage == 'true' && 'True' || 'False' }}"
STATIC_OPTION: "${{ inputs.static == 'true' && 'True' || 'False' }}"
INTEGRATION_TESTS_OPTION: "${{ inputs.build_integration_tests == 'true' && 'True' || 'False' }}"
TIME_TRACE: "${{ inputs.time_trace == 'true' && 'True' || 'False' }}"
run: |
cd build
conan \
install .. \
-of . \
-b "$CONAN_BUILD_OPTION" \
-s "build_type=${{ inputs.build_type }}" \
-o "&:static=${STATIC_OPTION}" \
-o "&:tests=True" \
-o "&:integration_tests=${INTEGRATION_TESTS_OPTION}" \
-o "&:lint=False" \
-o "&:coverage=${CODE_COVERAGE}" \
-o "&:time_trace=${TIME_TRACE}" \
--profile:all "${{ inputs.conan_profile }}"
- name: Run cmake
shell: bash
env:
BUILD_TYPE: "${{ inputs.build_type }}"
SANITIZER_OPTION: |-
${{ endsWith(inputs.conan_profile, '.asan') && '-Dsan=address' ||
endsWith(inputs.conan_profile, '.tsan') && '-Dsan=thread' ||
endsWith(inputs.conan_profile, '.ubsan') && '-Dsan=undefined' ||
'' }}
run: |
cd build
cmake \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
"${SANITIZER_OPTION}" \
.. \
-G Ninja

View File

@@ -0,0 +1,36 @@
name: Get number of threads
description: Determines number of threads to use on macOS and Linux
inputs:
subtract_threads:
description: How many threads to subtract from the calculated number
required: true
default: "0"
outputs:
threads_number:
description: Number of threads to use
value: ${{ steps.number_of_threads_export.outputs.num }}
runs:
using: composite
steps:
- name: Get number of threads on mac
id: mac_threads
if: ${{ runner.os == 'macOS' }}
shell: bash
run: echo "num=$(($(sysctl -n hw.logicalcpu) - 2))" >> $GITHUB_OUTPUT
- name: Get number of threads on Linux
id: linux_threads
if: ${{ runner.os == 'Linux' }}
shell: bash
run: echo "num=$(($(nproc) - 2))" >> $GITHUB_OUTPUT
- name: Shift and export number of threads
id: number_of_threads_export
shell: bash
run: |
num_of_threads="${{ steps.mac_threads.outputs.num || steps.linux_threads.outputs.num }}"
shift_by="${{ inputs.subtract_threads }}"
shifted="$((num_of_threads - shift_by))"
echo "num=$(( shifted > 1 ? shifted : 1 ))" >> $GITHUB_OUTPUT

View File

@@ -0,0 +1,77 @@
name: Prepare runner
description: Install packages, set environment variables, create directories
inputs:
disable_ccache:
description: Whether ccache should be disabled
required: true
runs:
using: composite
steps:
- name: Install packages on mac
if: ${{ runner.os == 'macOS' }}
shell: bash
run: |
brew install --quiet \
bison \
ca-certificates \
ccache \
clang-build-analyzer \
conan \
gh \
jq \
llvm@14 \
ninja \
pkg-config
echo "/opt/homebrew/opt/conan@2/bin" >> $GITHUB_PATH
- name: Install CMake 3.31.6 on mac
if: ${{ runner.os == 'macOS' }}
shell: bash
run: |
# Uninstall any existing cmake
brew uninstall --formula cmake --ignore-dependencies || true
# Download specific cmake formula
FORMULA_URL="https://raw.githubusercontent.com/Homebrew/homebrew-core/b4e46db74e74a8c1650b38b1da222284ce1ec5ce/Formula/c/cmake.rb"
FORMULA_EXPECTED_SHA256="c7ec95d86f0657638835441871e77541165e0a2581b53b3dd657cf13ad4228d4"
mkdir -p /tmp/homebrew-formula
curl -s -L "$FORMULA_URL" -o /tmp/homebrew-formula/cmake.rb
echo "$FORMULA_EXPECTED_SHA256 /tmp/homebrew-formula/cmake.rb" | shasum -a 256 -c
# Install cmake from the specific formula with force flag
brew install --formula --quiet --force /tmp/homebrew-formula/cmake.rb
- name: Fix git permissions on Linux
if: ${{ runner.os == 'Linux' }}
shell: bash
run: git config --global --add safe.directory "$PWD"
- name: Set env variables for macOS
if: ${{ runner.os == 'macOS' }}
shell: bash
run: |
echo "CCACHE_DIR=${{ github.workspace }}/.ccache" >> $GITHUB_ENV
echo "CONAN_HOME=${{ github.workspace }}/.conan2" >> $GITHUB_ENV
- name: Set env variables for Linux
if: ${{ runner.os == 'Linux' }}
shell: bash
run: |
echo "CCACHE_DIR=/root/.ccache" >> $GITHUB_ENV
echo "CONAN_HOME=/root/.conan2" >> $GITHUB_ENV
- name: Set CCACHE_DISABLE=1
if: ${{ inputs.disable_ccache == 'true' }}
shell: bash
run: |
echo "CCACHE_DISABLE=1" >> $GITHUB_ENV
- name: Create directories
shell: bash
run: |
mkdir -p "$CCACHE_DIR"
mkdir -p "$CONAN_HOME"

View File

@@ -0,0 +1,38 @@
name: Restore cache
description: Find and restores ccache cache
inputs:
conan_profile:
description: Conan profile name
required: true
ccache_dir:
description: Path to .ccache directory
required: true
build_type:
description: Current build type (e.g. Release, Debug)
required: true
default: Release
code_coverage:
description: Whether code coverage is on
required: true
default: "false"
outputs:
ccache_cache_hit:
description: True if ccache cache has been downloaded
value: ${{ steps.ccache_cache.outputs.cache-hit }}
runs:
using: composite
steps:
- name: Find common commit
id: git_common_ancestor
uses: ./.github/actions/git_common_ancestor
- name: Restore ccache cache
uses: actions/cache/restore@v4
id: ccache_cache
if: ${{ env.CCACHE_DISABLE != '1' }}
with:
path: ${{ inputs.ccache_dir }}
key: clio-ccache-${{ runner.os }}-${{ inputs.build_type }}${{ inputs.code_coverage == 'true' && '-code_coverage' || '' }}-${{ inputs.conan_profile }}-develop-${{ steps.git_common_ancestor.outputs.commit }}

38
.github/actions/save_cache/action.yml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: Save cache
description: Save ccache cache for develop branch
inputs:
conan_profile:
description: Conan profile name
required: true
ccache_dir:
description: Path to .ccache directory
required: true
build_type:
description: Current build type (e.g. Release, Debug)
required: true
default: Release
code_coverage:
description: Whether code coverage is on
required: true
default: "false"
ccache_cache_hit:
description: Whether ccache cache has been downloaded
required: true
ccache_cache_miss_rate:
description: How many ccache cache misses happened
runs:
using: composite
steps:
- name: Find common commit
id: git_common_ancestor
uses: ./.github/actions/git_common_ancestor
- name: Save ccache cache
if: ${{ inputs.ccache_cache_hit != 'true' || inputs.ccache_cache_miss_rate == '100.0' }}
uses: actions/cache/save@v4
with:
path: ${{ inputs.ccache_dir }}
key: clio-ccache-${{ runner.os }}-${{ inputs.build_type }}${{ inputs.code_coverage == 'true' && '-code_coverage' || '' }}-${{ inputs.conan_profile }}-develop-${{ steps.git_common_ancestor.outputs.commit }}

View File

@@ -0,0 +1,39 @@
name: Setup conan
description: Setup conan profiles and artifactory on macOS runner
inputs:
conan_files_dir:
description: Directory with conan files
required: true
runs:
using: composite
steps:
- name: Fail on non-macOS
if: runner.os != 'macOS'
shell: bash
run: exit 1
- name: Copy global.conf
shell: bash
run: |
cp "${{ inputs.conan_files_dir }}/global.conf" "${{ env.CONAN_HOME }}/global.conf"
- name: Create apple-clang conan profile
shell: bash
run: |
mkdir -p "${{ env.CONAN_HOME }}/profiles"
cp .github/actions/setup_conan_macos/apple-clang.profile "${{ env.CONAN_HOME }}/profiles/apple-clang"
- name: Create conan profiles for sanitizers
shell: bash
working-directory: ${{ inputs.conan_files_dir }}
run: |
cp ./sanitizer_template.profile "${{ env.CONAN_HOME }}/profiles/apple-clang.asan"
cp ./sanitizer_template.profile "${{ env.CONAN_HOME }}/profiles/apple-clang.tsan"
cp ./sanitizer_template.profile "${{ env.CONAN_HOME }}/profiles/apple-clang.ubsan"
- name: Add artifactory remote
shell: bash
run: |
conan remote add --index 0 ripple http://18.143.149.228:8081/artifactory/api/conan/dev

View File

@@ -4,8 +4,5 @@ build_type=Release
compiler=apple-clang compiler=apple-clang
compiler.cppstd=20 compiler.cppstd=20
compiler.libcxx=libc++ compiler.libcxx=libc++
compiler.version=17.0 compiler.version=16
os=Macos os=Macos
[conf]
grpc/1.50.1:tools.build:cxxflags+=["-Wno-missing-template-arg-list-after-template-kw"]

View File

@@ -14,7 +14,7 @@ updates:
target-branch: develop target-branch: develop
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: .github/actions/build-clio/ directory: .github/actions/build_clio/
schedule: schedule:
interval: weekly interval: weekly
day: monday day: monday
@@ -27,7 +27,7 @@ updates:
target-branch: develop target-branch: develop
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: .github/actions/build-docker-image/ directory: .github/actions/build_docker_image/
schedule: schedule:
interval: weekly interval: weekly
day: monday day: monday
@@ -40,7 +40,7 @@ updates:
target-branch: develop target-branch: develop
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: .github/actions/cmake/ directory: .github/actions/code_coverage/
schedule: schedule:
interval: weekly interval: weekly
day: monday day: monday
@@ -53,7 +53,7 @@ updates:
target-branch: develop target-branch: develop
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: .github/actions/code-coverage/ directory: .github/actions/create_issue/
schedule: schedule:
interval: weekly interval: weekly
day: monday day: monday
@@ -66,7 +66,7 @@ updates:
target-branch: develop target-branch: develop
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: .github/actions/conan/ directory: .github/actions/generate/
schedule: schedule:
interval: weekly interval: weekly
day: monday day: monday
@@ -79,7 +79,7 @@ updates:
target-branch: develop target-branch: develop
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: .github/actions/create-issue/ directory: .github/actions/get_number_of_threads/
schedule: schedule:
interval: weekly interval: weekly
day: monday day: monday
@@ -92,7 +92,7 @@ updates:
target-branch: develop target-branch: develop
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: .github/actions/git-common-ancestor/ directory: .github/actions/git_common_ancestor/
schedule: schedule:
interval: weekly interval: weekly
day: monday day: monday
@@ -105,7 +105,46 @@ updates:
target-branch: develop target-branch: develop
- package-ecosystem: github-actions - package-ecosystem: github-actions
directory: .github/actions/cache-key/ directory: .github/actions/prepare_runner/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
reviewers:
- XRPLF/clio-dev-team
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/restore_cache/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
reviewers:
- XRPLF/clio-dev-team
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/save_cache/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
reviewers:
- XRPLF/clio-dev-team
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/setup_conan_macos/
schedule: schedule:
interval: weekly interval: weekly
day: monday day: monday

View File

@@ -1,48 +0,0 @@
#!/bin/bash
set -ex
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_DIR="$(cd "$CURRENT_DIR/../../../" && pwd)"
CONAN_DIR="${CONAN_HOME:-$HOME/.conan2}"
PROFILES_DIR="$CONAN_DIR/profiles"
# When developers' compilers are updated, these profiles might be different
if [[ -z "$CI" ]]; then
APPLE_CLANG_PROFILE="$CURRENT_DIR/apple-clang-17.profile"
else
APPLE_CLANG_PROFILE="$CURRENT_DIR/apple-clang-17.profile"
fi
GCC_PROFILE="$REPO_DIR/docker/ci/conan/gcc.profile"
CLANG_PROFILE="$REPO_DIR/docker/ci/conan/clang.profile"
SANITIZER_TEMPLATE_FILE="$REPO_DIR/docker/ci/conan/sanitizer_template.profile"
rm -rf "$CONAN_DIR"
conan remote add --index 0 xrplf https://conan.ripplex.io
cp "$REPO_DIR/docker/ci/conan/global.conf" "$CONAN_DIR/global.conf"
create_profile_with_sanitizers() {
profile_name="$1"
profile_source="$2"
cp "$profile_source" "$PROFILES_DIR/$profile_name"
cp "$SANITIZER_TEMPLATE_FILE" "$PROFILES_DIR/$profile_name.asan"
cp "$SANITIZER_TEMPLATE_FILE" "$PROFILES_DIR/$profile_name.tsan"
cp "$SANITIZER_TEMPLATE_FILE" "$PROFILES_DIR/$profile_name.ubsan"
}
mkdir -p "$PROFILES_DIR"
if [[ "$(uname)" == "Darwin" ]]; then
create_profile_with_sanitizers "apple-clang" "$APPLE_CLANG_PROFILE"
echo "include(apple-clang)" >"$PROFILES_DIR/default"
else
create_profile_with_sanitizers "clang" "$CLANG_PROFILE"
create_profile_with_sanitizers "gcc" "$GCC_PROFILE"
echo "include(gcc)" >"$PROFILES_DIR/default"
fi

View File

@@ -1,25 +0,0 @@
#!/usr/bin/env bash
set -ex
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
echo "Using temporary CONAN_HOME: $TEMP_DIR"
# We use a temporary Conan home to avoid polluting the user's existing Conan
# configuration and to not use local cache (which leads to non-reproducible lockfiles).
export CONAN_HOME="$TEMP_DIR"
# Ensure that the xrplf remote is the first to be consulted, so any recipes we
# patched are used. We also add it there to not created huge diff when the
# official Conan Center Index is updated.
conan remote add --force --index 0 xrplf https://conan.ripplex.io
# Delete any existing lockfile.
rm -f conan.lock
# Create a new lockfile that is compatible with macOS.
# It should also work on Linux.
conan lock create . \
--profile:all=.github/scripts/conan/apple-clang-17.profile

45
.github/scripts/execute-tests-under-sanitizer vendored Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
set -o pipefail
# Note: This script is intended to be run from the root of the repository.
#
# This script runs each unit-test separately and generates reports from the currently active sanitizer.
# Output is saved in ./.sanitizer-report in the root of the repository
if [[ -z "$1" ]]; then
cat <<EOF
ERROR
-----------------------------------------------------------------------------
Path to clio_tests should be passed as first argument to the script.
-----------------------------------------------------------------------------
EOF
exit 1
fi
TEST_BINARY=$1
if [[ ! -f "$TEST_BINARY" ]]; then
echo "Test binary not found: $TEST_BINARY"
exit 1
fi
TESTS=$($TEST_BINARY --gtest_list_tests | awk '/^ / {print suite $1} !/^ / {suite=$1}')
OUTPUT_DIR="./.sanitizer-report"
mkdir -p "$OUTPUT_DIR"
for TEST in $TESTS; do
OUTPUT_FILE="$OUTPUT_DIR/${TEST//\//_}"
export TSAN_OPTIONS="log_path=\"$OUTPUT_FILE\" die_after_fork=0"
export ASAN_OPTIONS="log_path=\"$OUTPUT_FILE\""
export UBSAN_OPTIONS="log_path=\"$OUTPUT_FILE\""
export MallocNanoZone='0' # for MacOSX
$TEST_BINARY --gtest_filter="$TEST" > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "'$TEST' failed a sanitizer check."
fi
done

View File

@@ -3,9 +3,7 @@ import itertools
import json import json
LINUX_OS = ["heavy", "heavy-arm64"] LINUX_OS = ["heavy", "heavy-arm64"]
LINUX_CONTAINERS = [ LINUX_CONTAINERS = ['{ "image": "ghcr.io/xrplf/clio-ci:latest" }']
'{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }'
]
LINUX_COMPILERS = ["gcc", "clang"] LINUX_COMPILERS = ["gcc", "clang"]
MACOS_OS = ["macos15"] MACOS_OS = ["macos15"]
@@ -24,6 +22,9 @@ def generate_matrix():
itertools.product(MACOS_OS, MACOS_CONTAINERS, MACOS_COMPILERS), itertools.product(MACOS_OS, MACOS_CONTAINERS, MACOS_COMPILERS),
): ):
for sanitizer_ext, build_type in itertools.product(SANITIZER_EXT, BUILD_TYPES): for sanitizer_ext, build_type in itertools.product(SANITIZER_EXT, BUILD_TYPES):
# libbacktrace doesn't build on arm64 with gcc.tsan
if os == "heavy-arm64" and compiler == "gcc" and sanitizer_ext == ".tsan":
continue
configurations.append( configurations.append(
{ {
"os": os, "os": os,

View File

@@ -20,5 +20,5 @@ for artifact_name in $(ls); do
rm "${artifact_name}/${BINARY_NAME}" rm "${artifact_name}/${BINARY_NAME}"
rm -r "${artifact_name}" rm -r "${artifact_name}"
sha256sum "./${artifact_name}.zip" >"./${artifact_name}.zip.sha256sum" sha256sum "./${artifact_name}.zip" > "./${artifact_name}.zip.sha256sum"
done done

View File

@@ -2,20 +2,20 @@ name: Build
on: on:
push: push:
branches: [release/*, develop] branches: [master, release/*, develop]
pull_request: pull_request:
branches: [release/*, develop] branches: [master, release/*, develop]
paths: paths:
- .github/workflows/build.yml - .github/workflows/build.yml
- .github/workflows/reusable-build-test.yml - .github/workflows/build_and_test.yml
- .github/workflows/reusable-build.yml - .github/workflows/build_impl.yml
- .github/workflows/reusable-test.yml - .github/workflows/test_impl.yml
- .github/workflows/reusable-upload-coverage-report.yml - .github/workflows/upload_coverage_report.yml
- ".github/actions/**" - ".github/actions/**"
- "!.github/actions/build-docker-image/**" - "!.github/actions/build_docker_image/**"
- "!.github/actions/create-issue/**" - "!.github/actions/create_issue/**"
- CMakeLists.txt - CMakeLists.txt
- conanfile.py - conanfile.py
@@ -23,21 +23,15 @@ on:
- "cmake/**" - "cmake/**"
- "src/**" - "src/**"
- "tests/**" - "tests/**"
- "benchmarks/**"
- docs/config-description.md - docs/config-description.md
workflow_dispatch: workflow_dispatch:
concurrency: concurrency:
# Develop branch: Each run gets unique group (using run_number) for parallel execution # Only cancel in-progress jobs or runs for the current workflow - matches against branch & tags
# Other branches: Shared group with cancel-in-progress to stop old runs when new commits are pushed group: ${{ github.workflow }}-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.ref == 'refs/heads/develop' && github.run_number || 'branch' }}
cancel-in-progress: true cancel-in-progress: true
defaults:
run:
shell: bash
jobs: jobs:
build-and-test: build-and-test:
name: Build and Test name: Build and Test
@@ -48,10 +42,7 @@ jobs:
os: [heavy] os: [heavy]
conan_profile: [gcc, clang] conan_profile: [gcc, clang]
build_type: [Release, Debug] build_type: [Release, Debug]
container: container: ['{ "image": "ghcr.io/xrplf/clio-ci:latest" }']
[
'{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }',
]
static: [true] static: [true]
include: include:
@@ -61,14 +52,12 @@ jobs:
container: "" container: ""
static: false static: false
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/build_and_test.yml
with: with:
runs_on: ${{ matrix.os }} runs_on: ${{ matrix.os }}
container: ${{ matrix.container }} container: ${{ matrix.container }}
conan_profile: ${{ matrix.conan_profile }} conan_profile: ${{ matrix.conan_profile }}
build_type: ${{ matrix.build_type }} build_type: ${{ matrix.build_type }}
download_ccache: true
upload_ccache: true
static: ${{ matrix.static }} static: ${{ matrix.static }}
run_unit_tests: true run_unit_tests: true
run_integration_tests: false run_integration_tests: false
@@ -77,14 +66,13 @@ jobs:
code_coverage: code_coverage:
name: Run Code Coverage name: Run Code Coverage
uses: ./.github/workflows/reusable-build.yml uses: ./.github/workflows/build_impl.yml
with: with:
runs_on: heavy runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
conan_profile: gcc conan_profile: gcc
build_type: Debug build_type: Debug
download_ccache: true disable_cache: false
upload_ccache: true
code_coverage: true code_coverage: true
static: true static: true
upload_clio_server: false upload_clio_server: false
@@ -98,16 +86,17 @@ jobs:
needs: build-and-test needs: build-and-test
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696 image: ghcr.io/xrplf/clio-ci:latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 - uses: actions/download-artifact@v4
with: with:
name: clio_server_Linux_Release_gcc name: clio_server_Linux_Release_gcc
- name: Compare Config Description - name: Compare Config Description
shell: bash
run: | run: |
repoConfigFile=docs/config-description.md repoConfigFile=docs/config-description.md
configDescriptionFile=config_description_new.md configDescriptionFile=config_description_new.md

View File

@@ -23,14 +23,8 @@ on:
required: true required: true
type: string type: string
download_ccache: disable_cache:
description: Whether to download ccache from the cache description: Whether ccache should be disabled
required: false
type: boolean
default: true
upload_ccache:
description: Whether to upload ccache to the cache
required: false required: false
type: boolean type: boolean
default: false default: false
@@ -63,39 +57,24 @@ on:
type: string type: string
default: all default: all
package:
description: Whether to generate Debian package
required: false
type: boolean
default: false
version:
description: Version of the clio_server binary
required: false
type: string
default: ""
jobs: jobs:
build: build:
uses: ./.github/workflows/reusable-build.yml uses: ./.github/workflows/build_impl.yml
with: with:
runs_on: ${{ inputs.runs_on }} runs_on: ${{ inputs.runs_on }}
container: ${{ inputs.container }} container: ${{ inputs.container }}
conan_profile: ${{ inputs.conan_profile }} conan_profile: ${{ inputs.conan_profile }}
build_type: ${{ inputs.build_type }} build_type: ${{ inputs.build_type }}
download_ccache: ${{ inputs.download_ccache }} disable_cache: ${{ inputs.disable_cache }}
upload_ccache: ${{ inputs.upload_ccache }}
code_coverage: false code_coverage: false
static: ${{ inputs.static }} static: ${{ inputs.static }}
upload_clio_server: ${{ inputs.upload_clio_server }} upload_clio_server: ${{ inputs.upload_clio_server }}
targets: ${{ inputs.targets }} targets: ${{ inputs.targets }}
analyze_build_time: false analyze_build_time: false
package: ${{ inputs.package }}
version: ${{ inputs.version }}
test: test:
needs: build needs: build
uses: ./.github/workflows/reusable-test.yml uses: ./.github/workflows/test_impl.yml
with: with:
runs_on: ${{ inputs.runs_on }} runs_on: ${{ inputs.runs_on }}
container: ${{ inputs.container }} container: ${{ inputs.container }}

View File

@@ -38,37 +38,32 @@ on:
description: Whether to strip clio binary description: Whether to strip clio binary
default: true default: true
defaults:
run:
shell: bash
jobs: jobs:
build_and_publish_image: build_and_publish_image:
name: Build and publish image name: Build and publish image
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
- name: Download Clio binary from artifact - name: Download Clio binary from artifact
if: ${{ inputs.artifact_name != null }} if: ${{ inputs.artifact_name != null }}
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 uses: actions/download-artifact@v4
with: with:
name: ${{ inputs.artifact_name }} name: ${{ inputs.artifact_name }}
path: ./docker/clio/artifact/ path: ./docker/clio/artifact/
- name: Download Clio binary from url - name: Download Clio binary from url
if: ${{ inputs.clio_server_binary_url != null }} if: ${{ inputs.clio_server_binary_url != null }}
env: shell: bash
BINARY_URL: ${{ inputs.clio_server_binary_url }}
BINARY_SHA256: ${{ inputs.binary_sha256 }}
run: | run: |
wget "${BINARY_URL}" -P ./docker/clio/artifact/ wget "${{inputs.clio_server_binary_url}}" -P ./docker/clio/artifact/
if [ "$(sha256sum ./docker/clio/clio_server | awk '{print $1}')" != "${BINARY_SHA256}" ]; then if [ "$(sha256sum ./docker/clio/clio_server | awk '{print $1}')" != "${{inputs.binary_sha256}}" ]; then
echo "Binary sha256 sum doesn't match" echo "Binary sha256 sum doesn't match"
exit 1 exit 1
fi fi
- name: Unpack binary - name: Unpack binary
shell: bash
run: | run: |
sudo apt update && sudo apt install -y tar unzip sudo apt update && sudo apt install -y tar unzip
cd docker/clio/artifact cd docker/clio/artifact
@@ -78,33 +73,28 @@ jobs:
elif [[ $artifact == *.tar.gz ]]; then elif [[ $artifact == *.tar.gz ]]; then
tar -xvf $artifact tar -xvf $artifact
fi fi
chmod +x ./clio_server mv clio_server ../
mv ./clio_server ../
cd ../ cd ../
rm -rf ./artifact rm -rf ./artifact
- name: Strip binary - name: Strip binary
if: ${{ inputs.strip_binary }} if: ${{ inputs.strip_binary }}
shell: bash
run: strip ./docker/clio/clio_server run: strip ./docker/clio/clio_server
- name: Set GHCR_REPO
id: set-ghcr-repo
run: |
echo "GHCR_REPO=$(echo ghcr.io/${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_OUTPUT}
- name: Build Docker image - name: Build Docker image
uses: ./.github/actions/build-docker-image uses: ./.github/actions/build_docker_image
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }} DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }} DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with: with:
images: | images: |
ghcr.io/${{ steps.set-ghcr-repo.outputs.GHCR_REPO }}/clio ghcr.io/xrplf/clio
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio' || '' }} rippleci/clio
push_image: ${{ inputs.publish_image }} push_image: ${{ inputs.publish_image }}
directory: docker/clio directory: docker/clio
tags: ${{ inputs.tags }} tags: ${{ inputs.tags }}
platforms: linux/amd64 platforms: linux/amd64
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio' || '' }} dockerhub_repo: rippleci/clio
dockerhub_description: Clio is an XRP Ledger API server. dockerhub_description: Clio is an XRP Ledger API server.

View File

@@ -23,17 +23,10 @@ on:
required: true required: true
type: string type: string
download_ccache: disable_cache:
description: Whether to download ccache from the cache description: Whether ccache should be disabled
required: false required: false
type: boolean type: boolean
default: true
upload_ccache:
description: Whether to upload ccache to the cache
required: false
type: boolean
default: false
code_coverage: code_coverage:
description: Whether to enable code coverage description: Whether to enable code coverage
@@ -60,25 +53,10 @@ on:
required: true required: true
type: boolean type: boolean
package:
description: Whether to generate Debian package
required: false
type: boolean
version:
description: Version of the clio_server binary
required: false
type: string
default: ""
secrets: secrets:
CODECOV_TOKEN: CODECOV_TOKEN:
required: false required: false
defaults:
run:
shell: bash
jobs: jobs:
build: build:
name: Build name: Build
@@ -86,59 +64,46 @@ jobs:
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }} container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
steps: steps:
- name: Cleanup workspace - name: Clean workdir
if: ${{ runner.os == 'macOS' }} if: ${{ runner.os == 'macOS' }}
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4 uses: kuznetsss/workspace-cleanup@80b9863b45562c148927c3d53621ef354e5ae7ce # v1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d uses: ./.github/actions/prepare_runner
with: with:
enable_ccache: ${{ inputs.download_ccache }} disable_ccache: ${{ inputs.disable_cache }}
- name: Setup conan on macOS - name: Setup conan
if: ${{ runner.os == 'macOS' }} if: runner.os == 'macOS'
run: ./.github/scripts/conan/init.sh uses: ./.github/actions/setup_conan_macos
with:
conan_files_dir: docker/ci/conan/
- name: Generate cache key - name: Restore cache
uses: ./.github/actions/cache-key if: ${{ !inputs.disable_cache }}
id: cache_key uses: ./.github/actions/restore_cache
id: restore_cache
with: with:
conan_profile: ${{ inputs.conan_profile }} conan_profile: ${{ inputs.conan_profile }}
ccache_dir: ${{ env.CCACHE_DIR }}
build_type: ${{ inputs.build_type }} build_type: ${{ inputs.build_type }}
code_coverage: ${{ inputs.code_coverage }} code_coverage: ${{ inputs.code_coverage }}
- name: Restore ccache cache - name: Run conan and cmake
if: ${{ inputs.download_ccache && github.ref != 'refs/heads/develop' }} uses: ./.github/actions/generate
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ steps.cache_key.outputs.key }}
restore-keys: |
${{ steps.cache_key.outputs.restore_keys }}
- name: Run conan
uses: ./.github/actions/conan
with:
conan_profile: ${{ inputs.conan_profile }}
build_type: ${{ inputs.build_type }}
- name: Run CMake
uses: ./.github/actions/cmake
with: with:
conan_profile: ${{ inputs.conan_profile }} conan_profile: ${{ inputs.conan_profile }}
build_type: ${{ inputs.build_type }} build_type: ${{ inputs.build_type }}
code_coverage: ${{ inputs.code_coverage }} code_coverage: ${{ inputs.code_coverage }}
static: ${{ inputs.static }} static: ${{ inputs.static }}
time_trace: ${{ inputs.analyze_build_time }} time_trace: ${{ inputs.analyze_build_time }}
package: ${{ inputs.package }}
version: ${{ inputs.version }}
- name: Build Clio - name: Build Clio
uses: ./.github/actions/build-clio uses: ./.github/actions/build_clio
with: with:
targets: ${{ inputs.targets }} targets: ${{ inputs.targets }}
@@ -148,26 +113,24 @@ jobs:
ClangBuildAnalyzer --all build/ build_time_report.bin ClangBuildAnalyzer --all build/ build_time_report.bin
ClangBuildAnalyzer --analyze build_time_report.bin > build_time_report.txt ClangBuildAnalyzer --analyze build_time_report.bin > build_time_report.txt
cat build_time_report.txt cat build_time_report.txt
shell: bash
- name: Upload build time analyze report - name: Upload build time analyze report
if: ${{ inputs.analyze_build_time }} if: ${{ inputs.analyze_build_time }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@v4
with: with:
name: build_time_report_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: build_time_report_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
path: build_time_report.txt path: build_time_report.txt
- name: Show ccache's statistics and zero it - name: Show ccache's statistics
if: ${{ inputs.download_ccache }} if: ${{ !inputs.disable_cache }}
shell: bash
id: ccache_stats
run: | run: |
ccache --show-stats -vv ccache -s > /tmp/ccache.stats
ccache --zero-stats miss_rate=$(cat /tmp/ccache.stats | grep 'Misses' | head -n1 | sed 's/.*(\(.*\)%).*/\1/')
echo "miss_rate=${miss_rate}" >> $GITHUB_OUTPUT
- name: Save ccache cache cat /tmp/ccache.stats
if: ${{ inputs.upload_ccache && github.ref == 'refs/heads/develop' }}
uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ${{ env.CCACHE_DIR }}
key: ${{ steps.cache_key.outputs.key }}
- name: Strip unit_tests - name: Strip unit_tests
if: ${{ !endsWith(inputs.conan_profile, 'san') && !inputs.code_coverage && !inputs.analyze_build_time }} if: ${{ !endsWith(inputs.conan_profile, 'san') && !inputs.code_coverage && !inputs.analyze_build_time }}
@@ -178,60 +141,48 @@ jobs:
run: strip build/clio_integration_tests run: strip build/clio_integration_tests
- name: Upload clio_server - name: Upload clio_server
if: ${{ inputs.upload_clio_server && !inputs.code_coverage && !inputs.analyze_build_time }} if: inputs.upload_clio_server && !inputs.code_coverage && !inputs.analyze_build_time
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@v4
with: with:
name: clio_server_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: clio_server_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
path: build/clio_server path: build/clio_server
- name: Upload clio_tests - name: Upload clio_tests
if: ${{ !inputs.code_coverage && !inputs.analyze_build_time && !inputs.package }} if: ${{ !inputs.code_coverage && !inputs.analyze_build_time }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@v4
with: with:
name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
path: build/clio_tests path: build/clio_tests
- name: Upload clio_integration_tests - name: Upload clio_integration_tests
if: ${{ !inputs.code_coverage && !inputs.analyze_build_time && !inputs.package }} if: ${{ !inputs.code_coverage && !inputs.analyze_build_time }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@v4
with: with:
name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
path: build/clio_integration_tests path: build/clio_integration_tests
- name: Upload Clio Linux package - name: Save cache
if: ${{ inputs.package }} if: ${{ !inputs.disable_cache && github.ref == 'refs/heads/develop' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: ./.github/actions/save_cache
with: with:
name: clio_deb_package_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} conan_profile: ${{ inputs.conan_profile }}
path: build/*.deb ccache_dir: ${{ env.CCACHE_DIR }}
build_type: ${{ inputs.build_type }}
code_coverage: ${{ inputs.code_coverage }}
ccache_cache_hit: ${{ steps.restore_cache.outputs.ccache_cache_hit }}
ccache_cache_miss_rate: ${{ steps.ccache_stats.outputs.miss_rate }}
# This is run as part of the build job, because it requires the following: # This is run as part of the build job, because it requires the following:
# - source code # - source code
# - generated source code (Build.cpp)
# - conan packages # - conan packages
# - .gcno files in build directory # - .gcno files in build directory
# #
# It's all available in the build job, but not in the test job # It's all available in the build job, but not in the test job
- name: Run code coverage - name: Run code coverage
if: ${{ inputs.code_coverage }} if: ${{ inputs.code_coverage }}
uses: ./.github/actions/code-coverage uses: ./.github/actions/code_coverage
- name: Verify version is expected
if: ${{ inputs.version != '' }}
env:
INPUT_VERSION: ${{ inputs.version }}
BUILD_TYPE: ${{ inputs.build_type }}
run: |
set -e
EXPECTED_VERSION="clio-${INPUT_VERSION}"
if [[ "${BUILD_TYPE}" == "Debug" ]]; then
EXPECTED_VERSION="${EXPECTED_VERSION}+DEBUG"
fi
actual_version=$(./build/clio_server --version | head -n 1)
if [[ "${actual_version}" != "${EXPECTED_VERSION}" ]]; then
echo "Expected version '${EXPECTED_VERSION}', but got '${actual_version}'"
exit 1
fi
# `codecov/codecov-action` will rerun `gcov` if it's available and build directory is present # `codecov/codecov-action` will rerun `gcov` if it's available and build directory is present
# To prevent this from happening, we run this action in a separate workflow # To prevent this from happening, we run this action in a separate workflow
@@ -241,6 +192,6 @@ jobs:
if: ${{ inputs.code_coverage }} if: ${{ inputs.code_coverage }}
name: Codecov name: Codecov
needs: build needs: build
uses: ./.github/workflows/reusable-upload-coverage-report.yml uses: ./.github/workflows/upload_coverage_report.yml
secrets: secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -12,54 +12,47 @@ concurrency:
env: env:
CONAN_PROFILE: gcc CONAN_PROFILE: gcc
defaults:
run:
shell: bash
jobs: jobs:
build: build:
name: Build Clio / `libXRPL ${{ github.event.client_payload.version }}` name: Build Clio / `libXRPL ${{ github.event.client_payload.version }}`
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696 image: ghcr.io/xrplf/clio-ci:latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d
with:
enable_ccache: false
- name: Update libXRPL version requirement - name: Update libXRPL version requirement
shell: bash
run: | run: |
sed -i.bak -E "s|'xrpl/[a-zA-Z0-9\\.\\-]+'|'xrpl/${{ github.event.client_payload.conan_ref }}'|g" conanfile.py sed -i.bak -E "s|'xrpl/[a-zA-Z0-9\\.\\-]+'|'xrpl/${{ github.event.client_payload.version }}'|g" conanfile.py
rm -f conanfile.py.bak rm -f conanfile.py.bak
- name: Update conan lockfile - name: Update conan lockfile
shell: bash
run: | run: |
conan lock create . --profile:all ${{ env.CONAN_PROFILE }} conan lock create . -o '&:tests=True' -o '&:benchmark=True'
- name: Run conan - name: Prepare runner
uses: ./.github/actions/conan uses: ./.github/actions/prepare_runner
with: with:
conan_profile: ${{ env.CONAN_PROFILE }} disable_ccache: true
- name: Run CMake - name: Run conan and cmake
uses: ./.github/actions/cmake uses: ./.github/actions/generate
with: with:
conan_profile: ${{ env.CONAN_PROFILE }} conan_profile: ${{ env.CONAN_PROFILE }}
- name: Build Clio - name: Build Clio
uses: ./.github/actions/build-clio uses: ./.github/actions/build_clio
- name: Strip tests - name: Strip tests
run: strip build/clio_tests run: strip build/clio_tests
- name: Upload clio_tests - name: Upload clio_tests
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@v4
with: with:
name: clio_tests_check_libxrpl name: clio_tests_check_libxrpl
path: build/clio_tests path: build/clio_tests
@@ -69,10 +62,10 @@ jobs:
needs: build needs: build
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696 image: ghcr.io/xrplf/clio-ci:latest
steps: steps:
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 - uses: actions/download-artifact@v4
with: with:
name: clio_tests_check_libxrpl name: clio_tests_check_libxrpl
@@ -92,17 +85,16 @@ jobs:
issues: write issues: write
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
- name: Create an issue - name: Create an issue
uses: ./.github/actions/create-issue uses: ./.github/actions/create_issue
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
with: with:
labels: "compatibility,bug" labels: "compatibility,bug"
title: "Proposed libXRPL check failed" title: "Proposed libXRPL check failed"
body: > body: >
Clio build or tests failed against `libXRPL ${{ github.event.client_payload.conan_ref }}`. Clio build or tests failed against `libXRPL ${{ github.event.client_payload.version }}`.
PR: ${{ github.event.client_payload.pr_url }} Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
Workflow run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/

View File

@@ -5,26 +5,13 @@ on:
types: [opened, edited, reopened, synchronize] types: [opened, edited, reopened, synchronize]
branches: [develop] branches: [develop]
defaults:
run:
shell: bash
jobs: jobs:
check_title: check_title:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: ytanikin/pr-conventional-commits@fda730cb152c05a849d6d84325e50c6182d9d1e9 # 1.5.1 - uses: ytanikin/pr-conventional-commits@8267db1bacc237419f9ed0228bb9d94e94271a1d # v1.4.1
with: with:
task_types: '["build","feat","fix","docs","test","ci","style","refactor","perf","chore"]' task_types: '["build","feat","fix","docs","test","ci","style","refactor","perf","chore"]'
add_label: false add_label: false
custom_labels: '{"build":"build", "feat":"enhancement", "fix":"bug", "docs":"documentation", "test":"testability", "ci":"ci", "style":"refactoring", "refactor":"refactoring", "perf":"performance", "chore":"tooling"}' custom_labels: '{"build":"build", "feat":"enhancement", "fix":"bug", "docs":"documentation", "test":"testability", "ci":"ci", "style":"refactoring", "refactor":"refactoring", "perf":"performance", "chore":"tooling"}'
- name: Check if message starts with upper-case letter
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
if [[ ! "${PR_TITLE}" =~ ^[a-z]+:\ [\[A-Z] ]]; then
echo "Error: PR title must start with an upper-case letter."
exit 1
fi

View File

@@ -1,8 +1,6 @@
name: Clang-tidy check name: Clang-tidy check
on: on:
push:
branches: [develop]
schedule: schedule:
- cron: "0 9 * * 1-5" - cron: "0 9 * * 1-5"
workflow_dispatch: workflow_dispatch:
@@ -20,18 +18,12 @@ concurrency:
env: env:
CONAN_PROFILE: clang CONAN_PROFILE: clang
LLVM_TOOLS_VERSION: 20
defaults:
run:
shell: bash
jobs: jobs:
clang_tidy: clang_tidy:
if: github.event_name != 'push' || contains(github.event.head_commit.message, 'clang-tidy auto fixes')
runs-on: heavy runs-on: heavy
container: container:
image: ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696 image: ghcr.io/xrplf/clio-ci:latest
permissions: permissions:
contents: write contents: write
@@ -39,55 +31,57 @@ jobs:
pull-requests: write pull-requests: write
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d uses: ./.github/actions/prepare_runner
with: with:
enable_ccache: false disable_ccache: true
- name: Run conan - name: Restore cache
uses: ./.github/actions/conan uses: ./.github/actions/restore_cache
id: restore_cache
with:
conan_profile: ${{ env.CONAN_PROFILE }}
ccache_dir: ${{ env.CCACHE_DIR }}
- name: Run conan and cmake
uses: ./.github/actions/generate
with: with:
conan_profile: ${{ env.CONAN_PROFILE }} conan_profile: ${{ env.CONAN_PROFILE }}
- name: Run CMake - name: Get number of threads
uses: ./.github/actions/cmake uses: ./.github/actions/get_number_of_threads
with: id: number_of_threads
conan_profile: ${{ env.CONAN_PROFILE }}
- name: Get number of processors - name: Run clang-tidy
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf
id: nproc
- name: Run clang-tidy (several times)
continue-on-error: true continue-on-error: true
id: clang_tidy shell: bash
id: run_clang_tidy
run: | run: |
# We run clang-tidy several times, because some fixes may enable new fixes in subsequent runs. run-clang-tidy-19 -p build -j "${{ steps.number_of_threads.outputs.threads_number }}" -fix -quiet 1>output.txt
CLANG_TIDY_COMMAND="run-clang-tidy-${{ env.LLVM_TOOLS_VERSION }} -p build -j ${{ steps.nproc.outputs.nproc }} -fix -quiet"
${CLANG_TIDY_COMMAND} ||
${CLANG_TIDY_COMMAND} ||
${CLANG_TIDY_COMMAND}
- name: Check for changes
id: files_changed
continue-on-error: true
run: |
git diff --exit-code
- name: Fix local includes and clang-format style - name: Fix local includes and clang-format style
if: ${{ steps.files_changed.outcome != 'success' }} if: ${{ steps.run_clang_tidy.outcome != 'success' }}
shell: bash
run: | run: |
pre-commit run --all-files fix-local-includes || true pre-commit run --all-files fix-local-includes || true
pre-commit run --all-files clang-format || true pre-commit run --all-files clang-format || true
- name: Print issues found
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
shell: bash
run: |
sed -i '/error\||/!d' ./output.txt
cat output.txt
rm output.txt
- name: Create an issue - name: Create an issue
if: ${{ (steps.clang_tidy.outcome != 'success' || steps.files_changed.outcome != 'success') && github.event_name != 'pull_request' }} if: ${{ steps.run_clang_tidy.outcome != 'success' && github.event_name != 'pull_request' }}
id: create_issue id: create_issue
uses: ./.github/actions/create-issue uses: ./.github/actions/create_issue
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
with: with:
@@ -98,7 +92,7 @@ jobs:
List of the issues found: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/ List of the issues found: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
- uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 - uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0
if: ${{ steps.files_changed.outcome != 'success' && github.event_name != 'pull_request' }} if: ${{ steps.run_clang_tidy.outcome != 'success' && github.event_name != 'pull_request' }}
with: with:
gpg_private_key: ${{ secrets.ACTIONS_GPG_PRIVATE_KEY }} gpg_private_key: ${{ secrets.ACTIONS_GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.ACTIONS_GPG_PASSPHRASE }} passphrase: ${{ secrets.ACTIONS_GPG_PASSPHRASE }}
@@ -106,8 +100,8 @@ jobs:
git_commit_gpgsign: true git_commit_gpgsign: true
- name: Create PR with fixes - name: Create PR with fixes
if: ${{ steps.files_changed.outcome != 'success' && github.event_name != 'pull_request' }} if: ${{ steps.run_clang_tidy.outcome != 'success' && github.event_name != 'pull_request' }}
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
env: env:
GH_REPO: ${{ github.repository }} GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
@@ -122,5 +116,6 @@ jobs:
reviewers: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru" reviewers: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru"
- name: Fail the job - name: Fail the job
if: ${{ steps.clang_tidy.outcome != 'success' || steps.files_changed.outcome != 'success' }} if: ${{ steps.run_clang_tidy.outcome != 'success' }}
shell: bash
run: exit 1 run: exit 1

View File

@@ -0,0 +1,30 @@
name: Restart clang-tidy workflow
on:
push:
branches: [develop]
workflow_dispatch:
jobs:
restart_clang_tidy:
runs-on: ubuntu-latest
permissions:
actions: write
steps:
- uses: actions/checkout@v4
- name: Check last commit matches clang-tidy auto fixes
id: check
shell: bash
run: |
passed=$(if [[ "$(git log -1 --pretty=format:%s | grep 'style: clang-tidy auto fixes')" ]]; then echo 'true' ; else echo 'false' ; fi)
echo "passed=\"$passed\"" >> $GITHUB_OUTPUT
- name: Run clang-tidy workflow
if: ${{ contains(steps.check.outputs.passed, 'true') }}
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
run: gh workflow run clang-tidy.yml

View File

@@ -10,27 +10,18 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
defaults:
run:
shell: bash
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:
image: ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696 image: ghcr.io/xrplf/clio-ci:latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@v4
with: with:
lfs: true lfs: true
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d
with:
enable_ccache: false
- name: Create build directory - name: Create build directory
run: mkdir build_docs run: mkdir build_docs
@@ -43,10 +34,10 @@ jobs:
run: cmake --build . --target docs run: cmake --build . --target docs
- name: Setup Pages - name: Setup Pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0 uses: actions/configure-pages@v5
- name: Upload artifact - name: Upload artifact
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0 uses: actions/upload-pages-artifact@v3
with: with:
path: build_docs/html path: build_docs/html
name: docs-develop name: docs-develop
@@ -66,6 +57,6 @@ jobs:
steps: steps:
- name: Deploy to GitHub Pages - name: Deploy to GitHub Pages
id: deployment id: deployment
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5 uses: actions/deploy-pages@v4
with: with:
artifact_name: docs-develop artifact_name: docs-develop

View File

@@ -8,14 +8,14 @@ on:
paths: paths:
- .github/workflows/nightly.yml - .github/workflows/nightly.yml
- .github/workflows/reusable-release.yml - .github/workflows/release_impl.yml
- .github/workflows/reusable-build-test.yml - .github/workflows/build_and_test.yml
- .github/workflows/reusable-build.yml - .github/workflows/build_impl.yml
- .github/workflows/reusable-test.yml - .github/workflows/test_impl.yml
- .github/workflows/build-clio-docker-image.yml - .github/workflows/build_clio_docker_image.yml
- ".github/actions/**" - ".github/actions/**"
- "!.github/actions/code-coverage/**" - "!.github/actions/code_coverage/**"
- .github/scripts/prepare-release-artifacts.sh - .github/scripts/prepare-release-artifacts.sh
concurrency: concurrency:
@@ -23,25 +23,9 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
defaults:
run:
shell: bash
jobs: jobs:
get_date:
name: Get Date
runs-on: ubuntu-latest
outputs:
date: ${{ steps.get_date.outputs.date }}
steps:
- name: Get current date
id: get_date
run: |
echo "date=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
build-and-test: build-and-test:
name: Build and Test name: Build and Test
needs: get_date
strategy: strategy:
fail-fast: false fail-fast: false
@@ -55,19 +39,19 @@ jobs:
conan_profile: gcc conan_profile: gcc
build_type: Release build_type: Release
static: true static: true
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
- os: heavy - os: heavy
conan_profile: gcc conan_profile: gcc
build_type: Debug build_type: Debug
static: true static: true
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
- os: heavy - os: heavy
conan_profile: gcc.ubsan conan_profile: gcc.ubsan
build_type: Release build_type: Release
static: false static: false
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/build_and_test.yml
with: with:
runs_on: ${{ matrix.os }} runs_on: ${{ matrix.os }}
container: ${{ matrix.container }} container: ${{ matrix.container }}
@@ -77,33 +61,10 @@ jobs:
run_unit_tests: true run_unit_tests: true
run_integration_tests: true run_integration_tests: true
upload_clio_server: true upload_clio_server: true
download_ccache: false disable_cache: true
upload_ccache: false
version: nightly-${{ needs.get_date.outputs.date }}
package:
name: Build debian package
needs: get_date
uses: ./.github/workflows/reusable-build.yml
with:
runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }'
conan_profile: gcc
build_type: Release
download_ccache: false
upload_ccache: false
code_coverage: false
static: true
upload_clio_server: false
package: true
version: nightly-${{ needs.get_date.outputs.date }}
targets: package
analyze_build_time: false
analyze_build_time: analyze_build_time:
name: Analyze Build Time name: Analyze Build Time
needs: get_date
strategy: strategy:
fail-fast: false fail-fast: false
@@ -111,44 +72,43 @@ jobs:
include: include:
- os: heavy - os: heavy
conan_profile: clang conan_profile: clang
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
static: true static: true
- os: macos15 - os: macos15
conan_profile: apple-clang conan_profile: apple-clang
container: "" container: ""
static: false static: false
uses: ./.github/workflows/reusable-build.yml uses: ./.github/workflows/build_impl.yml
with: with:
runs_on: ${{ matrix.os }} runs_on: ${{ matrix.os }}
container: ${{ matrix.container }} container: ${{ matrix.container }}
conan_profile: ${{ matrix.conan_profile }} conan_profile: ${{ matrix.conan_profile }}
build_type: Release build_type: Release
download_ccache: false disable_cache: true
upload_ccache: false
code_coverage: false code_coverage: false
static: ${{ matrix.static }} static: ${{ matrix.static }}
upload_clio_server: false upload_clio_server: false
targets: all targets: all
analyze_build_time: true analyze_build_time: true
version: nightly-${{ needs.get_date.outputs.date }}
nightly_release: nightly_release:
needs: [build-and-test, package, get_date] needs: build-and-test
uses: ./.github/workflows/reusable-release.yml uses: ./.github/workflows/release_impl.yml
with: with:
delete_pattern: "nightly-*" overwrite_release: true
prerelease: true title: "Clio development (nightly) build"
title: "Clio development build (nightly-${{ needs.get_date.outputs.date }})" version: nightly
version: nightly-${{ needs.get_date.outputs.date }}
header: > header: >
# Release notes
> **Note:** Please remember that this is a development release and it is not recommended for production use. > **Note:** Please remember that this is a development release and it is not recommended for production use.
Changelog (including previous releases): <https://github.com/XRPLF/clio/commits/nightly-${{ needs.get_date.outputs.date }}> Changelog (including previous releases): <https://github.com/XRPLF/clio/commits/nightly>
generate_changelog: false generate_changelog: false
draft: false draft: false
build_and_publish_docker_image: build_and_publish_docker_image:
uses: ./.github/workflows/build-clio-docker-image.yml uses: ./.github/workflows/build_clio_docker_image.yml
needs: build-and-test needs: build-and-test
secrets: inherit secrets: inherit
with: with:
@@ -169,10 +129,10 @@ jobs:
issues: write issues: write
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
- name: Create an issue - name: Create an issue
uses: ./.github/actions/create-issue uses: ./.github/actions/create_issue
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
with: with:

View File

@@ -1,22 +1,39 @@
name: Pre-commit auto-update name: Pre-commit auto-update
on: on:
schedule:
# every first day of the month # every first day of the month
schedule:
- cron: "0 0 1 * *" - cron: "0 0 1 * *"
pull_request: # on demand
branches: [release/*, develop]
paths:
- ".pre-commit-config.yaml"
workflow_dispatch: workflow_dispatch:
jobs: jobs:
auto-update: auto-update:
uses: XRPLF/actions/.github/workflows/pre-commit-autoupdate.yml@8b19d3462e52cd8ea4d76b4c8d0f7533e7469c15 runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: with:
sign_commit: true python-version: 3.x
committer: "Clio CI <skuznetsov@ripple.com>"
- run: pip install pre-commit
- run: pre-commit autoupdate --freeze
- run: pre-commit run --all-files || true
- uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
if: always()
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
with:
branch: update/pre-commit-hooks
title: "style: Update pre-commit hooks"
commit-message: "style: Update pre-commit hooks"
body: Update versions of pre-commit hooks to latest version.
reviewers: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru" reviewers: "godexsoft,kuznetsss,PeterChen13579,mathbunnyru"
secrets:
GPG_PRIVATE_KEY: ${{ secrets.ACTIONS_GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.ACTIONS_GPG_PASSPHRASE }}

View File

@@ -3,12 +3,26 @@ name: Run pre-commit hooks
on: on:
pull_request: pull_request:
push: push:
branches: [develop] branches:
- develop
workflow_dispatch: workflow_dispatch:
jobs: jobs:
run-hooks: run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@320be44621ca2a080f05aeb15817c44b84518108 runs-on: heavy
container:
image: ghcr.io/xrplf/clio-ci:latest
steps:
- name: Checkout Repo ⚡️
uses: actions/checkout@v4
with: with:
runs_on: heavy fetch-depth: 0
container: '{ "image": "ghcr.io/xrplf/clio-pre-commit:14342e087ceb8b593027198bf9ef06a43833c696" }'
- name: Prepare runner
uses: ./.github/actions/prepare_runner
with:
disable_ccache: true
- name: Run pre-commit ✅
run: pre-commit run --all-files

View File

@@ -29,9 +29,9 @@ jobs:
conan_profile: gcc conan_profile: gcc
build_type: Release build_type: Release
static: true static: true
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/build_and_test.yml
with: with:
runs_on: ${{ matrix.os }} runs_on: ${{ matrix.os }}
container: ${{ matrix.container }} container: ${{ matrix.container }}
@@ -41,38 +41,16 @@ jobs:
run_unit_tests: true run_unit_tests: true
run_integration_tests: true run_integration_tests: true
upload_clio_server: true upload_clio_server: true
download_ccache: false disable_cache: true
upload_ccache: false
version: ${{ github.event_name == 'push' && github.ref_name || '' }}
package:
name: Build debian package
uses: ./.github/workflows/reusable-build.yml
with:
runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }'
conan_profile: gcc
build_type: Release
download_ccache: false
upload_ccache: false
code_coverage: false
static: true
upload_clio_server: false
package: true
version: ${{ github.event_name == 'push' && github.ref_name || '' }}
targets: package
analyze_build_time: false
release: release:
needs: [build-and-test, package] needs: build-and-test
uses: ./.github/workflows/reusable-release.yml uses: ./.github/workflows/release_impl.yml
with: with:
delete_pattern: "" overwrite_release: false
prerelease: ${{ contains(github.ref_name, '-') }} title: "${{ github.ref_name}}"
title: "${{ github.ref_name }}"
version: "${{ github.ref_name }}" version: "${{ github.ref_name }}"
header: > header: >
${{ contains(github.ref_name, '-') && '> **Note:** Please remember that this is a release candidate and it is not recommended for production use.' || '' }} # Introducing Clio version ${{ github.ref_name }}
generate_changelog: ${{ !contains(github.ref_name, '-') }} generate_changelog: true
draft: ${{ !contains(github.ref_name, '-') }} draft: true

117
.github/workflows/release_impl.yml vendored Normal file
View File

@@ -0,0 +1,117 @@
name: Make release
on:
workflow_call:
inputs:
overwrite_release:
description: "Overwrite the current release and tag"
required: true
type: boolean
title:
description: "Release title"
required: true
type: string
version:
description: "Release version"
required: true
type: string
header:
description: "Release notes header"
required: true
type: string
generate_changelog:
description: "Generate changelog"
required: false
type: boolean
draft:
description: "Create a draft release"
required: false
type: boolean
jobs:
release:
runs-on: heavy
container:
image: ghcr.io/xrplf/clio-ci:latest
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Prepare runner
uses: ./.github/actions/prepare_runner
with:
disable_ccache: true
- uses: actions/download-artifact@v4
with:
path: release_artifacts
pattern: clio_server_*
- name: Create release notes
shell: bash
run: |
printf '%s\n' "${{ inputs.header }}" > "${RUNNER_TEMP}/release_notes.md"
- name: Generate changelog
shell: bash
if: ${{ inputs.generate_changelog }}
run: |
LAST_TAG=$(gh release view --json tagName -q .tagName)
LAST_TAG_COMMIT=$(git rev-parse $LAST_TAG)
BASE_COMMIT=$(git merge-base HEAD $LAST_TAG_COMMIT)
git-cliff "${BASE_COMMIT}..HEAD" --ignore-tags "nightly|-b"
cat CHANGELOG.md >> "${RUNNER_TEMP}/release_notes.md"
- name: Prepare release artifacts
shell: bash
run: .github/scripts/prepare-release-artifacts.sh release_artifacts
- name: Append sha256 checksums
shell: bash
working-directory: release_artifacts
run: |
{
echo '## SHA256 checksums'
echo
echo '```'
cat *.sha256sum
echo '```'
} >> "${RUNNER_TEMP}/release_notes.md"
- name: Upload release notes
uses: actions/upload-artifact@v4
with:
name: release_notes_${{ inputs.version }}
path: "${RUNNER_TEMP}/release_notes.md"
- name: Remove current release and tag
if: ${{ github.event_name != 'pull_request' && inputs.overwrite_release }}
shell: bash
run: |
gh release delete ${{ inputs.version }} --yes || true
git push origin :${{ inputs.version }} || true
- name: Publish release
if: ${{ github.event_name != 'pull_request' }}
shell: bash
run: |
gh release create ${{ inputs.version }} \
${{ inputs.overwrite_release && '--prerelease' || '' }} \
--title "${{ inputs.title }}" \
--target $GITHUB_SHA \
${{ inputs.draft && '--draft' || '' }} \
--notes-file "${RUNNER_TEMP}/release_notes.md" \
./release_artifacts/clio_server*

View File

@@ -1,129 +0,0 @@
name: Make release
on:
workflow_call:
inputs:
delete_pattern:
description: "Pattern to delete previous releases"
required: true
type: string
prerelease:
description: "Create a prerelease"
required: true
type: boolean
title:
description: "Release title"
required: true
type: string
version:
description: "Release version"
required: true
type: string
header:
description: "Release notes header"
required: true
type: string
generate_changelog:
description: "Generate changelog"
required: true
type: boolean
draft:
description: "Create a draft release"
required: true
type: boolean
defaults:
run:
shell: bash
jobs:
release:
runs-on: heavy
container:
image: ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696
env:
GH_REPO: ${{ github.repository }}
GH_TOKEN: ${{ github.token }}
permissions:
contents: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d
with:
enable_ccache: false
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
path: release_artifacts
pattern: clio_server_*
- name: Prepare release artifacts
run: .github/scripts/prepare-release-artifacts.sh release_artifacts
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
path: release_artifacts
pattern: clio_deb_package_*
- name: Create release notes
env:
RELEASE_HEADER: ${{ inputs.header }}
run: |
echo "# Release notes" > "${RUNNER_TEMP}/release_notes.md"
echo "" >> "${RUNNER_TEMP}/release_notes.md"
printf '%s\n' "${RELEASE_HEADER}" >> "${RUNNER_TEMP}/release_notes.md"
- name: Generate changelog
if: ${{ inputs.generate_changelog }}
run: |
LAST_TAG="$(gh release view --json tagName -q .tagName --repo XRPLF/clio)"
LAST_TAG_COMMIT="$(git rev-parse $LAST_TAG)"
BASE_COMMIT="$(git merge-base HEAD $LAST_TAG_COMMIT)"
git-cliff "${BASE_COMMIT}..HEAD" --ignore-tags "nightly|-b|-rc" >> "${RUNNER_TEMP}/release_notes.md"
- name: Upload release notes
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: release_notes_${{ inputs.version }}
path: "${RUNNER_TEMP}/release_notes.md"
- name: Remove previous release with a pattern
if: ${{ github.event_name != 'pull_request' && inputs.delete_pattern != '' }}
env:
DELETE_PATTERN: ${{ inputs.delete_pattern }}
run: |
RELEASES_TO_DELETE=$(gh release list --limit 50 --repo "${GH_REPO}" | grep -E "${DELETE_PATTERN}" | awk -F'\t' '{print $3}' || true)
if [ -n "$RELEASES_TO_DELETE" ]; then
for RELEASE in $RELEASES_TO_DELETE; do
echo "Deleting release: $RELEASE"
gh release delete "$RELEASE" --repo "${GH_REPO}" --yes --cleanup-tag
done
fi
- name: Publish release
if: ${{ github.event_name != 'pull_request' }}
env:
RELEASE_VERSION: ${{ inputs.version }}
PRERELEASE_OPTION: ${{ inputs.prerelease && '--prerelease' || '' }}
RELEASE_TITLE: ${{ inputs.title }}
DRAFT_OPTION: ${{ inputs.draft && '--draft' || '' }}
run: |
gh release create "${RELEASE_VERSION}" \
${PRERELEASE_OPTION} \
--title "${RELEASE_TITLE}" \
--target "${GITHUB_SHA}" \
${DRAFT_OPTION} \
--notes-file "${RUNNER_TEMP}/release_notes.md" \
./release_artifacts/clio_*

View File

@@ -8,13 +8,14 @@ on:
paths: paths:
- .github/workflows/sanitizers.yml - .github/workflows/sanitizers.yml
- .github/workflows/reusable-build-test.yml - .github/workflows/build_and_test.yml
- .github/workflows/reusable-build.yml - .github/workflows/build_impl.yml
- .github/workflows/reusable-test.yml - .github/workflows/test_impl.yml
- ".github/actions/**" - ".github/actions/**"
- "!.github/actions/build-docker-image/**" - "!.github/actions/build_docker_image/**"
- "!.github/actions/create-issue/**" - "!.github/actions/create_issue/**"
- .github/scripts/execute-tests-under-sanitizer
- CMakeLists.txt - CMakeLists.txt
- conanfile.py - conanfile.py
@@ -36,18 +37,20 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
compiler: [gcc, clang] compiler: ["gcc", "clang"]
sanitizer_ext: [.asan, .tsan, .ubsan] sanitizer_ext: [".asan", ".tsan", ".ubsan"]
build_type: [Release, Debug] exclude:
# Currently, clang.tsan unit tests hang
- compiler: clang
sanitizer_ext: .tsan
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/build_and_test.yml
with: with:
runs_on: heavy runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696" }' container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
download_ccache: false disable_cache: true
upload_ccache: false
conan_profile: ${{ matrix.compiler }}${{ matrix.sanitizer_ext }} conan_profile: ${{ matrix.compiler }}${{ matrix.sanitizer_ext }}
build_type: ${{ matrix.build_type }} build_type: Release
static: false static: false
run_unit_tests: true run_unit_tests: true
run_integration_tests: false run_integration_tests: false

View File

@@ -33,62 +33,82 @@ on:
required: true required: true
type: boolean type: boolean
defaults:
run:
shell: bash
jobs: jobs:
unit_tests: unit_tests:
name: Unit testing name: Unit testing
runs-on: ${{ inputs.runs_on }} runs-on: ${{ inputs.runs_on }}
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }} container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
if: ${{ inputs.run_unit_tests }} if: inputs.run_unit_tests
env:
# TODO: remove completely when we have fixed all currently existing issues with sanitizers
SANITIZER_IGNORE_ERRORS: ${{ endsWith(inputs.conan_profile, '.asan') || endsWith(inputs.conan_profile, '.tsan') }}
steps: steps:
- name: Cleanup workspace - name: Clean workdir
if: ${{ runner.os == 'macOS' }} if: ${{ runner.os == 'macOS' }}
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4 uses: kuznetsss/workspace-cleanup@80b9863b45562c148927c3d53621ef354e5ae7ce # v1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 - uses: actions/download-artifact@v4
with: with:
name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
- name: Make clio_tests executable - name: Make clio_tests executable
shell: bash
run: chmod +x ./clio_tests run: chmod +x ./clio_tests
- name: Run clio_tests - name: Run clio_tests (regular)
continue-on-error: true if: env.SANITIZER_IGNORE_ERRORS == 'false'
id: run_clio_tests
run: ./clio_tests run: ./clio_tests
- name: Run clio_tests (sanitizer errors ignored)
if: env.SANITIZER_IGNORE_ERRORS == 'true'
run: ./.github/scripts/execute-tests-under-sanitizer ./clio_tests
- name: Check for sanitizer report
if: env.SANITIZER_IGNORE_ERRORS == 'true'
shell: bash
id: check_report
run: |
if ls .sanitizer-report/* 1> /dev/null 2>&1; then
echo "found_report=true" >> $GITHUB_OUTPUT
else
echo "found_report=false" >> $GITHUB_OUTPUT
fi
- name: Upload sanitizer report
if: env.SANITIZER_IGNORE_ERRORS == 'true' && steps.check_report.outputs.found_report == 'true'
uses: actions/upload-artifact@v4
with:
name: ${{ inputs.conan_profile }}_report
path: .sanitizer-report/*
include-hidden-files: true
- name: Create an issue - name: Create an issue
if: ${{ steps.run_clio_tests.outcome == 'failure' && endsWith(inputs.conan_profile, 'san') }} if: false && env.SANITIZER_IGNORE_ERRORS == 'true' && steps.check_report.outputs.found_report == 'true'
uses: ./.github/actions/create-issue uses: ./.github/actions/create_issue
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
with: with:
labels: "bug" labels: "bug"
title: "[${{ inputs.conan_profile }}] reported issues" title: "[${{ inputs.conan_profile }}] reported issues"
body: > body: >
Clio tests failed one or more sanitizer checks when built with `${{ inputs.conan_profile }}`. Clio tests failed one or more sanitizer checks when built with ${{ inputs.conan_profile }}`.
Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/ Workflow: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}/
Reports are available as artifacts.
- name: Fail the job if clio_tests failed
if: ${{ steps.run_clio_tests.outcome == 'failure' }}
run: exit 1
integration_tests: integration_tests:
name: Integration testing name: Integration testing
runs-on: ${{ inputs.runs_on }} runs-on: ${{ inputs.runs_on }}
container: ${{ inputs.container != '' && fromJson(inputs.container) || null }} container: ${{ inputs.container != '' && fromJson(inputs.container) || null }}
if: ${{ inputs.run_integration_tests }} if: inputs.run_integration_tests
services: services:
scylladb: scylladb:
@@ -100,21 +120,15 @@ jobs:
--health-retries 5 --health-retries 5
steps: steps:
- name: Cleanup workspace - name: Clean workdir
if: ${{ runner.os == 'macOS' }} if: ${{ runner.os == 'macOS' }}
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4 uses: kuznetsss/workspace-cleanup@80b9863b45562c148927c3d53621ef354e5ae7ce # v1.0
- name: Delete and start colima (macOS) - name: Spin up scylladb
# This is a temporary workaround for colima issues on macOS runners
if: ${{ runner.os == 'macOS' }} if: ${{ runner.os == 'macOS' }}
timeout-minutes: 3
run: | run: |
colima delete --force docker rm --force scylladb || true
colima start
- name: Spin up scylladb (macOS)
if: ${{ runner.os == 'macOS' }}
timeout-minutes: 1
run: |
docker run \ docker run \
--detach \ --detach \
--name scylladb \ --name scylladb \
@@ -126,15 +140,11 @@ jobs:
--memory 16G \ --memory 16G \
scylladb/scylla scylladb/scylla
- name: Wait for scylladb container to be healthy (macOS)
if: ${{ runner.os == 'macOS' }}
timeout-minutes: 1
run: |
until [ "$(docker inspect -f '{{.State.Health.Status}}' scylladb)" == "healthy" ]; do until [ "$(docker inspect -f '{{.State.Health.Status}}' scylladb)" == "healthy" ]; do
sleep 1 sleep 5
done done
- uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 - uses: actions/download-artifact@v4
with: with:
name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}

View File

@@ -1,364 +0,0 @@
name: Update CI docker image
on:
pull_request:
paths:
- .github/workflows/update-docker-ci.yml
- ".github/actions/build-docker-image/**"
- "docker/**"
- "!docker/clio/**"
- "!docker/develop/**"
push:
branches: [develop]
paths:
- .github/workflows/update-docker-ci.yml
- ".github/actions/build-docker-image/**"
- "docker/**"
- "!docker/clio/**"
- "!docker/develop/**"
workflow_dispatch:
concurrency:
# Only matches runs for the current workflow - matches against branch & tags
group: ${{ github.workflow }}-${{ github.ref }}
# We want to execute all builds sequentially in develop
cancel-in-progress: false
env:
CLANG_MAJOR_VERSION: 19
GCC_MAJOR_VERSION: 15
GCC_VERSION: 15.2.0
defaults:
run:
shell: bash
jobs:
repo:
name: Calculate repo name
runs-on: ubuntu-latest
outputs:
GHCR_REPO: ${{ steps.set-ghcr-repo.outputs.GHCR_REPO }}
steps:
- name: Set GHCR_REPO
id: set-ghcr-repo
run: |
echo "GHCR_REPO=$(echo ghcr.io/${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_OUTPUT}
gcc-amd64:
name: Build and push GCC docker image (amd64)
runs-on: heavy
needs: repo
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
with:
files: "docker/compilers/gcc/**"
- uses: ./.github/actions/build-docker-image
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with:
images: |
${{ needs.repo.outputs.GHCR_REPO }}/clio-gcc
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_gcc' || '' }}
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/compilers/gcc
tags: |
type=raw,value=amd64-latest
type=raw,value=amd64-${{ env.GCC_MAJOR_VERSION }}
type=raw,value=amd64-${{ env.GCC_VERSION }}
type=raw,value=amd64-${{ github.sha }}
platforms: linux/amd64
build_args: |
GCC_MAJOR_VERSION=${{ env.GCC_MAJOR_VERSION }}
GCC_VERSION=${{ env.GCC_VERSION }}
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_gcc' || '' }}
dockerhub_description: GCC compiler for XRPLF/clio.
gcc-arm64:
name: Build and push GCC docker image (arm64)
runs-on: heavy-arm64
needs: repo
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
with:
files: "docker/compilers/gcc/**"
- uses: ./.github/actions/build-docker-image
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with:
images: |
${{ needs.repo.outputs.GHCR_REPO }}/clio-gcc
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_gcc' || '' }}
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/compilers/gcc
tags: |
type=raw,value=arm64-latest
type=raw,value=arm64-${{ env.GCC_MAJOR_VERSION }}
type=raw,value=arm64-${{ env.GCC_VERSION }}
type=raw,value=arm64-${{ github.sha }}
platforms: linux/arm64
build_args: |
GCC_MAJOR_VERSION=${{ env.GCC_MAJOR_VERSION }}
GCC_VERSION=${{ env.GCC_VERSION }}
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_gcc' || '' }}
dockerhub_description: GCC compiler for XRPLF/clio.
gcc-merge:
name: Merge and push multi-arch GCC docker image
runs-on: heavy
needs: [repo, gcc-amd64, gcc-arm64]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
with:
files: "docker/compilers/gcc/**"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Login to GitHub Container Registry
if: ${{ github.event_name != 'pull_request' }}
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }}
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PW }}
- name: Create and push multi-arch manifest
if: ${{ github.event_name != 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
run: |
push_image() {
image=$1
docker buildx imagetools create \
-t $image:latest \
-t $image:${{ env.GCC_MAJOR_VERSION }} \
-t $image:${{ env.GCC_VERSION }} \
-t $image:${{ github.sha }} \
$image:arm64-latest \
$image:amd64-latest
}
push_image ${{ needs.repo.outputs.GHCR_REPO }}/clio-gcc
if [[ ${{ github.repository_owner }} == 'XRPLF' ]]; then
push_image rippleci/clio_clang
fi
clang:
name: Build and push Clang docker image
runs-on: heavy
needs: repo
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
with:
files: "docker/compilers/clang/**"
- uses: ./.github/actions/build-docker-image
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with:
images: |
${{ needs.repo.outputs.GHCR_REPO }}/clio-clang
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_clang' || '' }}
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/compilers/clang
tags: |
type=raw,value=latest
type=raw,value=${{ env.CLANG_MAJOR_VERSION }}
type=raw,value=${{ github.sha }}
platforms: linux/amd64,linux/arm64
build_args: |
CLANG_MAJOR_VERSION=${{ env.CLANG_MAJOR_VERSION }}
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_clang' || '' }}
dockerhub_description: Clang compiler for XRPLF/clio.
tools-amd64:
name: Build and push tools docker image (amd64)
runs-on: heavy
needs: [repo, gcc-merge]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
with:
files: "docker/tools/**"
- uses: ./.github/actions/build-docker-image
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
images: |
${{ needs.repo.outputs.GHCR_REPO }}/clio-tools
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/tools
tags: |
type=raw,value=amd64-latest
type=raw,value=amd64-${{ github.sha }}
platforms: linux/amd64
build_args: |
GHCR_REPO=${{ needs.repo.outputs.GHCR_REPO }}
GCC_VERSION=${{ env.GCC_VERSION }}
tools-arm64:
name: Build and push tools docker image (arm64)
runs-on: heavy-arm64
needs: [repo, gcc-merge]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
with:
files: "docker/tools/**"
- uses: ./.github/actions/build-docker-image
if: ${{ steps.changed-files.outputs.any_changed == 'true' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
images: |
${{ needs.repo.outputs.GHCR_REPO }}/clio-tools
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/tools
tags: |
type=raw,value=arm64-latest
type=raw,value=arm64-${{ github.sha }}
platforms: linux/arm64
build_args: |
GHCR_REPO=${{ needs.repo.outputs.GHCR_REPO }}
GCC_VERSION=${{ env.GCC_VERSION }}
tools-merge:
name: Merge and push multi-arch tools docker image
runs-on: heavy
needs: [repo, tools-amd64, tools-arm64]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
with:
files: "docker/tools/**"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3.12.0
- name: Login to GitHub Container Registry
if: ${{ github.event_name != 'pull_request' }}
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3.7.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Create and push multi-arch manifest
if: ${{ github.event_name != 'pull_request' && steps.changed-files.outputs.any_changed == 'true' }}
run: |
image=${{ needs.repo.outputs.GHCR_REPO }}/clio-tools
docker buildx imagetools create \
-t $image:latest \
-t $image:${{ github.sha }} \
$image:arm64-latest \
$image:amd64-latest
pre-commit:
name: Build and push pre-commit docker image
runs-on: heavy
needs: [repo, tools-merge]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/build-docker-image
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
images: |
${{ needs.repo.outputs.GHCR_REPO }}/clio-pre-commit
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/pre-commit
tags: |
type=raw,value=latest
type=raw,value=${{ github.sha }}
platforms: linux/amd64,linux/arm64
build_args: |
GHCR_REPO=${{ needs.repo.outputs.GHCR_REPO }}
ci:
name: Build and push CI docker image
runs-on: heavy
needs: [repo, gcc-merge, clang, tools-merge]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/build-docker-image
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with:
images: |
${{ needs.repo.outputs.GHCR_REPO }}/clio-ci
${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_ci' || '' }}
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/ci
tags: |
type=raw,value=latest
type=raw,value=gcc_${{ env.GCC_MAJOR_VERSION }}_clang_${{ env.CLANG_MAJOR_VERSION }}
type=raw,value=${{ github.sha }}
platforms: linux/amd64,linux/arm64
build_args: |
GHCR_REPO=${{ needs.repo.outputs.GHCR_REPO }}
CLANG_MAJOR_VERSION=${{ env.CLANG_MAJOR_VERSION }}
GCC_MAJOR_VERSION=${{ env.GCC_MAJOR_VERSION }}
GCC_VERSION=${{ env.GCC_VERSION }}
dockerhub_repo: ${{ github.repository_owner == 'XRPLF' && 'rippleci/clio_ci' || '' }}
dockerhub_description: CI image for XRPLF/clio.

236
.github/workflows/update_docker_ci.yml vendored Normal file
View File

@@ -0,0 +1,236 @@
name: Update CI docker image
on:
pull_request:
paths:
- .github/workflows/update_docker_ci.yml
- ".github/actions/build_docker_image/**"
- "docker/ci/**"
- "docker/compilers/**"
- "docker/tools/**"
push:
branches: [develop]
paths:
- .github/workflows/update_docker_ci.yml
- ".github/actions/build_docker_image/**"
- "docker/ci/**"
- "docker/compilers/**"
- "docker/tools/**"
workflow_dispatch:
concurrency:
# Only cancel in-progress jobs or runs for the current workflow - matches against branch & tags
group: ${{ github.workflow }}-${{ github.ref }}
# We want to execute all builds sequentially in develop
cancel-in-progress: false
env:
GHCR_REPO: ghcr.io/${{ github.repository_owner }}
jobs:
gcc-amd64:
name: Build and push GCC docker image (amd64)
runs-on: heavy
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: "docker/compilers/gcc/**"
- uses: ./.github/actions/build_docker_image
if: steps.changed-files.outputs.any_changed == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with:
images: |
${{ env.GHCR_REPO }}/clio-gcc
rippleci/clio_gcc
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/compilers/gcc
tags: |
type=raw,value=amd64-latest
type=raw,value=amd64-12
type=raw,value=amd64-12.3.0
type=raw,value=amd64-${{ github.sha }}
platforms: linux/amd64
dockerhub_repo: rippleci/clio_gcc
dockerhub_description: GCC compiler for XRPLF/clio.
gcc-arm64:
name: Build and push GCC docker image (arm64)
runs-on: heavy-arm64
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: "docker/compilers/gcc/**"
- uses: ./.github/actions/build_docker_image
if: steps.changed-files.outputs.any_changed == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with:
images: |
${{ env.GHCR_REPO }}/clio-gcc
rippleci/clio_gcc
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/compilers/gcc
tags: |
type=raw,value=arm64-latest
type=raw,value=arm64-12
type=raw,value=arm64-12.3.0
type=raw,value=arm64-${{ github.sha }}
platforms: linux/arm64
dockerhub_repo: rippleci/clio_gcc
dockerhub_description: GCC compiler for XRPLF/clio.
gcc-merge:
name: Merge and push multi-arch GCC docker image
runs-on: heavy
needs: [gcc-amd64, gcc-arm64]
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: "docker/compilers/gcc/**"
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_PW }}
- name: Make GHCR_REPO lowercase
run: |
echo "GHCR_REPO_LC=$(echo ${{env.GHCR_REPO}} | tr '[:upper:]' '[:lower:]')" >> ${GITHUB_ENV}
- name: Create and push multi-arch manifest
if: github.event_name != 'pull_request' && steps.changed-files.outputs.any_changed == 'true'
run: |
for image in ${{ env.GHCR_REPO_LC }}/clio-gcc rippleci/clio_gcc; do
docker buildx imagetools create \
-t $image:latest \
-t $image:12 \
-t $image:12.3.0 \
-t $image:${{ github.sha }} \
$image:arm64-latest \
$image:amd64-latest
done
clang:
name: Build and push Clang docker image
runs-on: heavy
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: "docker/compilers/clang/**"
- uses: ./.github/actions/build_docker_image
if: steps.changed-files.outputs.any_changed == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with:
images: |
${{ env.GHCR_REPO }}/clio-clang
rippleci/clio_clang
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/compilers/clang
tags: |
type=raw,value=latest
type=raw,value=16
type=raw,value=${{ github.sha }}
platforms: linux/amd64,linux/arm64
dockerhub_repo: rippleci/clio_clang
dockerhub_description: Clang compiler for XRPLF/clio.
tools:
name: Build and push tools docker image
runs-on: heavy
steps:
- uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: "docker/tools/**"
- uses: ./.github/actions/build_docker_image
if: steps.changed-files.outputs.any_changed == 'true'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
images: |
${{ env.GHCR_REPO }}/clio-tools
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/tools
tags: |
type=raw,value=latest
type=raw,value=${{ github.sha }}
platforms: linux/amd64,linux/arm64
ci:
name: Build and push CI docker image
runs-on: heavy
needs: [gcc-merge, clang, tools]
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/build_docker_image
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DOCKERHUB_USER: ${{ secrets.DOCKERHUB_USER }}
DOCKERHUB_PW: ${{ secrets.DOCKERHUB_PW }}
with:
images: |
${{ env.GHCR_REPO }}/clio-ci
rippleci/clio_ci
push_image: ${{ github.event_name != 'pull_request' }}
directory: docker/ci
tags: |
type=raw,value=latest
type=raw,value=gcc_12_clang_16
type=raw,value=${{ github.sha }}
platforms: linux/amd64,linux/arm64
dockerhub_repo: rippleci/clio_ci
dockerhub_description: CI image for XRPLF/clio.

View File

@@ -10,31 +10,20 @@ on:
required: false required: false
default: false default: false
type: boolean type: boolean
force_upload:
description: "Force upload of all dependencies"
required: false
default: false
type: boolean
pull_request: pull_request:
branches: [develop] branches:
- develop
paths: paths:
- .github/workflows/upload-conan-deps.yml - .github/workflows/upload_conan_deps.yml
- .github/scripts/generate_conan_matrix.py
- .github/actions/conan/action.yml
- ".github/scripts/conan/**"
- "!.github/scripts/conan/regenerate_lockfile.sh"
- conanfile.py - conanfile.py
- conan.lock - conan.lock
push: push:
branches: [develop] branches:
- develop
paths: paths:
- .github/workflows/upload-conan-deps.yml - .github/workflows/upload_conan_deps.yml
- .github/scripts/generate_conan_matrix.py
- .github/actions/conan/action.yml
- ".github/scripts/conan/**"
- "!.github/scripts/conan/regenerate_lockfile.sh"
- conanfile.py - conanfile.py
- conan.lock - conan.lock
@@ -42,21 +31,17 @@ concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true
defaults:
run:
shell: bash
jobs: jobs:
generate-matrix: generate-matrix:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }} matrix: ${{ steps.set-matrix.outputs.matrix }}
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
- name: Calculate conan matrix - name: Calculate conan matrix
id: set-matrix id: set-matrix
run: .github/scripts/conan/generate_matrix.py >> "${GITHUB_OUTPUT}" run: .github/scripts/generate_conan_matrix.py >> "${GITHUB_OUTPUT}"
upload-conan-deps: upload-conan-deps:
name: Build ${{ matrix.compiler }}${{ matrix.sanitizer_ext }} ${{ matrix.build_type }} name: Build ${{ matrix.compiler }}${{ matrix.sanitizer_ext }} ${{ matrix.build_type }}
@@ -66,7 +51,6 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }} matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
max-parallel: 10
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
container: ${{ matrix.container != '' && fromJson(matrix.container) || null }} container: ${{ matrix.container != '' && fromJson(matrix.container) || null }}
@@ -75,22 +59,24 @@ jobs:
CONAN_PROFILE: ${{ matrix.compiler }}${{ matrix.sanitizer_ext }} CONAN_PROFILE: ${{ matrix.compiler }}${{ matrix.sanitizer_ext }}
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d uses: ./.github/actions/prepare_runner
with: with:
enable_ccache: false disable_ccache: true
- name: Setup conan on macOS - name: Setup conan
if: ${{ runner.os == 'macOS' }} if: runner.os == 'macOS'
run: ./.github/scripts/conan/init.sh uses: ./.github/actions/setup_conan_macos
with:
conan_files_dir: docker/ci/conan/
- name: Show conan profile - name: Show conan profile
run: conan profile show --profile:all ${{ env.CONAN_PROFILE }} run: conan profile show --profile:all ${{ env.CONAN_PROFILE }}
- name: Run conan - name: Run conan and cmake
uses: ./.github/actions/conan uses: ./.github/actions/generate
with: with:
conan_profile: ${{ env.CONAN_PROFILE }} conan_profile: ${{ env.CONAN_PROFILE }}
# We check that everything builds fine from source on scheduled runs # We check that everything builds fine from source on scheduled runs
@@ -99,11 +85,9 @@ jobs:
build_type: ${{ matrix.build_type }} build_type: ${{ matrix.build_type }}
- name: Login to Conan - name: Login to Conan
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }} if: github.event_name != 'pull_request'
run: conan remote login -p ${{ secrets.CONAN_PASSWORD }} xrplf ${{ secrets.CONAN_USERNAME }} run: conan remote login -p ${{ secrets.CONAN_PASSWORD }} ripple ${{ secrets.CONAN_USERNAME }}
- name: Upload Conan packages - name: Upload Conan packages
if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' && github.event_name != 'schedule' }} if: github.event_name != 'pull_request' && github.event_name != 'schedule'
env: run: conan upload "*" -r=ripple --confirm
FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
run: conan upload "*" -r=xrplf --confirm ${FORCE_OPTION}

View File

@@ -1,34 +1,31 @@
name: Upload report name: Upload report
on: on:
workflow_dispatch:
workflow_call: workflow_call:
secrets: secrets:
CODECOV_TOKEN: CODECOV_TOKEN:
required: true required: true
defaults:
run:
shell: bash
jobs: jobs:
upload_report: upload_report:
name: Upload report name: Upload report
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Download report artifact - name: Download report artifact
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0 uses: actions/download-artifact@v4
with: with:
name: coverage-report.xml name: coverage-report.xml
path: build path: build
- name: Upload coverage report - name: Upload coverage report
if: ${{ hashFiles('build/coverage_report.xml') != '' }} if: ${{ hashFiles('build/coverage_report.xml') != '' }}
uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5.5.2 uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with: with:
files: build/coverage_report.xml files: build/coverage_report.xml
fail_ci_if_error: true fail_ci_if_error: true

4
.gitignore vendored
View File

@@ -4,11 +4,9 @@
.build .build
.cache .cache
.vscode .vscode
.zed
.python-version .python-version
.DS_Store .DS_Store
.sanitizer-report .sanitizer-report
CMakeUserPresets.json CMakeUserPresets.json
config.json config.json
CLAUDE.md src/util/build/Build.cpp
.claude/**

View File

@@ -11,15 +11,12 @@
# #
# See https://pre-commit.com for more information # See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks # See https://pre-commit.com/hooks.html for more hooks
exclude: | exclude: ^(docs/doxygen-awesome-theme/|conan\.lock$)
(?x)^(
docs/doxygen-awesome-theme/.*
)$
repos: repos:
# `pre-commit sample-config` default hooks # `pre-commit sample-config` default hooks
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0 rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0
hooks: hooks:
- id: check-added-large-files - id: check-added-large-files
- id: check-executables-have-shebangs - id: check-executables-have-shebangs
@@ -29,24 +26,24 @@ repos:
# Autoformat: YAML, JSON, Markdown, etc. # Autoformat: YAML, JSON, Markdown, etc.
- repo: https://github.com/rbubley/mirrors-prettier - repo: https://github.com/rbubley/mirrors-prettier
rev: c2bc67fe8f8f549cc489e00ba8b45aa18ee713b1 # frozen: v3.8.1 rev: 787fb9f542b140ba0b2aced38e6a3e68021647a3 # frozen: v3.5.3
hooks: hooks:
- id: prettier - id: prettier
- repo: https://github.com/igorshubovych/markdownlint-cli - repo: https://github.com/igorshubovych/markdownlint-cli
rev: 76b3d32d3f4b965e1d6425253c59407420ae2c43 # frozen: v0.47.0 rev: 586c3ea3f51230da42bab657c6a32e9e66c364f0 # frozen: v0.44.0
hooks: hooks:
- id: markdownlint-fix - id: markdownlint-fix
exclude: LICENSE.md exclude: LICENSE.md
- repo: https://github.com/hadolint/hadolint - repo: https://github.com/hadolint/hadolint
rev: 4e697ba704fd23b2409b947a319c19c3ee54d24f # frozen: v2.14.0 rev: c3dc18df7a501f02a560a2cc7ba3c69a85ca01d3 # frozen: v2.13.1-beta
hooks: hooks:
- id: hadolint-docker - id: hadolint-docker
# hadolint-docker is a special hook that runs hadolint in a Docker container # hadolint-docker is a special hook that runs hadolint in a Docker container
# Docker is not installed in the environment where pre-commit is run # Docker is not installed in the environment where pre-commit is run
stages: [manual] stages: [manual]
entry: hadolint/hadolint:v2.14.0 hadolint entry: hadolint/hadolint:v2.12.1-beta hadolint
- repo: https://github.com/codespell-project/codespell - repo: https://github.com/codespell-project/codespell
rev: 63c8f8312b7559622c0d82815639671ae42132ac # frozen: v2.4.1 rev: 63c8f8312b7559622c0d82815639671ae42132ac # frozen: v2.4.1
@@ -58,52 +55,27 @@ repos:
--ignore-words=pre-commit-hooks/codespell_ignore.txt, --ignore-words=pre-commit-hooks/codespell_ignore.txt,
] ]
- repo: https://github.com/psf/black-pre-commit-mirror # Running fix-local-includes before clang-format
rev: ea488cebbfd88a5f50b8bd95d5c829d0bb76feb8 # frozen: 26.1.0 # to ensure that the include order is correct.
hooks:
- id: black
- repo: https://github.com/scop/pre-commit-shfmt
rev: 2a30809d16bc7a60d9b97353c797f42b510d3368 # frozen: v3.12.0-2
hooks:
- id: shfmt
args: ["-i", "4", "--write"]
# Running some C++ hooks before clang-format
# to ensure that the style is consistent.
- repo: local - repo: local
hooks: hooks:
- id: json-in-cpp
name: Fix JSON style in C++
entry: pre-commit-hooks/json_in_cpp.py
types: [c++]
language: python
exclude: |
(?x)^(
tests/unit/etl/SubscriptionSourceTests.cpp|
tests/unit/web/ServerTests.cpp|
tests/unit/web/impl/ErrorHandlingTests.cpp|
tests/unit/web/ng/ServerTests.cpp|
tests/unit/web/ng/impl/ErrorHandlingTests.cpp
)$
- id: fix-local-includes - id: fix-local-includes
name: Fix Local Includes name: Fix Local Includes
entry: pre-commit-hooks/fix-local-includes.sh entry: pre-commit-hooks/fix-local-includes.sh
types: [c++] types: [c++]
language: script language: script
- repo: https://github.com/pre-commit/mirrors-clang-format - repo: https://github.com/pre-commit/mirrors-clang-format
rev: cd481d7b0bfb5c7b3090c21846317f9a8262e891 # frozen: v22.1.0 rev: f9a52e87b6cdcb01b0a62b8611d9ba9f2dad0067 # frozen: v19.1.7
hooks: hooks:
- id: clang-format - id: clang-format
args: [--style=file] args: [--style=file]
types: [c++] types: [c++]
- repo: https://github.com/BlankSpruce/gersemi - repo: https://github.com/cheshirekow/cmake-format-precommit
rev: 0.26.0 rev: e2c2116d86a80e72e7146a06e68b7c228afc6319 # frozen: v0.6.13
hooks: hooks:
- id: gersemi - id: cmake-format
additional_dependencies: [PyYAML]
- repo: local - repo: local
hooks: hooks:

View File

@@ -1,9 +1,8 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
project( set(CMAKE_PROJECT_INCLUDE_BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ClioVersion.cmake)
clio
VERSION ${CLIO_VERSION} project(clio VERSION ${CLIO_VERSION} HOMEPAGE_URL "https://github.com/XRPLF/clio"
HOMEPAGE_URL "https://github.com/XRPLF/clio"
DESCRIPTION "An XRP Ledger API Server" DESCRIPTION "An XRP Ledger API Server"
) )
@@ -14,15 +13,11 @@ option(integration_tests "Build integration tests" FALSE)
option(benchmark "Build benchmarks" FALSE) option(benchmark "Build benchmarks" FALSE)
option(docs "Generate doxygen docs" FALSE) option(docs "Generate doxygen docs" FALSE)
option(coverage "Build test coverage report" FALSE) option(coverage "Build test coverage report" FALSE)
option(package "Create distribution packages" FALSE) option(packaging "Create distribution packages" FALSE)
option(lint "Run clang-tidy checks during compilation" FALSE) option(lint "Run clang-tidy checks during compilation" FALSE)
option(static "Statically linked Clio" FALSE) option(static "Statically linked Clio" FALSE)
option(snapshot "Build snapshot tool" FALSE) option(snapshot "Build snapshot tool" FALSE)
option( option(time_trace "Build using -ftime-trace to create compiler trace reports" FALSE)
time_trace
"Build using -ftime-trace to create compiler trace reports"
FALSE
)
# ========================================================================== # # ========================================================================== #
set(san "" CACHE STRING "Add sanitizer instrumentation") set(san "" CACHE STRING "Add sanitizer instrumentation")
@@ -36,15 +31,19 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
include(Ccache) include(Ccache)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(ClangTidy) include(ClangTidy)
include(Linker)
add_library(clio_options INTERFACE) add_library(clio_options INTERFACE)
target_compile_features(clio_options INTERFACE cxx_std_23) # Clio needs c++23 but deps can remain c++20 for now target_compile_features(clio_options INTERFACE cxx_std_23) # Clio needs c++23 but deps can remain c++20 for now
target_include_directories(clio_options INTERFACE ${CMAKE_SOURCE_DIR}/src) target_include_directories(clio_options INTERFACE ${CMAKE_SOURCE_DIR}/src)
if(verbose) if (verbose)
set(CMAKE_VERBOSE_MAKEFILE TRUE) set(CMAKE_VERBOSE_MAKEFILE TRUE)
endif() endif ()
if (packaging)
add_definitions(-DPKG=1)
target_compile_definitions(clio_options INTERFACE PKG=1)
endif ()
# Clio tweaks and checks # Clio tweaks and checks
include(CheckCompiler) include(CheckCompiler)
@@ -59,48 +58,43 @@ include(deps/Threads)
include(deps/libfmt) include(deps/libfmt)
include(deps/cassandra) include(deps/cassandra)
include(deps/libbacktrace) include(deps/libbacktrace)
include(deps/spdlog)
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(tests) add_subdirectory(tests)
if(benchmark) if (benchmark)
add_subdirectory(benchmarks) add_subdirectory(benchmarks)
endif() endif ()
# Enable selected sanitizer if enabled via `san` # Enable selected sanitizer if enabled via `san`
if(san) if (san)
set(SUPPORTED_SANITIZERS "address" "thread" "memory" "undefined") set(SUPPORTED_SANITIZERS "address" "thread" "memory" "undefined")
if(NOT san IN_LIST SUPPORTED_SANITIZERS) list(FIND SUPPORTED_SANITIZERS "${san}" INDEX)
message( if (INDEX EQUAL -1)
FATAL_ERROR message(FATAL_ERROR "Error: Unsupported sanitizer '${san}'. Supported values are: ${SUPPORTED_SANITIZERS}.")
"Error: Unsupported sanitizer '${san}'. Supported values are: ${SUPPORTED_SANITIZERS}." endif ()
)
endif()
# Sanitizers recommend minimum of -O1 for reasonable performance so we enable it for debug builds
set(SAN_OPTIMIZATION_FLAG "")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(SAN_OPTIMIZATION_FLAG -O1)
endif()
target_compile_options( target_compile_options(
clio_options clio_options INTERFACE # Sanitizers recommend minimum of -O1 for reasonable performance
INTERFACE ${SAN_OPTIMIZATION_FLAG} ${SAN_FLAG} -fno-omit-frame-pointer $<$<CONFIG:Debug>:-O1> ${SAN_FLAG} -fno-omit-frame-pointer
)
target_compile_definitions(
clio_options INTERFACE $<$<STREQUAL:${san},address>:SANITIZER=ASAN> $<$<STREQUAL:${san},thread>:SANITIZER=TSAN>
$<$<STREQUAL:${san},memory>:SANITIZER=MSAN> $<$<STREQUAL:${san},undefined>:SANITIZER=UBSAN>
) )
target_link_libraries(clio_options INTERFACE ${SAN_FLAG} ${SAN_LIB}) target_link_libraries(clio_options INTERFACE ${SAN_FLAG} ${SAN_LIB})
endif() endif ()
# Generate `docs` target for doxygen documentation if enabled Note: use `make docs` to generate the documentation # Generate `docs` target for doxygen documentation if enabled Note: use `make docs` to generate the documentation
if(docs) if (docs)
add_subdirectory(docs) add_subdirectory(docs)
endif() endif ()
include(install/install) include(install/install)
if(package) if (packaging)
include(ClioPackage) include(cmake/packaging.cmake) # This file exists only in build runner
endif() endif ()
if(snapshot) if (snapshot)
add_subdirectory(tools/snapshot) add_subdirectory(tools/snapshot)
endif() endif ()

View File

@@ -180,7 +180,6 @@ Existing maintainers can resign, or be subject to a vote for removal at the behe
- [kuznetsss](https://github.com/kuznetsss) (Ripple) - [kuznetsss](https://github.com/kuznetsss) (Ripple)
- [legleux](https://github.com/legleux) (Ripple) - [legleux](https://github.com/legleux) (Ripple)
- [PeterChen13579](https://github.com/PeterChen13579) (Ripple) - [PeterChen13579](https://github.com/PeterChen13579) (Ripple)
- [mathbunnyru](https://github.com/mathbunnyru) (Ripple)
### Honorable ex-Maintainers ### Honorable ex-Maintainers

View File

@@ -34,6 +34,7 @@ Below are some useful docs to learn more about Clio.
- [How to configure Clio and rippled](./docs/configure-clio.md) - [How to configure Clio and rippled](./docs/configure-clio.md)
- [How to run Clio](./docs/run-clio.md) - [How to run Clio](./docs/run-clio.md)
- [Logging](./docs/logging.md)
- [Troubleshooting guide](./docs/trouble_shooting.md) - [Troubleshooting guide](./docs/trouble_shooting.md)
**General reference material:** **General reference material:**

View File

@@ -2,26 +2,15 @@ add_executable(clio_benchmark)
target_sources( target_sources(
clio_benchmark clio_benchmark
PRIVATE PRIVATE # Common
# Common
Main.cpp Main.cpp
Playground.cpp Playground.cpp
# ExecutionContext # ExecutionContext
util/async/ExecutionContextBenchmarks.cpp util/async/ExecutionContextBenchmarks.cpp
# Logger
util/log/LoggerBenchmark.cpp
# WorkQueue
rpc/WorkQueueBenchmarks.cpp
) )
include(deps/gbench) include(deps/gbench)
target_include_directories(clio_benchmark PRIVATE .) target_include_directories(clio_benchmark PRIVATE .)
target_link_libraries( target_link_libraries(clio_benchmark PUBLIC clio_etl benchmark::benchmark_main)
clio_benchmark set_target_properties(clio_benchmark PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
PRIVATE clio_rpc clio_util benchmark::benchmark_main spdlog::spdlog
)
set_target_properties(
clio_benchmark
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
)

View File

@@ -1,153 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of clio: https://github.com/XRPLF/clio
Copyright (c) 2025, the clio developers.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "rpc/WorkQueue.hpp"
#include "util/Assert.hpp"
#include "util/config/Array.hpp"
#include "util/config/ConfigConstraints.hpp"
#include "util/config/ConfigDefinition.hpp"
#include "util/config/ConfigValue.hpp"
#include "util/config/Types.hpp"
#include "util/log/Logger.hpp"
#include "util/prometheus/Prometheus.hpp"
#include <benchmark/benchmark.h>
#include <boost/asio/steady_timer.hpp>
#include <algorithm>
#include <atomic>
#include <cassert>
#include <chrono>
#include <cstddef>
#include <cstdint>
#include <mutex>
#include <thread>
#include <vector>
using namespace rpc;
using namespace util::config;
namespace {
auto const kCONFIG = ClioConfigDefinition{
{"prometheus.compress_reply", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
{"prometheus.enabled", ConfigValue{ConfigType::Boolean}.defaultValue(true)},
{"log.channels.[].channel", Array{ConfigValue{ConfigType::String}}},
{"log.channels.[].level", Array{ConfigValue{ConfigType::String}}},
{"log.level", ConfigValue{ConfigType::String}.defaultValue("info")},
{"log.format",
ConfigValue{ConfigType::String}.defaultValue(R"(%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v)")},
{"log.is_async", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
{"log.enable_console", ConfigValue{ConfigType::Boolean}.defaultValue(false)},
{"log.directory", ConfigValue{ConfigType::String}.optional()},
{"log.rotation_size",
ConfigValue{ConfigType::Integer}.defaultValue(2048).withConstraint(gValidateUint32)},
{"log.directory_max_files",
ConfigValue{ConfigType::Integer}.defaultValue(25).withConstraint(gValidateUint32)},
{"log.tag_style", ConfigValue{ConfigType::String}.defaultValue("none")},
};
// this should be a fixture but it did not work with Args very well
void
init()
{
static std::once_flag kONCE;
std::call_once(kONCE, [] {
PrometheusService::init(kCONFIG);
(void)util::LogService::init(kCONFIG);
});
}
} // namespace
static void
benchmarkWorkQueue(benchmark::State& state)
{
init();
auto const wqThreads = static_cast<uint32_t>(state.range(0));
auto const maxQueueSize = static_cast<uint32_t>(state.range(1));
auto const clientThreads = static_cast<uint32_t>(state.range(2));
auto const itemsPerClient = static_cast<uint32_t>(state.range(3));
auto const clientProcessingMs = static_cast<uint32_t>(state.range(4));
for (auto _ : state) {
std::atomic_size_t totalExecuted = 0uz;
std::atomic_size_t totalQueued = 0uz;
state.PauseTiming();
WorkQueue queue(wqThreads, maxQueueSize);
state.ResumeTiming();
std::vector<std::thread> threads;
threads.reserve(clientThreads);
for (auto t = 0uz; t < clientThreads; ++t) {
threads.emplace_back([&] {
for (auto i = 0uz; i < itemsPerClient; ++i) {
totalQueued += static_cast<std::size_t>(queue.postCoro(
[&clientProcessingMs, &totalExecuted](auto yield) {
++totalExecuted;
boost::asio::steady_timer timer(
yield.get_executor(), std::chrono::milliseconds{clientProcessingMs}
);
timer.async_wait(yield);
std::this_thread::sleep_for(std::chrono::microseconds{10});
},
/* isWhiteListed = */ false
));
}
});
}
for (auto& t : threads)
t.join();
queue.stop();
ASSERT(totalExecuted == totalQueued, "Totals don't match");
ASSERT(totalQueued <= itemsPerClient * clientThreads, "Queued more than requested");
if (maxQueueSize == 0) {
ASSERT(
totalQueued == itemsPerClient * clientThreads, "Queued exactly the expected amount"
);
} else {
ASSERT(
totalQueued >= std::min(maxQueueSize, itemsPerClient * clientThreads),
"Queued less than expected"
);
}
}
}
// Usage example:
/*
./clio_benchmark \
--benchmark_repetitions=10 \
--benchmark_display_aggregates_only=true \
--benchmark_min_time=1x \
--benchmark_filter="WorkQueue"
*/
// TODO: figure out what happens on 1 thread
BENCHMARK(benchmarkWorkQueue)
->ArgsProduct({{2, 4, 8, 16}, {0, 5'000}, {4, 8, 16}, {1'000, 10'000}, {10, 100, 250}})
->Unit(benchmark::kMillisecond);

View File

@@ -1,154 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of clio: https://github.com/XRPLF/clio
Copyright (c) 2025, the clio developers.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include "util/config/ConfigDefinition.hpp"
#include "util/log/Logger.hpp"
#include "util/prometheus/Prometheus.hpp"
#include <benchmark/benchmark.h>
#include <fmt/format.h>
#include <spdlog/async.h>
#include <spdlog/async_logger.h>
#include <spdlog/spdlog.h>
#include <barrier>
#include <chrono>
#include <cstddef>
#include <filesystem>
#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <vector>
using namespace util;
static constexpr auto kLOG_FORMAT = "%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v";
struct BenchmarkLoggingInitializer {
[[nodiscard]] static std::shared_ptr<spdlog::sinks::sink>
createFileSink(LogService::FileLoggingParams const& params)
{
return LogService::createFileSink(params, kLOG_FORMAT);
}
static Logger
getLogger(std::shared_ptr<spdlog::logger> logger)
{
return Logger(std::move(logger));
}
};
namespace {
std::string
uniqueLogDir()
{
auto const epochTime = std::chrono::high_resolution_clock::now().time_since_epoch();
auto const tmpDir = std::filesystem::temp_directory_path();
std::string const dirName = fmt::format(
"logs_{}", std::chrono::duration_cast<std::chrono::microseconds>(epochTime).count()
);
return tmpDir / "clio_benchmark" / dirName;
}
} // anonymous namespace
static void
benchmarkConcurrentFileLogging(benchmark::State& state)
{
auto const numThreads = static_cast<size_t>(state.range(0));
auto const messagesPerThread = static_cast<size_t>(state.range(1));
PrometheusService::init(config::getClioConfig());
auto const logDir = uniqueLogDir();
for (auto _ : state) {
state.PauseTiming();
std::filesystem::create_directories(logDir);
static constexpr size_t kQUEUE_SIZE = 8192;
static constexpr size_t kTHREAD_COUNT = 1;
spdlog::init_thread_pool(kQUEUE_SIZE, kTHREAD_COUNT);
auto fileSink = BenchmarkLoggingInitializer::createFileSink({
.logDir = logDir,
.rotationSizeMB = 5,
.dirMaxFiles = 25,
});
std::vector<std::thread> threads;
threads.reserve(numThreads);
std::chrono::high_resolution_clock::time_point start;
std::barrier barrier(numThreads, [&state, &start]() {
state.ResumeTiming();
start = std::chrono::high_resolution_clock::now();
});
for (size_t threadNum = 0; threadNum < numThreads; ++threadNum) {
threads.emplace_back([threadNum, messagesPerThread, fileSink, &barrier]() {
std::string const channel = fmt::format("Thread_{}", threadNum);
auto logger = std::make_shared<spdlog::async_logger>(
channel, fileSink, spdlog::thread_pool(), spdlog::async_overflow_policy::block
);
spdlog::register_logger(logger);
Logger const threadLogger =
BenchmarkLoggingInitializer::getLogger(std::move(logger));
barrier.arrive_and_wait();
for (size_t messageNum = 0; messageNum < messagesPerThread; ++messageNum) {
LOG(threadLogger.info()) << "Test log message #" << messageNum;
}
});
}
for (auto& thread : threads) {
thread.join();
}
spdlog::shutdown();
auto const end = std::chrono::high_resolution_clock::now();
state.SetIterationTime(
std::chrono::duration_cast<std::chrono::duration<double>>(end - start).count()
);
std::filesystem::remove_all(logDir);
}
auto const totalMessages = numThreads * messagesPerThread;
state.counters["TotalMessagesRate"] =
benchmark::Counter(totalMessages, benchmark::Counter::kIsRate);
state.counters["Threads"] = numThreads;
state.counters["MessagesPerThread"] = messagesPerThread;
}
// One line of log message is around 110 bytes
// So, 100K messages is around 10.5MB
BENCHMARK(benchmarkConcurrentFileLogging)
->ArgsProduct({
// Number of threads
{1, 2, 4, 8},
// Messages per thread
{10'000, 100'000, 500'000, 1'000'000, 10'000'000},
})
->UseManualTime()
->Unit(benchmark::kMillisecond);

View File

@@ -49,6 +49,8 @@ postprocessors = [
] ]
# render body even when there are no releases to process # render body even when there are no releases to process
# render_always = true # render_always = true
# output file path
output = "CHANGELOG.md"
[git] [git]
# parse the commits based on https://www.conventionalcommits.org # parse the commits based on https://www.conventionalcommits.org

View File

@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/* /*
This file is part of clio: https://github.com/XRPLF/clio This file is part of clio: https://github.com/XRPLF/clio
Copyright (c) 2025, the clio developers. Copyright (c) 2022, the clio developers.
Permission to use, copy, modify, and distribute this software for any Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above
@@ -17,27 +17,26 @@
*/ */
//============================================================================== //==============================================================================
#pragma once #include "util/build/Build.hpp"
#include "util/StringBuffer.hpp"
#include <ostream>
#include <string> #include <string>
class LoggerBuffer { namespace util::build {
public:
std::string
getStrAndReset()
{
return buffer_.getStrAndReset();
}
std::ostream& static constexpr char versionString[] = "@CLIO_VERSION@"; // NOLINT(readability-identifier-naming)
getStream()
{
return stream_;
}
private: std::string const&
StringBuffer buffer_; getClioVersionString()
std::ostream stream_ = std::ostream{&buffer_}; {
}; static std::string const value = versionString; // NOLINT(readability-identifier-naming)
return value;
}
std::string const&
getClioFullVersionString()
{
static std::string const value = "clio-" + getClioVersionString(); // NOLINT(readability-identifier-naming)
return value;
}
} // namespace util::build

View File

@@ -1,5 +1,5 @@
find_program(CCACHE_PATH "ccache") find_program(CCACHE_PATH "ccache")
if(CCACHE_PATH) if (CCACHE_PATH)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}") set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}")
message(STATUS "Using ccache: ${CCACHE_PATH}") message(STATUS "Using ccache: ${CCACHE_PATH}")
endif() endif ()

View File

@@ -1,48 +1,42 @@
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16)
message(FATAL_ERROR "Clang 16+ required for building clio") message(FATAL_ERROR "Clang 16+ required for building clio")
endif() endif ()
set(is_clang TRUE) set(is_clang TRUE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 15)
message(FATAL_ERROR "AppleClang 15+ required for building clio") message(FATAL_ERROR "AppleClang 15+ required for building clio")
endif() endif ()
set(is_appleclang TRUE) set(is_appleclang TRUE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12) if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12)
message(FATAL_ERROR "GCC 12+ required for building clio") message(FATAL_ERROR "GCC 12+ required for building clio")
endif() endif ()
set(is_gcc TRUE) set(is_gcc TRUE)
else() else ()
message( message(FATAL_ERROR "Supported compilers: AppleClang 15+, Clang 16+, GCC 12+")
FATAL_ERROR endif ()
"Supported compilers: AppleClang 15+, Clang 16+, GCC 12+"
)
endif()
if(san) if (san)
string(TOLOWER ${san} san) string(TOLOWER ${san} san)
set(SAN_FLAG "-fsanitize=${san}") set(SAN_FLAG "-fsanitize=${san}")
set(SAN_LIB "") set(SAN_LIB "")
if(is_gcc) if (is_gcc)
if(san STREQUAL "address") if (san STREQUAL "address")
set(SAN_LIB "asan") set(SAN_LIB "asan")
elseif(san STREQUAL "thread") elseif (san STREQUAL "thread")
set(SAN_LIB "tsan") set(SAN_LIB "tsan")
elseif(san STREQUAL "memory") elseif (san STREQUAL "memory")
set(SAN_LIB "msan") set(SAN_LIB "msan")
elseif(san STREQUAL "undefined") elseif (san STREQUAL "undefined")
set(SAN_LIB "ubsan") set(SAN_LIB "ubsan")
endif() endif ()
endif() endif ()
set(_saved_CRL ${CMAKE_REQUIRED_LIBRARIES}) set(_saved_CRL ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES "${SAN_FLAG};${SAN_LIB}") set(CMAKE_REQUIRED_LIBRARIES "${SAN_FLAG};${SAN_LIB}")
check_cxx_compiler_flag(${SAN_FLAG} COMPILER_SUPPORTS_SAN) check_cxx_compiler_flag(${SAN_FLAG} COMPILER_SUPPORTS_SAN)
set(CMAKE_REQUIRED_LIBRARIES ${_saved_CRL}) set(CMAKE_REQUIRED_LIBRARIES ${_saved_CRL})
if(NOT COMPILER_SUPPORTS_SAN) if (NOT COMPILER_SUPPORTS_SAN)
message( message(FATAL_ERROR "${san} sanitizer does not seem to be supported by your compiler")
FATAL_ERROR endif ()
"${san} sanitizer does not seem to be supported by your compiler" endif ()
)
endif()
endif()

View File

@@ -1,41 +1,33 @@
if(lint) if (lint)
# Find clang-tidy binary
if(DEFINED ENV{CLIO_CLANG_TIDY_BIN})
set(_CLANG_TIDY_BIN $ENV{CLIO_CLANG_TIDY_BIN})
if((NOT EXISTS ${_CLANG_TIDY_BIN}) OR IS_DIRECTORY ${_CLANG_TIDY_BIN})
message(
FATAL_ERROR
"$ENV{CLIO_CLANG_TIDY_BIN} no such file. Check CLIO_CLANG_TIDY_BIN env variable"
)
endif()
message(STATUS "Using clang-tidy from CLIO_CLANG_TIDY_BIN")
else()
find_program(
_CLANG_TIDY_BIN
NAMES "clang-tidy-20" "clang-tidy"
REQUIRED
)
endif()
if(NOT _CLANG_TIDY_BIN) # Find clang-tidy binary
if (DEFINED ENV{CLIO_CLANG_TIDY_BIN})
set(_CLANG_TIDY_BIN $ENV{CLIO_CLANG_TIDY_BIN})
if ((NOT EXISTS ${_CLANG_TIDY_BIN}) OR IS_DIRECTORY ${_CLANG_TIDY_BIN})
message(FATAL_ERROR "$ENV{CLIO_CLANG_TIDY_BIN} no such file. Check CLIO_CLANG_TIDY_BIN env variable")
endif ()
message(STATUS "Using clang-tidy from CLIO_CLANG_TIDY_BIN")
else ()
find_program(_CLANG_TIDY_BIN NAMES "clang-tidy-19" "clang-tidy" REQUIRED)
endif ()
if (NOT _CLANG_TIDY_BIN)
message( message(
FATAL_ERROR FATAL_ERROR
"clang-tidy binary not found. Please set the CLIO_CLANG_TIDY_BIN environment variable or install clang-tidy." "clang-tidy binary not found. Please set the CLIO_CLANG_TIDY_BIN environment variable or install clang-tidy."
) )
endif() endif ()
# Support for https://github.com/matus-chochlik/ctcache # Support for https://github.com/matus-chochlik/ctcache
find_program(CLANG_TIDY_CACHE_PATH NAMES "clang-tidy-cache") find_program(CLANG_TIDY_CACHE_PATH NAMES "clang-tidy-cache")
if(CLANG_TIDY_CACHE_PATH) if (CLANG_TIDY_CACHE_PATH)
set(_CLANG_TIDY_CMD set(_CLANG_TIDY_CMD "${CLANG_TIDY_CACHE_PATH};${_CLANG_TIDY_BIN}"
"${CLANG_TIDY_CACHE_PATH};${_CLANG_TIDY_BIN}" CACHE STRING "A combined command to run clang-tidy with caching wrapper"
CACHE STRING
"A combined command to run clang-tidy with caching wrapper"
) )
else() else ()
set(_CLANG_TIDY_CMD "${_CLANG_TIDY_BIN}") set(_CLANG_TIDY_CMD "${_CLANG_TIDY_BIN}")
endif() endif ()
set(CMAKE_CXX_CLANG_TIDY "${_CLANG_TIDY_CMD};--quiet") set(CMAKE_CXX_CLANG_TIDY "${_CLANG_TIDY_CMD};--quiet")
message(STATUS "Using clang-tidy: ${CMAKE_CXX_CLANG_TIDY}") message(STATUS "Using clang-tidy: ${CMAKE_CXX_CLANG_TIDY}")
endif() endif ()

View File

@@ -1,8 +0,0 @@
include("${CMAKE_CURRENT_LIST_DIR}/ClioVersion.cmake")
set(CPACK_PACKAGING_INSTALL_PREFIX "/opt/clio")
set(CPACK_PACKAGE_VERSION "${CLIO_VERSION}")
set(CPACK_STRIP_FILES TRUE)
include(pkg/deb)
include(CPack)

View File

@@ -1,67 +1,48 @@
#[===================================================================[
write version to source
#]===================================================================]
find_package(Git REQUIRED) find_package(Git REQUIRED)
if(DEFINED ENV{GITHUB_BRANCH_NAME}) set(GIT_COMMAND rev-parse --short HEAD)
set(GIT_BUILD_BRANCH $ENV{GITHUB_BRANCH_NAME})
set(GIT_COMMIT_HASH $ENV{GITHUB_HEAD_SHA})
else()
set(GIT_COMMAND branch --show-current)
execute_process(
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BUILD_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY
)
set(GIT_COMMAND rev-parse HEAD)
execute_process(
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY
)
endif()
execute_process( execute_process(
COMMAND date +%Y%m%d%H%M%S COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE REV
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE BUILD_DATE
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_STRIP_TRAILING_WHITESPACE
COMMAND_ERROR_IS_FATAL ANY
) )
message(STATUS "Git branch: ${GIT_BUILD_BRANCH}") set(GIT_COMMAND branch --show-current)
message(STATUS "Git commit hash: ${GIT_COMMIT_HASH}") execute_process(
message(STATUS "Build date: ${BUILD_DATE}") COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE
if(
DEFINED ENV{FORCE_CLIO_VERSION}
AND NOT "$ENV{FORCE_CLIO_VERSION}" STREQUAL ""
) )
message(
STATUS
"Using explicitly provided '${FORCE_CLIO_VERSION}' as Clio version"
)
set(CLIO_VERSION "$ENV{FORCE_CLIO_VERSION}") if (BRANCH STREQUAL "")
set(DOC_CLIO_VERSION "$ENV{FORCE_CLIO_VERSION}") set(BRANCH "dev")
else() endif ()
message(
STATUS
"Using 'YYYYMMDDHMS-<branch>-<git short rev>' as Clio version"
)
string(SUBSTRING ${GIT_COMMIT_HASH} 0 7 GIT_COMMIT_HASH_SHORT) if (NOT (BRANCH MATCHES master OR BRANCH MATCHES release/*)) # for develop and any other branch name
# YYYYMMDDHMS-<branch>-<git-rev>
set(CLIO_VERSION set(GIT_COMMAND show -s --date=format:%Y%m%d%H%M%S --format=%cd)
"${BUILD_DATE}-${GIT_BUILD_BRANCH}-${GIT_COMMIT_HASH_SHORT}" execute_process(
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE DATE
OUTPUT_STRIP_TRAILING_WHITESPACE
) )
set(CLIO_VERSION "${DATE}-${BRANCH}-${REV}")
set(DOC_CLIO_VERSION "develop") set(DOC_CLIO_VERSION "develop")
endif() else ()
set(GIT_COMMAND describe --tags)
execute_process(
COMMAND ${GIT_EXECUTABLE} ${GIT_COMMAND} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE CLIO_TAG_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(CLIO_VERSION "${CLIO_TAG_VERSION}")
set(DOC_CLIO_VERSION "${CLIO_TAG_VERSION}")
endif ()
if(CMAKE_BUILD_TYPE MATCHES Debug) if (CMAKE_BUILD_TYPE MATCHES Debug)
set(CLIO_VERSION "${CLIO_VERSION}+DEBUG") set(CLIO_VERSION "${CLIO_VERSION}+DEBUG")
endif() endif ()
message(STATUS "Build version: ${CLIO_VERSION}") message(STATUS "Build version: ${CLIO_VERSION}")
configure_file(${CMAKE_CURRENT_LIST_DIR}/Build.cpp.in ${CMAKE_CURRENT_LIST_DIR}/../src/util/build/Build.cpp)

View File

@@ -106,120 +106,78 @@ option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE)
# Check prereqs # Check prereqs
find_program(GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) find_program(GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
if(DEFINED CODE_COVERAGE_GCOV_TOOL) if (DEFINED CODE_COVERAGE_GCOV_TOOL)
set(GCOV_TOOL "${CODE_COVERAGE_GCOV_TOOL}") set(GCOV_TOOL "${CODE_COVERAGE_GCOV_TOOL}")
elseif(DEFINED ENV{CODE_COVERAGE_GCOV_TOOL}) elseif (DEFINED ENV{CODE_COVERAGE_GCOV_TOOL})
set(GCOV_TOOL "$ENV{CODE_COVERAGE_GCOV_TOOL}") set(GCOV_TOOL "$ENV{CODE_COVERAGE_GCOV_TOOL}")
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
if(APPLE) if (APPLE)
execute_process( execute_process(COMMAND xcrun -f llvm-cov OUTPUT_VARIABLE LLVMCOV_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
COMMAND xcrun -f llvm-cov else ()
OUTPUT_VARIABLE LLVMCOV_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else()
find_program(LLVMCOV_PATH llvm-cov) find_program(LLVMCOV_PATH llvm-cov)
endif() endif ()
if(LLVMCOV_PATH) if (LLVMCOV_PATH)
set(GCOV_TOOL "${LLVMCOV_PATH} gcov") set(GCOV_TOOL "${LLVMCOV_PATH} gcov")
endif() endif ()
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
find_program(GCOV_PATH gcov) find_program(GCOV_PATH gcov)
set(GCOV_TOOL "${GCOV_PATH}") set(GCOV_TOOL "${GCOV_PATH}")
endif() endif ()
# Check supported compiler (Clang, GNU and Flang) # Check supported compiler (Clang, GNU and Flang)
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(LANG ${LANGUAGES}) foreach (LANG ${LANGUAGES})
if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") if ("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3) if ("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3)
message( message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
FATAL_ERROR endif ()
"Clang version must be 3.0.0 or greater! Aborting..." elseif (NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU" AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES
) "(LLVM)?[Ff]lang"
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...") message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...")
endif() endif ()
endforeach() endforeach ()
set(COVERAGE_COMPILER_FLAGS "-g --coverage" CACHE INTERNAL "") set(COVERAGE_COMPILER_FLAGS "-g --coverage" CACHE INTERNAL "")
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") if (CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path) check_cxx_compiler_flag(-fprofile-abs-path HAVE_cxx_fprofile_abs_path)
if(HAVE_cxx_fprofile_abs_path) if (HAVE_cxx_fprofile_abs_path)
set(COVERAGE_CXX_COMPILER_FLAGS set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
"${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path" endif ()
)
endif()
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path) check_c_compiler_flag(-fprofile-abs-path HAVE_c_fprofile_abs_path)
if(HAVE_c_fprofile_abs_path) if (HAVE_c_fprofile_abs_path)
set(COVERAGE_C_COMPILER_FLAGS set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path")
"${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path" endif ()
) endif ()
endif()
endif()
set(CMAKE_Fortran_FLAGS_COVERAGE set(CMAKE_Fortran_FLAGS_COVERAGE ${COVERAGE_COMPILER_FLAGS}
${COVERAGE_COMPILER_FLAGS} CACHE STRING "Flags used by the Fortran compiler during coverage builds." FORCE
CACHE STRING
"Flags used by the Fortran compiler during coverage builds."
FORCE
) )
set(CMAKE_CXX_FLAGS_COVERAGE set(CMAKE_CXX_FLAGS_COVERAGE ${COVERAGE_COMPILER_FLAGS}
${COVERAGE_COMPILER_FLAGS} CACHE STRING "Flags used by the C++ compiler during coverage builds." FORCE
CACHE STRING
"Flags used by the C++ compiler during coverage builds."
FORCE
) )
set(CMAKE_C_FLAGS_COVERAGE set(CMAKE_C_FLAGS_COVERAGE ${COVERAGE_COMPILER_FLAGS}
${COVERAGE_COMPILER_FLAGS} CACHE STRING "Flags used by the C compiler during coverage builds." FORCE
CACHE STRING
"Flags used by the C compiler during coverage builds."
FORCE
) )
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE 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 CACHE STRING "Flags used by the shared libraries linker during coverage builds." FORCE
"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( mark_as_advanced(
CMAKE_Fortran_FLAGS_COVERAGE CMAKE_Fortran_FLAGS_COVERAGE CMAKE_CXX_FLAGS_COVERAGE CMAKE_C_FLAGS_COVERAGE CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE CMAKE_SHARED_LINKER_FLAGS_COVERAGE
) )
get_property( get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
GENERATOR_IS_MULTI_CONFIG if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG))
GLOBAL message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
PROPERTY GENERATOR_IS_MULTI_CONFIG endif () # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR 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( if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
CMAKE_C_COMPILER_ID STREQUAL "GNU"
OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU"
)
link_libraries(gcov) link_libraries(gcov)
endif() endif ()
# Defines a target for running and collection code coverage information Builds dependencies, runs the given executable # 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 # and outputs reports. NOTE! The executable should always have a ZERO as exit code otherwise the coverage generation
@@ -233,145 +191,108 @@ endif()
# defaults to xml) EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative # to BASE_DIRECTORY, # 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 # with CMake 3.4+) ) The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the GCVOR
# command. # command.
function(setup_target_for_coverage_gcovr) function (setup_target_for_coverage_gcovr)
set(options NONE) set(options NONE)
set(oneValueArgs BASE_DIRECTORY NAME FORMAT) set(oneValueArgs BASE_DIRECTORY NAME FORMAT)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments( cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
Coverage
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
if(NOT GCOV_TOOL) if (NOT GCOV_TOOL)
message(FATAL_ERROR "Could not find gcov or llvm-cov tool! Aborting...") message(FATAL_ERROR "Could not find gcov or llvm-cov tool! Aborting...")
endif() endif ()
if(NOT GCOVR_PATH) if (NOT GCOVR_PATH)
message(FATAL_ERROR "Could not find gcovr tool! Aborting...") message(FATAL_ERROR "Could not find gcovr tool! Aborting...")
endif() endif ()
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
if(DEFINED Coverage_BASE_DIRECTORY) if (DEFINED Coverage_BASE_DIRECTORY)
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
else() else ()
set(BASEDIR ${PROJECT_SOURCE_DIR}) set(BASEDIR ${PROJECT_SOURCE_DIR})
endif() endif ()
if(NOT DEFINED Coverage_FORMAT) if (NOT DEFINED Coverage_FORMAT)
set(Coverage_FORMAT xml) set(Coverage_FORMAT xml)
endif() endif ()
if("--output" IN_LIST GCOVR_ADDITIONAL_ARGS) if ("--output" IN_LIST GCOVR_ADDITIONAL_ARGS)
message( message(FATAL_ERROR "Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting...")
FATAL_ERROR else ()
"Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting..." if ((Coverage_FORMAT STREQUAL "html-details") OR (Coverage_FORMAT STREQUAL "html-nested"))
) set(GCOVR_OUTPUT_FILE ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html)
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}) set(GCOVR_CREATE_FOLDER ${PROJECT_BINARY_DIR}/${Coverage_NAME})
elseif(Coverage_FORMAT STREQUAL "html-single") elseif (Coverage_FORMAT STREQUAL "html-single")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.html) set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.html)
elseif( elseif ((Coverage_FORMAT STREQUAL "json-summary") OR (Coverage_FORMAT STREQUAL "json-details")
(Coverage_FORMAT STREQUAL "json-summary")
OR (Coverage_FORMAT STREQUAL "json-details")
OR (Coverage_FORMAT STREQUAL "coveralls") OR (Coverage_FORMAT STREQUAL "coveralls")
) )
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.json) set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.json)
elseif(Coverage_FORMAT STREQUAL "txt") elseif (Coverage_FORMAT STREQUAL "txt")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.txt) set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.txt)
elseif(Coverage_FORMAT STREQUAL "csv") elseif (Coverage_FORMAT STREQUAL "csv")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.csv) set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.csv)
else() else ()
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.xml) set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.xml)
endif() endif ()
endif() endif ()
if( if ((Coverage_FORMAT STREQUAL "cobertura") OR (Coverage_FORMAT STREQUAL "xml"))
(Coverage_FORMAT STREQUAL "cobertura")
OR (Coverage_FORMAT STREQUAL "xml")
)
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}")
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura-pretty) list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura-pretty)
set(Coverage_FORMAT cobertura) # overwrite xml set(Coverage_FORMAT cobertura) # overwrite xml
elseif(Coverage_FORMAT STREQUAL "sonarqube") elseif (Coverage_FORMAT STREQUAL "sonarqube")
list(APPEND GCOVR_ADDITIONAL_ARGS --sonarqube "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --sonarqube "${GCOVR_OUTPUT_FILE}")
elseif(Coverage_FORMAT STREQUAL "json-summary") elseif (Coverage_FORMAT STREQUAL "json-summary")
list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary "${GCOVR_OUTPUT_FILE}")
list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary-pretty) list(APPEND GCOVR_ADDITIONAL_ARGS --json-summary-pretty)
elseif(Coverage_FORMAT STREQUAL "json-details") elseif (Coverage_FORMAT STREQUAL "json-details")
list(APPEND GCOVR_ADDITIONAL_ARGS --json "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --json "${GCOVR_OUTPUT_FILE}")
list(APPEND GCOVR_ADDITIONAL_ARGS --json-pretty) list(APPEND GCOVR_ADDITIONAL_ARGS --json-pretty)
elseif(Coverage_FORMAT STREQUAL "coveralls") elseif (Coverage_FORMAT STREQUAL "coveralls")
list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls "${GCOVR_OUTPUT_FILE}")
list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls-pretty) list(APPEND GCOVR_ADDITIONAL_ARGS --coveralls-pretty)
elseif(Coverage_FORMAT STREQUAL "csv") elseif (Coverage_FORMAT STREQUAL "csv")
list(APPEND GCOVR_ADDITIONAL_ARGS --csv "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --csv "${GCOVR_OUTPUT_FILE}")
elseif(Coverage_FORMAT STREQUAL "txt") elseif (Coverage_FORMAT STREQUAL "txt")
list(APPEND GCOVR_ADDITIONAL_ARGS --txt "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --txt "${GCOVR_OUTPUT_FILE}")
elseif(Coverage_FORMAT STREQUAL "html-single") elseif (Coverage_FORMAT STREQUAL "html-single")
list(APPEND GCOVR_ADDITIONAL_ARGS --html "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --html "${GCOVR_OUTPUT_FILE}")
list(APPEND GCOVR_ADDITIONAL_ARGS --html-self-contained) list(APPEND GCOVR_ADDITIONAL_ARGS --html-self-contained)
elseif(Coverage_FORMAT STREQUAL "html-nested") elseif (Coverage_FORMAT STREQUAL "html-nested")
list(APPEND GCOVR_ADDITIONAL_ARGS --html-nested "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --html-nested "${GCOVR_OUTPUT_FILE}")
elseif(Coverage_FORMAT STREQUAL "html-details") elseif (Coverage_FORMAT STREQUAL "html-details")
list(APPEND GCOVR_ADDITIONAL_ARGS --html-details "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --html-details "${GCOVR_OUTPUT_FILE}")
else() else ()
message( message(FATAL_ERROR "Unsupported output style ${Coverage_FORMAT}! Aborting...")
FATAL_ERROR endif ()
"Unsupported output style ${Coverage_FORMAT}! Aborting..."
)
endif()
# Collect excludes (CMake 3.4+: Also compute absolute paths) # Collect excludes (CMake 3.4+: Also compute absolute paths)
set(GCOVR_EXCLUDES "") set(GCOVR_EXCLUDES "")
foreach( foreach (EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES})
EXCLUDE if (CMAKE_VERSION VERSION_GREATER 3.4)
${Coverage_EXCLUDE} get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
${COVERAGE_EXCLUDES} endif ()
${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}") list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
endforeach() endforeach ()
list(REMOVE_DUPLICATES GCOVR_EXCLUDES) list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
# Combine excludes to several -e arguments # Combine excludes to several -e arguments
set(GCOVR_EXCLUDE_ARGS "") set(GCOVR_EXCLUDE_ARGS "")
foreach(EXCLUDE ${GCOVR_EXCLUDES}) foreach (EXCLUDE ${GCOVR_EXCLUDES})
list(APPEND GCOVR_EXCLUDE_ARGS "-e") list(APPEND GCOVR_EXCLUDE_ARGS "-e")
list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}") list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
endforeach() endforeach ()
# Set up commands which will be run to generate coverage data Run tests # Set up commands which will be run to generate coverage data Run tests
set(GCOVR_EXEC_TESTS_CMD ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}) set(GCOVR_EXEC_TESTS_CMD ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS})
# Create folder # Create folder
if(DEFINED GCOVR_CREATE_FOLDER) if (DEFINED GCOVR_CREATE_FOLDER)
set(GCOVR_FOLDER_CMD set(GCOVR_FOLDER_CMD ${CMAKE_COMMAND} -E make_directory ${GCOVR_CREATE_FOLDER})
${CMAKE_COMMAND} else ()
-E
make_directory
${GCOVR_CREATE_FOLDER}
)
else()
set(GCOVR_FOLDER_CMD echo) # dummy set(GCOVR_FOLDER_CMD echo) # dummy
endif() endif ()
# Running gcovr # Running gcovr
set(GCOVR_CMD set(GCOVR_CMD
@@ -386,33 +307,23 @@ function(setup_target_for_coverage_gcovr)
--object-directory=${PROJECT_BINARY_DIR} --object-directory=${PROJECT_BINARY_DIR}
) )
if(CODE_COVERAGE_VERBOSE) if (CODE_COVERAGE_VERBOSE)
message(STATUS "Executed command report") message(STATUS "Executed command report")
message(STATUS "Command to run tests: ") message(STATUS "Command to run tests: ")
string( string(REPLACE ";" " " GCOVR_EXEC_TESTS_CMD_SPACED "${GCOVR_EXEC_TESTS_CMD}")
REPLACE ";"
" "
GCOVR_EXEC_TESTS_CMD_SPACED
"${GCOVR_EXEC_TESTS_CMD}"
)
message(STATUS "${GCOVR_EXEC_TESTS_CMD_SPACED}") message(STATUS "${GCOVR_EXEC_TESTS_CMD_SPACED}")
if(NOT GCOVR_FOLDER_CMD STREQUAL "echo") if (NOT GCOVR_FOLDER_CMD STREQUAL "echo")
message(STATUS "Command to create a folder: ") message(STATUS "Command to create a folder: ")
string( string(REPLACE ";" " " GCOVR_FOLDER_CMD_SPACED "${GCOVR_FOLDER_CMD}")
REPLACE ";"
" "
GCOVR_FOLDER_CMD_SPACED
"${GCOVR_FOLDER_CMD}"
)
message(STATUS "${GCOVR_FOLDER_CMD_SPACED}") message(STATUS "${GCOVR_FOLDER_CMD_SPACED}")
endif() endif ()
message(STATUS "Command to generate gcovr coverage data: ") message(STATUS "Command to generate gcovr coverage data: ")
string(REPLACE ";" " " GCOVR_CMD_SPACED "${GCOVR_CMD}") string(REPLACE ";" " " GCOVR_CMD_SPACED "${GCOVR_CMD}")
message(STATUS "${GCOVR_CMD_SPACED}") message(STATUS "${GCOVR_CMD_SPACED}")
endif() endif ()
add_custom_target( add_custom_target(
${Coverage_NAME} ${Coverage_NAME}
@@ -428,41 +339,23 @@ function(setup_target_for_coverage_gcovr)
# Show info where to find the report # Show info where to find the report
add_custom_command( add_custom_command(
TARGET ${Coverage_NAME} TARGET ${Coverage_NAME} POST_BUILD COMMAND ;
POST_BUILD COMMENT "Code coverage report saved in ${GCOVR_OUTPUT_FILE} formatted as ${Coverage_FORMAT}"
COMMAND ;
COMMENT
"Code coverage report saved in ${GCOVR_OUTPUT_FILE} formatted as ${Coverage_FORMAT}"
) )
endfunction() # setup_target_for_coverage_gcovr endfunction () # setup_target_for_coverage_gcovr
function(append_coverage_compiler_flags) function (append_coverage_compiler_flags)
set(CMAKE_C_FLAGS set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
"${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
PARENT_SCOPE set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
) message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}")
set(CMAKE_CXX_FLAGS endfunction () # append_coverage_compiler_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 # Setup coverage for specific library
function(append_coverage_compiler_flags_to_target name mode) function (append_coverage_compiler_flags_to_target name mode)
separate_arguments(_flag_list NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}") separate_arguments(_flag_list NATIVE_COMMAND "${COVERAGE_COMPILER_FLAGS}")
target_compile_options(${name} ${mode} ${_flag_list}) target_compile_options(${name} ${mode} ${_flag_list})
if( if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
CMAKE_C_COMPILER_ID STREQUAL "GNU"
OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU"
)
target_link_libraries(${name} ${mode} gcov) target_link_libraries(${name} ${mode} gcov)
endif() endif ()
endfunction() endfunction ()

View File

@@ -1,11 +0,0 @@
if(DEFINED CMAKE_LINKER_TYPE)
message(STATUS "Custom linker is already set: ${CMAKE_LINKER_TYPE}")
return()
endif()
find_program(MOLD_PATH mold)
if(MOLD_PATH AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
message(STATUS "Using Mold linker: ${MOLD_PATH}")
set(CMAKE_LINKER_TYPE MOLD)
endif()

View File

@@ -30,29 +30,30 @@ set(COMPILER_FLAGS
# TODO: re-enable when we change CI #884 if (is_gcc AND NOT lint) list(APPEND COMPILER_FLAGS -Wduplicated-branches # TODO: re-enable when we change CI #884 if (is_gcc AND NOT lint) list(APPEND COMPILER_FLAGS -Wduplicated-branches
# -Wduplicated-cond -Wlogical-op -Wuseless-cast ) endif () # -Wduplicated-cond -Wlogical-op -Wuseless-cast ) endif ()
if(is_clang) if (is_clang)
# gcc is too aggressive with shadowing list(APPEND COMPILER_FLAGS -Wshadow # gcc is to aggressive with shadowing
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78147 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78147
list(APPEND COMPILER_FLAGS -Wshadow) )
endif() endif ()
if(is_appleclang) if (is_appleclang)
list(APPEND COMPILER_FLAGS -Wreorder-init-list) list(APPEND COMPILER_FLAGS -Wreorder-init-list)
endif() endif ()
if(san) if (san)
# When building with sanitizers some compilers will actually produce extra warnings/errors. We don't want this yet, # When building with sanitizers some compilers will actually produce extra warnings/errors. We don't want this yet, at
# at least not until we have fixed all runtime issues reported by the sanitizers. Once that is done we can start # least not until we have fixed all runtime issues reported by the sanitizers. Once that is done we can start removing
# removing some of these and trying to fix it in our codebase. We can never remove all of below because most of them # some of these and trying to fix it in our codebase. We can never remove all of below because most of them are
# are reported from deep inside libraries like boost or libxrpl. # reported from deep inside libraries like boost or libxrpl.
# #
# TODO: Address in https://github.com/XRPLF/clio/issues/1885 # TODO: Address in https://github.com/XRPLF/clio/issues/1885
list( list(
APPEND COMPILER_FLAGS APPEND
COMPILER_FLAGS
-Wno-error=tsan # Disables treating TSAN warnings as errors -Wno-error=tsan # Disables treating TSAN warnings as errors
-Wno-tsan # Disables TSAN warnings (thread-safety analysis) -Wno-tsan # Disables TSAN warnings (thread-safety analysis)
-Wno-uninitialized # Disables warnings about uninitialized variables (AddressSanitizer, -Wno-uninitialized # Disables warnings about uninitialized variables (AddressSanitizer, UndefinedBehaviorSanitizer,
# UndefinedBehaviorSanitizer, etc.) # etc.)
-Wno-stringop-overflow # Disables warnings about potential string operation overflows (AddressSanitizer) -Wno-stringop-overflow # Disables warnings about potential string operation overflows (AddressSanitizer)
-Wno-unsafe-buffer-usage # Disables warnings about unsafe memory operations (AddressSanitizer) -Wno-unsafe-buffer-usage # Disables warnings about unsafe memory operations (AddressSanitizer)
-Wno-frame-larger-than # Disables warnings about stack frame size being too large (AddressSanitizer) -Wno-frame-larger-than # Disables warnings about stack frame size being too large (AddressSanitizer)
@@ -65,23 +66,17 @@ if(san)
-Wno-address # Disables warnings about address-related issues (UndefinedBehaviorSanitizer) -Wno-address # Disables warnings about address-related issues (UndefinedBehaviorSanitizer)
-Wno-array-bounds # Disables array bounds checks (UndefinedBehaviorSanitizer) -Wno-array-bounds # Disables array bounds checks (UndefinedBehaviorSanitizer)
) )
endif() endif ()
# See https://github.com/cpp-best-practices/cppbestpractices/blob/master/02-Use_the_Tools_Available.md#gcc--clang for # See https://github.com/cpp-best-practices/cppbestpractices/blob/master/02-Use_the_Tools_Available.md#gcc--clang for
# the flags description # the flags description
if(time_trace) if (time_trace)
if(is_clang OR is_appleclang) if (is_clang OR is_appleclang)
list(APPEND COMPILER_FLAGS -ftime-trace) list(APPEND COMPILER_FLAGS -ftime-trace)
else() else ()
message( message(FATAL_ERROR "Clang or AppleClang is required to use `-ftime-trace`")
FATAL_ERROR endif ()
"Clang or AppleClang is required to use `-ftime-trace`" endif ()
)
endif()
endif()
target_compile_options(clio_options INTERFACE ${COMPILER_FLAGS}) target_compile_options(clio_options INTERFACE ${COMPILER_FLAGS})
# Add debug symbols for all builds, including Release. This is needed to get useful stack traces in production.
target_compile_options(clio_options INTERFACE -g)

View File

@@ -1,17 +1,11 @@
include(CheckIncludeFileCXX) include(CheckIncludeFileCXX)
check_include_file_cxx("source_location" SOURCE_LOCATION_AVAILABLE) check_include_file_cxx("source_location" SOURCE_LOCATION_AVAILABLE)
if(SOURCE_LOCATION_AVAILABLE) if (SOURCE_LOCATION_AVAILABLE)
target_compile_definitions(clio_options INTERFACE "HAS_SOURCE_LOCATION") target_compile_definitions(clio_options INTERFACE "HAS_SOURCE_LOCATION")
endif() endif ()
check_include_file_cxx( check_include_file_cxx("experimental/source_location" EXPERIMENTAL_SOURCE_LOCATION_AVAILABLE)
"experimental/source_location" if (EXPERIMENTAL_SOURCE_LOCATION_AVAILABLE)
EXPERIMENTAL_SOURCE_LOCATION_AVAILABLE target_compile_definitions(clio_options INTERFACE "HAS_EXPERIMENTAL_SOURCE_LOCATION")
) endif ()
if(EXPERIMENTAL_SOURCE_LOCATION_AVAILABLE)
target_compile_definitions(
clio_options
INTERFACE "HAS_EXPERIMENTAL_SOURCE_LOCATION"
)
endif()

View File

@@ -1,10 +1,4 @@
set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON) set(Boost_USE_STATIC_RUNTIME ON)
find_package( find_package(Boost 1.82 REQUIRED CONFIG COMPONENTS program_options coroutine system log log_setup)
Boost
1.82
REQUIRED
CONFIG
COMPONENTS program_options coroutine system log log_setup
)

View File

@@ -1,6 +1,3 @@
find_package(OpenSSL 1.1.1 REQUIRED CONFIG) find_package(OpenSSL 1.1.1 REQUIRED CONFIG)
set_target_properties( set_target_properties(OpenSSL::SSL PROPERTIES INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2)
OpenSSL::SSL
PROPERTIES INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
)

View File

@@ -1,14 +1,11 @@
if("${san}" STREQUAL "") if ("${san}" STREQUAL "")
target_compile_definitions(clio_options INTERFACE BOOST_STACKTRACE_LINK) target_compile_definitions(clio_options INTERFACE BOOST_STACKTRACE_LINK)
target_compile_definitions( target_compile_definitions(clio_options INTERFACE BOOST_STACKTRACE_USE_BACKTRACE)
clio_options
INTERFACE BOOST_STACKTRACE_USE_BACKTRACE
)
find_package(libbacktrace REQUIRED CONFIG) find_package(libbacktrace REQUIRED CONFIG)
else() else ()
# Some sanitizers (TSAN and ASAN for sure) can't be used with libbacktrace because they have their own backtracing # Some sanitizers (TSAN and ASAN for sure) can't be used with libbacktrace because they have their own backtracing
# capabilities and there are conflicts. In any case, this makes sure Clio code knows that backtrace is not # capabilities and there are conflicts. In any case, this makes sure Clio code knows that backtrace is not available.
# available. See relevant conan profiles for sanitizers where we disable stacktrace in Boost explicitly. # See relevant conan profiles for sanitizers where we disable stacktrace in Boost explicitly.
target_compile_definitions(clio_options INTERFACE CLIO_WITHOUT_STACKTRACE) target_compile_definitions(clio_options INTERFACE CLIO_WITHOUT_STACKTRACE)
message(STATUS "Sanitizer enabled, disabling stacktrace") message(STATUS "Sanitizer enabled, disabling stacktrace")
endif() endif ()

View File

@@ -1,5 +0,0 @@
find_package(spdlog REQUIRED)
if(NOT TARGET spdlog::spdlog)
message(FATAL_ERROR "spdlog::spdlog target not found")
endif()

View File

@@ -1,31 +1,13 @@
set(CLIO_INSTALL_DIR "/opt/clio") set(CLIO_INSTALL_DIR "/opt/clio")
set(CMAKE_INSTALL_PREFIX set(CMAKE_INSTALL_PREFIX ${CLIO_INSTALL_DIR})
"${CLIO_INSTALL_DIR}"
CACHE PATH
"Install prefix"
FORCE
)
set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") install(TARGETS clio_server DESTINATION bin)
include(GNUInstallDirs)
install(TARGETS clio_server DESTINATION "${CMAKE_INSTALL_BINDIR}")
file(READ docs/examples/config/example-config.json config) file(READ docs/examples/config/example-config.json config)
string(REGEX REPLACE "./clio_log" "/var/log/clio/" config "${config}") string(REGEX REPLACE "./clio_log" "/var/log/clio/" config "${config}")
file(WRITE ${CMAKE_BINARY_DIR}/install-config.json "${config}") file(WRITE ${CMAKE_BINARY_DIR}/install-config.json "${config}")
install( install(FILES ${CMAKE_BINARY_DIR}/install-config.json DESTINATION etc RENAME config.json)
FILES ${CMAKE_BINARY_DIR}/install-config.json
DESTINATION etc
RENAME config.json
)
configure_file( configure_file("${CMAKE_SOURCE_DIR}/cmake/install/clio.service.in" "${CMAKE_BINARY_DIR}/clio.service")
"${CMAKE_SOURCE_DIR}/cmake/install/clio.service.in"
"${CMAKE_BINARY_DIR}/clio.service" install(FILES "${CMAKE_BINARY_DIR}/clio.service" DESTINATION /lib/systemd/system)
)
install(
FILES "${CMAKE_BINARY_DIR}/clio.service"
DESTINATION /lib/systemd/system
)

View File

@@ -1,12 +0,0 @@
set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/XRPLF/clio")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Ripple Labs Inc. <support@ripple.com>")
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA ${CMAKE_SOURCE_DIR}/cmake/pkg/postinst)
# We must replace "-" with "~" otherwise dpkg will sort "X.Y.Z-b1" as greater than "X.Y.Z"
string(REPLACE "-" "~" git "${CPACK_PACKAGE_VERSION}")

View File

@@ -1,45 +0,0 @@
#!/bin/sh
set -e
USER_NAME=clio
GROUP_NAME="${USER_NAME}"
CLIO_EXECUTABLE="clio_server"
CLIO_PREFIX="/opt/clio"
CLIO_BIN="$CLIO_PREFIX/bin/${CLIO_EXECUTABLE}"
CLIO_CONFIG="$CLIO_PREFIX/etc/config.json"
case "$1" in
configure)
if ! id -u "$USER_NAME" >/dev/null 2>&1; then
# Users who should not have a home directory should have their home directory set to /nonexistent
# https://www.debian.org/doc/debian-policy/ch-opersys.html#non-existent-home-directories
useradd \
--system \
--home-dir /nonexistent \
--no-create-home \
--shell /usr/sbin/nologin \
--comment "system user for ${CLIO_EXECUTABLE}" \
--user-group \
${USER_NAME}
fi
install -d -o "$USER_NAME" -g "$GROUP_NAME" /var/log/clio
if [ -f "$CLIO_CONFIG" ]; then
chown "$USER_NAME:$GROUP_NAME" "$CLIO_CONFIG"
fi
chown -R "$USER_NAME:$GROUP_NAME" "$CLIO_PREFIX"
ln -sf "$CLIO_BIN" "/usr/bin/${CLIO_EXECUTABLE}"
;;
abort-upgrade | abort-remove | abort-deconfigure) ;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0

View File

@@ -1,61 +1,56 @@
{ {
"version": "0.5", "version": "0.5",
"requires": [ "requires": [
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075", "zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1750263732.782",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987", "xxhash/0.8.2#7856c968c985b2981b707ee8f2413b2b%1750263730.908",
"xrpl/3.1.0#3d408ab8c8020014fa7dd52bc7cc7ea8%1769706825.165", "xrpl/2.5.0-rc1#e5897e048ea5712d2c71561c507d949d%1750263725.455",
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1765850149.926", "sqlite3/3.47.0#7a0904fd061f5f8a2366c294f9387830%1750263721.79",
"spdlog/1.17.0#bcbaaf7147bda6ad24ffbd1ac3d7142c%1768312128.781", "soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1750263717.455",
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1765850149.46", "re2/20230301#dfd6e2bf050eb90ddd8729cfb4c844a4%1750263715.145",
"re2/20230301#ca3b241baec15bd31ea9187150e0b333%1765850148.103", "rapidjson/cci.20220822#1b9d8c2256876a154172dc5cfbe447c6%1750263713.526",
"rapidjson/cci.20220822#1b9d8c2256876a154172dc5cfbe447c6%1754325007.656", "protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1750263698.841",
"protobuf/3.21.12#44ee56c0a6eea0c19aeeaca680370b88%1764175361.456", "openssl/1.1.1v#216374e4fb5b2e0f5ab1fb6f27b5b434%1750263685.885",
"openssl/1.1.1w#a8f0792d7c5121b954578a7149d23e03%1756223730.729", "nudb/2.0.8#63990d3e517038e04bf529eb8167f69f%1750263683.814",
"nudb/2.0.9#0432758a24204da08fee953ec9ea03cb%1769436073.32", "minizip/1.2.13#9e87d57804bd372d6d1e32b1871517a3%1750263681.745",
"minizip/1.2.13#9e87d57804bd372d6d1e32b1871517a3%1754325004.374", "lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1750263679.891",
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914", "libuv/1.46.0#78565d142ac7102776256328a26cdf60%1750263677.819",
"libuv/1.46.0#dc28c1f653fa197f00db5b577a6f6011%1754325003.592", "libiconv/1.17#1ae2f60ab5d08de1643a22a81b360c59%1750257497.552",
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492", "libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1750263675.748",
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03", "libarchive/3.7.6#e0453864b2a4d225f06b3304903cb2b7%1750263671.05",
"libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1765850144.736", "http_parser/2.9.4#98d91690d6fd021e9e624218a85d9d97%1750263668.751",
"http_parser/2.9.4#98d91690d6fd021e9e624218a85d9d97%1754325001.385", "gtest/1.14.0#f8f0757a574a8dd747d16af62d6eb1b7%1750263666.833",
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152", "grpc/1.50.1#02291451d1e17200293a409410d1c4e1%1750263646.614",
"grpc/1.50.1#02291451d1e17200293a409410d1c4e1%1756234248.958", "fmt/10.1.1#021e170cf81db57da82b5f737b6906c1%1750263644.741",
"fmt/12.1.0#50abab23274d56bb8f42c94b3b9a40c7%1763984116.926", "date/3.0.3#cf28fe9c0aab99fe12da08aa42df65e1%1750263643.099",
"doctest/2.4.11#a4211dfc329a16ba9f280f9574025659%1756234220.819", "cassandra-cpp-driver/2.17.0#e50919efac8418c26be6671fd702540a%1750263632.157",
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772", "c-ares/1.34.5#b78b91e7cfb1f11ce777a285bbf169c6%1750263630.06",
"cassandra-cpp-driver/2.17.0#bd3934138689482102c265d01288a316%1764175359.611", "bzip2/1.0.8#00b4a4658791c1f06914e087f0e792f5%1750263627.95",
"c-ares/1.34.5#5581c2b62a608b40bb85d965ab3ec7c8%1765850144.336", "boost/1.83.0#8eb22f36ddfb61f54bbc412c4555bd66%1750263616.444",
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837", "benchmark/1.8.3#1a2ce62c99e2b3feaa57b1f0c15a8c46%1724323740.181",
"boost/1.83.0#91d8b1572534d2c334d6790e3c34d0c1%1764175359.61", "abseil/20230802.1#f0f91485b111dc9837a68972cb19ca7b%1750263609.776"
"benchmark/1.9.4#ce4403f7a24d3e1f907cd9da4b678be4%1754578869.672",
"abseil/20230802.1#90ba607d4ee8fb5fb157c3db540671fc%1764175359.429"
], ],
"build_requires": [ "build_requires": [
"zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075", "zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1750263732.782",
"protobuf/3.21.12#44ee56c0a6eea0c19aeeaca680370b88%1764175361.456", "protobuf/3.21.12#d927114e28de9f4691a6bbcdd9a529d1%1750263698.841",
"cmake/4.2.0#ae0a44f44a1ef9ab68fd4b3e9a1f8671%1765850153.937", "protobuf/3.21.9#64ce20e1d9ea24f3d6c504015d5f6fa8%1750263690.822",
"cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1765850153.479", "cmake/3.31.6#ed0e6c1d49bd564ce6fed1a19653b86d%1750263636.055",
"b2/5.3.3#107c15377719889654eb9a162a673975%1765850144.355" "b2/5.3.2#7b5fabfe7088ae933fb3e78302343ea0%1750263614.565"
], ],
"python_requires": [], "python_requires": [],
"overrides": { "overrides": {
"protobuf/3.21.12#44ee56c0a6eea0c19aeeaca680370b88": [ "boost/1.83.0": [
null,
"boost/1.83.0#8eb22f36ddfb61f54bbc412c4555bd66"
],
"protobuf/3.21.9": [
null, null,
"protobuf/3.21.12" "protobuf/3.21.12"
], ],
"boost/1.83.0#91d8b1572534d2c334d6790e3c34d0c1": [
null,
"boost/1.83.0#91d8b1572534d2c334d6790e3c34d0c1"
],
"lz4/1.9.4": [ "lz4/1.9.4": [
"lz4/1.10.0" "lz4/1.10.0"
], ],
"boost/1.90.0": [
"boost/1.83.0"
],
"sqlite3/3.44.2": [ "sqlite3/3.44.2": [
"sqlite3/3.49.1" "sqlite3/3.47.0"
] ]
}, },
"config_requires": [] "config_requires": []

View File

@@ -3,63 +3,92 @@ from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
class ClioConan(ConanFile): class ClioConan(ConanFile):
name = "clio" name = 'clio'
license = "ISC" license = 'ISC'
author = "Alex Kremer <akremer@ripple.com>, John Freeman <jfreeman@ripple.com>, Ayaz Salikhov <asalikhov@ripple.com>" author = 'Alex Kremer <akremer@ripple.com>, John Freeman <jfreeman@ripple.com>, Ayaz Salikhov <asalikhov@ripple.com>'
url = "https://github.com/xrplf/clio" url = 'https://github.com/xrplf/clio'
description = "Clio RPC server" description = 'Clio RPC server'
settings = "os", "compiler", "build_type", "arch" settings = 'os', 'compiler', 'build_type', 'arch'
options = {} options = {
'static': [True, False], # static linkage
'verbose': [True, False],
'tests': [True, False], # build unit tests; create `clio_tests` binary
'integration_tests': [True, False], # build integration tests; create `clio_integration_tests` binary
'benchmark': [True, False], # build benchmarks; create `clio_benchmarks` binary
'docs': [True, False], # doxygen API docs; create custom target 'docs'
'packaging': [True, False], # create distribution packages
'coverage': [True, False], # build for test coverage report; create custom target `clio_tests-ccov`
'lint': [True, False], # run clang-tidy checks during compilation
'snapshot': [True, False], # build export/import snapshot tool
'time_trace': [True, False] # build using -ftime-trace to create compiler trace reports
}
requires = [ requires = [
"cassandra-cpp-driver/2.17.0", 'boost/1.83.0',
"fmt/12.1.0", 'cassandra-cpp-driver/2.17.0',
"grpc/1.50.1", 'fmt/10.1.1',
"libbacktrace/cci.20210118", 'protobuf/3.21.12',
"openssl/1.1.1w", 'grpc/1.50.1',
"protobuf/3.21.12", 'openssl/1.1.1v',
"spdlog/1.17.0", 'xrpl/2.5.0-rc1',
"xrpl/3.1.0", 'zlib/1.3.1',
"zlib/1.3.1", 'libbacktrace/cci.20210118'
] ]
default_options = { default_options = {
"cassandra-cpp-driver/*:shared": False, 'static': False,
"date/*:header_only": True, 'verbose': False,
"grpc/*:secure": True, 'tests': False,
"grpc/*:shared": False, 'integration_tests': False,
"gtest/*:no_main": True, 'benchmark': False,
"libpq/*:shared": False, 'packaging': False,
"lz4/*:shared": False, 'coverage': False,
"openssl/*:shared": False, 'lint': False,
"protobuf/*:shared": False, 'docs': False,
"protobuf/*:with_zlib": True, 'snapshot': False,
"snappy/*:shared": False, 'time_trace': False,
"xrpl/*:rocksdb": False,
"xrpl/*:tests": False, 'xrpl/*:tests': False,
'xrpl/*:rocksdb': False,
'cassandra-cpp-driver/*:shared': False,
'date/*:header_only': True,
'grpc/*:shared': False,
'grpc/*:secure': True,
'libpq/*:shared': False,
'lz4/*:shared': False,
'openssl/*:shared': False,
'protobuf/*:shared': False,
'protobuf/*:with_zlib': True,
'snappy/*:shared': False,
'gtest/*:no_main': True,
} }
exports_sources = ("CMakeLists.txt", "cmake/*", "src/*") exports_sources = (
'CMakeLists.txt', 'cmake/*', 'src/*'
)
def requirements(self): def requirements(self):
self.requires("boost/1.83.0", force=True) if self.options.tests or self.options.integration_tests:
self.requires("gtest/1.17.0") self.requires('gtest/1.14.0')
self.requires("benchmark/1.9.4") if self.options.benchmark:
self.requires('benchmark/1.8.3')
def configure(self): def configure(self):
if self.settings.compiler == "apple-clang": if self.settings.compiler == 'apple-clang':
self.options["boost"].visibility = "global" self.options['boost'].visibility = 'global'
def layout(self): def layout(self):
cmake_layout(self) cmake_layout(self)
# Fix this setting to follow the default introduced in Conan 1.48 # Fix this setting to follow the default introduced in Conan 1.48
# to align with our build instructions. # to align with our build instructions.
self.folders.generators = "build/generators" self.folders.generators = 'build/generators'
generators = "CMakeDeps" generators = 'CMakeDeps'
def generate(self): def generate(self):
tc = CMakeToolchain(self) tc = CMakeToolchain(self)
for option_name, option_value in self.options.items():
tc.variables[option_name] = option_value
tc.generate() tc.generate()
def build(self): def build(self):

View File

@@ -1,11 +1,7 @@
ARG GHCR_REPO=invalid FROM ghcr.io/xrplf/clio-gcc:12.3.0 AS clio-gcc
ARG CLANG_MAJOR_VERSION=invalid FROM ghcr.io/xrplf/clio-tools:latest AS clio-tools
ARG GCC_VERSION=invalid
FROM ${GHCR_REPO}/clio-gcc:${GCC_VERSION} AS clio-gcc FROM ghcr.io/xrplf/clio-clang:16
FROM ${GHCR_REPO}/clio-tools:latest AS clio-tools
FROM ${GHCR_REPO}/clio-clang:${CLANG_MAJOR_VERSION}
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
@@ -20,99 +16,76 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
USER root USER root
WORKDIR /root WORKDIR /root
# Install common tools and dependencies ARG LLVM_TOOLS_VERSION=19
# Add repositories
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
curl \ curl \
dpkg-dev \
file \
git \
git-lfs \
gnupg \ gnupg \
graphviz \
jq \
# libgmp, libmpfr and libncurses are gdb dependencies
libgmp-dev \
libmpfr-dev \
libncurses-dev \
make \
wget \ wget \
zip \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/* \
&& echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${LLVM_TOOLS_VERSION} main" >> /etc/apt/sources.list \
# Install Python tools
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
python3 \
python3-pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN pip install -q --no-cache-dir \
# TODO: Remove this once we switch to newer Ubuntu base image
# lxml 6.0.0 is not compatible with our image
'lxml<6.0.0' \
cmake \
conan==2.24.0 \
gcovr \
# We're adding pre-commit to this image as well,
# because clang-tidy workflow requires it
pre-commit
# Install LLVM tools
ARG LLVM_TOOLS_VERSION=20
RUN echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${LLVM_TOOLS_VERSION} main" >> /etc/apt/sources.list \
&& wget --progress=dot:giga -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && wget --progress=dot:giga -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
# Install packages
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
clang-tidy-${LLVM_TOOLS_VERSION} \ clang-tidy-${LLVM_TOOLS_VERSION} \
clang-tools-${LLVM_TOOLS_VERSION} \ clang-tools-${LLVM_TOOLS_VERSION} \
git \
git-lfs \
graphviz \
jq \
make \
ninja-build \
python3 \
python3-pip \
zip \
&& pip3 install -q --upgrade --no-cache-dir pip \
&& pip3 install -q --no-cache-dir \
cmake==3.31.6 \
conan==2.17.0 \
gcovr \
pre-commit \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
ARG GCC_MAJOR_VERSION=invalid # Install gcc-12 and make ldconfig aware of the new libstdc++ location (for gcc)
# Install custom-built gcc and make ldconfig aware of the new libstdc++ location (for gcc)
# Note: Clang is using libc++ instead # Note: Clang is using libc++ instead
COPY --from=clio-gcc /gcc${GCC_MAJOR_VERSION}.deb / COPY --from=clio-gcc /gcc12.deb /
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
binutils \ binutils \
libc6-dev \ libc6-dev \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* \ && rm -rf /var/lib/apt/lists/* \
&& dpkg -i /gcc${GCC_MAJOR_VERSION}.deb \ && dpkg -i /gcc12.deb \
&& rm -rf /gcc${GCC_MAJOR_VERSION}.deb \ && rm -rf /gcc12.deb \
&& ldconfig && ldconfig
# Rewire to use our custom-built gcc as default compiler # Rewire to use gcc-12 as default compiler
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCC_MAJOR_VERSION} 100 \ RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 100 \
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-${GCC_MAJOR_VERSION} 100 \ && update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++-12 100 \
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_MAJOR_VERSION} 100 \ && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 \
&& update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-${GCC_MAJOR_VERSION} 100 \ && update-alternatives --install /usr/bin/cc cc /usr/bin/gcc-12 100 \
&& update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-${GCC_MAJOR_VERSION} 100 \ && update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-12 100 \
&& update-alternatives --install /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-${GCC_MAJOR_VERSION} 100 \ && update-alternatives --install /usr/bin/gcov-dump gcov-dump /usr/bin/gcov-dump-12 100 \
&& update-alternatives --install /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-${GCC_MAJOR_VERSION} 100 && update-alternatives --install /usr/bin/gcov-tool gcov-tool /usr/bin/gcov-tool-12 100
COPY --from=clio-tools \ COPY --from=clio-tools \
/usr/local/bin/mold \
/usr/local/bin/ld.mold \
/usr/local/bin/ccache \ /usr/local/bin/ccache \
/usr/local/bin/doxygen \ /usr/local/bin/doxygen \
/usr/local/bin/ClangBuildAnalyzer \ /usr/local/bin/ClangBuildAnalyzer \
/usr/local/bin/git-cliff \ /usr/local/bin/git-cliff \
/usr/local/bin/gh \ /usr/local/bin/gh \
/usr/local/bin/gdb \
/usr/local/bin/ninja \
/usr/local/bin/ /usr/local/bin/
WORKDIR /root WORKDIR /root
# Setup conan # Setup conan
RUN conan remote add --index 0 xrplf https://conan.ripplex.io RUN conan remote add --index 0 ripple http://18.143.149.228:8081/artifactory/api/conan/dev
WORKDIR /root/.conan2 WORKDIR /root/.conan2
COPY conan/global.conf ./global.conf COPY conan/global.conf ./global.conf

View File

@@ -5,18 +5,14 @@ It is used in [Clio Github Actions](https://github.com/XRPLF/clio/actions) but c
The image is based on Ubuntu 20.04 and contains: The image is based on Ubuntu 20.04 and contains:
- ccache 4.12.2 - ccache 4.11.3
- Clang 19 - clang 16.0.6
- ClangBuildAnalyzer 1.6.0 - ClangBuildAnalyzer 1.6.0
- Conan 2.24.0 - conan 2.17.0
- Doxygen 1.16.1 - doxygen 1.12
- GCC 15.2.0 - gcc 12.3.0
- GDB 17.1 - gh 2.74
- gh 2.83.2 - git-cliff 2.9.1
- git-cliff 2.11.0
- mold 2.40.4
- Ninja 1.13.2
- Python 3.8
- and some other useful tools - and some other useful tools
Conan is set up to build Clio without any additional steps. Conan is set up to build Clio without any additional steps.

View File

@@ -4,9 +4,8 @@ build_type=Release
compiler=clang compiler=clang
compiler.cppstd=20 compiler.cppstd=20
compiler.libcxx=libc++ compiler.libcxx=libc++
compiler.version=19 compiler.version=16
os=Linux os=Linux
[conf] [conf]
tools.build:compiler_executables={"c": "/usr/bin/clang-19", "cpp": "/usr/bin/clang++-19"} tools.build:compiler_executables={'c': '/usr/bin/clang-16', 'cpp': '/usr/bin/clang++-16'}
grpc/1.50.1:tools.build:cxxflags+=["-Wno-missing-template-arg-list-after-template-kw"]

View File

@@ -4,8 +4,8 @@ build_type=Release
compiler=gcc compiler=gcc
compiler.cppstd=20 compiler.cppstd=20
compiler.libcxx=libstdc++11 compiler.libcxx=libstdc++11
compiler.version=15 compiler.version=12
os=Linux os=Linux
[conf] [conf]
tools.build:compiler_executables={"c": "/usr/bin/gcc-15", "cpp": "/usr/bin/g++-15"} tools.build:compiler_executables={'c': '/usr/bin/gcc-12', 'cpp': '/usr/bin/g++-12'}

View File

@@ -1,2 +1,3 @@
core.download:parallel={{os.cpu_count()}} core.download:parallel={{os.cpu_count()}}
core.upload:parallel={{os.cpu_count()}} core.upload:parallel={{os.cpu_count()}}
tools.info.package_id:confs = ["tools.build:cflags", "tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags"]

View File

@@ -1,15 +1,7 @@
{% set compiler, sani = profile_name.split('.') %} {% set compiler, sani = profile_name.split('.') %}
{% set sanitizer_opt_map = {"asan": "address", "tsan": "thread", "ubsan": "undefined"} %} {% set sanitizer_opt_map = {'asan': 'address', 'tsan': 'thread', 'ubsan': 'undefined'} %}
{% set sanitizer = sanitizer_opt_map[sani] %} {% set sanitizer = sanitizer_opt_map[sani] %}
{% set sanitizer_b2_flags_map = {
"address": "context-impl=ucontext address-sanitizer=norecover",
"thread": "context-impl=ucontext thread-sanitizer=norecover",
"undefined": "undefined-sanitizer=norecover"
} %}
{% set sanitizer_b2_flags_str = sanitizer_b2_flags_map[sanitizer] %}
{% set sanitizer_build_flags_str = "-fsanitize=" ~ sanitizer ~ " -g -O1 -fno-omit-frame-pointer" %} {% set sanitizer_build_flags_str = "-fsanitize=" ~ sanitizer ~ " -g -O1 -fno-omit-frame-pointer" %}
{% set sanitizer_build_flags = sanitizer_build_flags_str.split(' ') %} {% set sanitizer_build_flags = sanitizer_build_flags_str.split(' ') %}
{% set sanitizer_link_flags_str = "-fsanitize=" ~ sanitizer %} {% set sanitizer_link_flags_str = "-fsanitize=" ~ sanitizer %}
@@ -18,20 +10,11 @@
include({{ compiler }}) include({{ compiler }})
[options] [options]
boost/*:extra_b2_flags="{{ sanitizer_b2_flags_str }}" boost/*:extra_b2_flags = "cxxflags=\"{{ sanitizer_build_flags_str }}\" linkflags=\"{{ sanitizer_link_flags_str }}\""
boost/*:without_context=False boost/*:without_stacktrace = True
boost/*:without_stacktrace=True
[conf] [conf]
tools.build:cflags+={{ sanitizer_build_flags }} tools.build:cflags += {{ sanitizer_build_flags }}
tools.build:cxxflags+={{ sanitizer_build_flags }} tools.build:cxxflags += {{ sanitizer_build_flags }}
tools.build:exelinkflags+={{ sanitizer_link_flags }} tools.build:exelinkflags += {{ sanitizer_link_flags }}
tools.build:sharedlinkflags+={{ sanitizer_link_flags }} tools.build:sharedlinkflags += {{ sanitizer_link_flags }}
{% if sanitizer == "address" %}
tools.build:defines+=["BOOST_USE_ASAN", "BOOST_USE_UCONTEXT"]
{% elif sanitizer == "thread" %}
tools.build:defines+=["BOOST_USE_TSAN", "BOOST_USE_UCONTEXT"]
{% endif %}
tools.info.package_id:confs+=["tools.build:cflags", "tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags", "tools.build:defines"]

View File

@@ -1,20 +1,18 @@
FROM ubuntu:22.04 FROM ubuntu:22.04
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
libatomic1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN groupadd -g 10001 clio \
&& useradd -u 10000 -g 10001 -s /bin/bash clio
COPY ./clio_server /opt/clio/bin/clio_server COPY ./clio_server /opt/clio/bin/clio_server
RUN ln -s /opt/clio/bin/clio_server /usr/local/bin/clio_server \ RUN ln -s /opt/clio/bin/clio_server /usr/local/bin/clio_server \
&& mkdir -p /opt/clio/etc/ \ && mkdir -p /opt/clio/etc/ \
&& mkdir -p /opt/clio/log/ \ && mkdir -p /opt/clio/log/ \
&& chown clio:clio /opt/clio/log && groupadd -g 10001 clio \
&& useradd -u 10000 -g 10001 -s /bin/bash clio \
&& chown clio:clio /opt/clio/log \
&& apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
libatomic1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
USER clio USER clio
ENTRYPOINT ["/opt/clio/bin/clio_server"] ENTRYPOINT ["/opt/clio/bin/clio_server"]

View File

@@ -13,8 +13,8 @@ Clio repository provides an [example](https://github.com/XRPLF/clio/blob/develop
Config file recommendations: Config file recommendations:
- Set `log.enable_console` to `false` if you want to avoid logs being written to `stdout`. - Set `log_to_console` to `false` if you want to avoid logs being written to `stdout`.
- Set `log.directory` to `/opt/clio/log` to store logs in a volume. - Set `log_directory` to `/opt/clio/log` to store logs in a volume.
## Usage ## Usage

View File

@@ -8,6 +8,8 @@ SHELL ["/bin/bash", "-c"]
USER root USER root
WORKDIR /root WORKDIR /root
ARG CLANG_VERSION=16
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
wget \ wget \
@@ -16,17 +18,13 @@ RUN apt-get update \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
ARG CLANG_MAJOR_VERSION=invalid
# Bump this version to force rebuild of the image
ARG BUILD_VERSION=1
RUN wget --progress=dot:giga https://apt.llvm.org/llvm.sh \ RUN wget --progress=dot:giga https://apt.llvm.org/llvm.sh \
&& chmod +x llvm.sh \ && chmod +x llvm.sh \
&& ./llvm.sh ${CLANG_MAJOR_VERSION} \ && ./llvm.sh ${CLANG_VERSION} \
&& rm -rf llvm.sh \ && rm -rf llvm.sh \
&& apt-get update \ && apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
libc++-${CLANG_MAJOR_VERSION}-dev \ libc++-${CLANG_VERSION}-dev \
libc++abi-${CLANG_MAJOR_VERSION}-dev \ libc++abi-${CLANG_VERSION}-dev \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*

View File

@@ -1,14 +1,16 @@
ARG UBUNTU_VERSION=20.04 ARG UBUNTU_VERSION=20.04
ARG GCC_MAJOR_VERSION=invalid ARG GCC_MAJOR_VERSION=12
FROM ubuntu:$UBUNTU_VERSION AS build FROM ubuntu:$UBUNTU_VERSION AS build
ARG UBUNTU_VERSION ARG UBUNTU_VERSION
ARG GCC_MAJOR_VERSION ARG GCC_MAJOR_VERSION
ARG GCC_MINOR_VERSION=3
ARG BUILD_VERSION=0 ARG GCC_PATCH_VERSION=0
ARG GCC_VERSION=${GCC_MAJOR_VERSION}.${GCC_MINOR_VERSION}.${GCC_PATCH_VERSION}
ARG BUILD_VERSION=6
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ARG TARGETARCH ARG TARGETARCH
@@ -25,8 +27,6 @@ RUN apt-get update \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
ARG GCC_VERSION
WORKDIR / WORKDIR /
RUN wget --progress=dot:giga https://gcc.gnu.org/pub/gcc/releases/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz \ RUN wget --progress=dot:giga https://gcc.gnu.org/pub/gcc/releases/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz \
&& tar xf gcc-$GCC_VERSION.tar.gz && tar xf gcc-$GCC_VERSION.tar.gz
@@ -34,7 +34,6 @@ RUN wget --progress=dot:giga https://gcc.gnu.org/pub/gcc/releases/gcc-$GCC_VERSI
WORKDIR /gcc-$GCC_VERSION WORKDIR /gcc-$GCC_VERSION
RUN ./contrib/download_prerequisites RUN ./contrib/download_prerequisites
# hadolint ignore=DL3059
RUN mkdir /gcc-build RUN mkdir /gcc-build
WORKDIR /gcc-build WORKDIR /gcc-build
RUN /gcc-$GCC_VERSION/configure \ RUN /gcc-$GCC_VERSION/configure \
@@ -69,13 +68,12 @@ RUN /gcc-$GCC_VERSION/configure \
--enable-checking=release --enable-checking=release
RUN make -j "$(nproc)" RUN make -j "$(nproc)"
RUN make install-strip DESTDIR=/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION
RUN export GDB_AUTOLOAD_DIR="/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/share/gdb/auto-load/usr/lib64" \ RUN make install-strip DESTDIR=/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION \
&& mkdir -p "$GDB_AUTOLOAD_DIR" \ && mkdir -p /gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/share/gdb/auto-load/usr/lib64 \
&& mv \ && mv \
/gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/lib64/libstdc++.so.*-gdb.py \ /gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/lib64/libstdc++.so.6.0.30-gdb.py \
$GDB_AUTOLOAD_DIR/ /gcc-$GCC_VERSION-$BUILD_VERSION-ubuntu-$UBUNTU_VERSION/usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.30-gdb.py
# Generate deb # Generate deb
WORKDIR / WORKDIR /

View File

@@ -1,4 +1,4 @@
Package: gcc-15-ubuntu-UBUNTUVERSION Package: gcc-12-ubuntu-UBUNTUVERSION
Version: VERSION Version: VERSION
Architecture: TARGETARCH Architecture: TARGETARCH
Maintainer: Alex Kremer <akremer@ripple.com> Maintainer: Alex Kremer <akremer@ripple.com>

View File

@@ -1,6 +1,6 @@
services: services:
clio_develop: clio_develop:
image: ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696 image: ghcr.io/xrplf/clio-ci:latest
volumes: volumes:
- clio_develop_conan_data:/root/.conan2/p - clio_develop_conan_data:/root/.conan2/p
- clio_develop_ccache:/root/.ccache - clio_develop_ccache:/root/.ccache

View File

@@ -2,7 +2,7 @@
script_dir=$(dirname $0) script_dir=$(dirname $0)
pushd $script_dir >/dev/null pushd $script_dir > /dev/null
function start_container { function start_container {
if [ -z "$(docker ps -q -f name=clio_develop)" ]; then if [ -z "$(docker ps -q -f name=clio_develop)" ]; then
@@ -41,26 +41,21 @@ EOF
} }
case $1 in case $1 in
-h | --help) -h|--help)
print_help print_help ;;
;;
-t | --terminal) -t|--terminal)
open_terminal open_terminal ;;
;;
-s | --stop) -s|--stop)
stop_container stop_container ;;
;;
-*) -*)
echo "Unknown option: $1" echo "Unknown option: $1"
print_help print_help ;;
;;
*) *)
run "$@" run "$@" ;;
;;
esac esac
popd >/dev/null popd > /dev/null

View File

@@ -1,38 +0,0 @@
ARG GHCR_REPO=invalid
FROM ${GHCR_REPO}/clio-tools:latest AS clio-tools
# We're using Ubuntu 24.04 to have a more recent version of Python
FROM ubuntu:24.04
ARG DEBIAN_FRONTEND=noninteractive
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# hadolint ignore=DL3002
USER root
WORKDIR /root
# Install common tools and dependencies
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
curl \
git \
libatomic1 \
software-properties-common \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install Python tools
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
python3 \
python3-pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN pip install -q --no-cache-dir --break-system-packages \
pre-commit
COPY --from=clio-tools \
/usr/local/bin/doxygen \
/usr/local/bin/

View File

@@ -1,72 +1,42 @@
ARG GHCR_REPO=invalid FROM ubuntu:20.04
ARG GCC_VERSION=invalid
FROM ${GHCR_REPO}/clio-gcc:${GCC_VERSION}
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ARG TARGETARCH ARG TARGETARCH
SHELL ["/bin/bash", "-o", "pipefail", "-c"] SHELL ["/bin/bash", "-o", "pipefail", "-c"]
ARG BUILD_VERSION=0
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
python3 \ bison \
python3-pip \ build-essential \
cmake \
flex \
ninja-build \
software-properties-common \ software-properties-common \
wget \ wget \
&& pip3 install -q --no-cache-dir \
cmake \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
WORKDIR /tmp WORKDIR /tmp
ARG NINJA_VERSION=1.13.2 ARG CCACHE_VERSION=4.11.3
RUN wget --progress=dot:giga "https://github.com/ninja-build/ninja/archive/refs/tags/v${NINJA_VERSION}.tar.gz" \
&& tar xf "v${NINJA_VERSION}.tar.gz" \
&& cd "ninja-${NINJA_VERSION}" \
&& ./configure.py --bootstrap \
&& mv ninja /usr/local/bin/ninja \
&& rm -rf /tmp/* /var/tmp/*
ARG MOLD_VERSION=2.40.4
RUN wget --progress=dot:giga "https://github.com/rui314/mold/archive/refs/tags/v${MOLD_VERSION}.tar.gz" \
&& tar xf "v${MOLD_VERSION}.tar.gz" \
&& cd "mold-${MOLD_VERSION}" \
&& mkdir build \
&& cd build \
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
&& ninja install \
&& rm -rf /tmp/* /var/tmp/*
ARG CCACHE_VERSION=4.12.2
RUN wget --progress=dot:giga "https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/ccache/ccache/releases/download/v${CCACHE_VERSION}/ccache-${CCACHE_VERSION}.tar.gz" \
&& tar xf "ccache-${CCACHE_VERSION}.tar.gz" \ && tar xf "ccache-${CCACHE_VERSION}.tar.gz" \
&& cd "ccache-${CCACHE_VERSION}" \ && cd "ccache-${CCACHE_VERSION}" \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=False .. \ && cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=False .. \
&& ninja install \ && cmake --build . --target install \
&& rm -rf /tmp/* /var/tmp/* && rm -rf /tmp/* /var/tmp/*
RUN apt-get update \ ARG DOXYGEN_VERSION=1.12.0
&& apt-get install -y --no-install-recommends --no-install-suggests \
bison \
flex \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ARG DOXYGEN_VERSION=1.16.1
RUN wget --progress=dot:giga "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.src.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/doxygen/doxygen/releases/download/Release_${DOXYGEN_VERSION//./_}/doxygen-${DOXYGEN_VERSION}.src.tar.gz" \
&& tar xf "doxygen-${DOXYGEN_VERSION}.src.tar.gz" \ && tar xf "doxygen-${DOXYGEN_VERSION}.src.tar.gz" \
&& cd "doxygen-${DOXYGEN_VERSION}" \ && cd "doxygen-${DOXYGEN_VERSION}" \
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \ && cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
&& ninja install \ && cmake --build . --target install \
&& rm -rf /tmp/* /var/tmp/* && rm -rf /tmp/* /var/tmp/*
ARG CLANG_BUILD_ANALYZER_VERSION=1.6.0 ARG CLANG_BUILD_ANALYZER_VERSION=1.6.0
@@ -76,37 +46,19 @@ RUN wget --progress=dot:giga "https://github.com/aras-p/ClangBuildAnalyzer/archi
&& mkdir build \ && mkdir build \
&& cd build \ && cd build \
&& cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \ && cmake -GNinja -DCMAKE_BUILD_TYPE=Release .. \
&& ninja install \ && cmake --build . --target install \
&& rm -rf /tmp/* /var/tmp/* && rm -rf /tmp/* /var/tmp/*
ARG GIT_CLIFF_VERSION=2.11.0 ARG GIT_CLIFF_VERSION=2.9.1
RUN wget --progress=dot:giga "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-musl.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/orhun/git-cliff/releases/download/v${GIT_CLIFF_VERSION}/git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-musl.tar.gz" \
&& tar xf git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-musl.tar.gz \ && tar xf git-cliff-${GIT_CLIFF_VERSION}-x86_64-unknown-linux-musl.tar.gz \
&& mv git-cliff-${GIT_CLIFF_VERSION}/git-cliff /usr/local/bin/git-cliff \ && mv git-cliff-${GIT_CLIFF_VERSION}/git-cliff /usr/local/bin/git-cliff \
&& rm -rf /tmp/* /var/tmp/* && rm -rf /tmp/* /var/tmp/*
ARG GH_VERSION=2.83.2 ARG GH_VERSION=2.74.0
RUN wget --progress=dot:giga "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz" \ RUN wget --progress=dot:giga "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz" \
&& tar xf gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz \ && tar xf gh_${GH_VERSION}_linux_${TARGETARCH}.tar.gz \
&& mv gh_${GH_VERSION}_linux_${TARGETARCH}/bin/gh /usr/local/bin/gh \ && mv gh_${GH_VERSION}_linux_${TARGETARCH}/bin/gh /usr/local/bin/gh \
&& rm -rf /tmp/* /var/tmp/* && rm -rf /tmp/* /var/tmp/*
RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \
libgmp-dev \
libmpfr-dev \
libncurses-dev \
make \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ARG GDB_VERSION=17.1
RUN wget --progress=dot:giga "https://sourceware.org/pub/gdb/releases/gdb-${GDB_VERSION}.tar.gz" \
&& tar xf "gdb-${GDB_VERSION}.tar.gz" \
&& cd "gdb-${GDB_VERSION}" \
&& ./configure --prefix=/usr/local \
&& make -j "$(nproc)" \
&& make install-gdb \
&& rm -rf /tmp/* /var/tmp/*
WORKDIR /root WORKDIR /root

View File

@@ -3,8 +3,6 @@ PROJECT_LOGO = ${SOURCE}/docs/img/xrpl-logo.svg
PROJECT_NUMBER = ${DOC_CLIO_VERSION} PROJECT_NUMBER = ${DOC_CLIO_VERSION}
PROJECT_BRIEF = The XRP Ledger API server. PROJECT_BRIEF = The XRP Ledger API server.
DOT_GRAPH_MAX_NODES = 100
EXTRACT_ALL = NO EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO EXTRACT_PRIVATE = NO
EXTRACT_PACKAGE = YES EXTRACT_PACKAGE = YES
@@ -15,7 +13,6 @@ EXTRACT_ANON_NSPACES = NO
SORT_MEMBERS_CTORS_1ST = YES SORT_MEMBERS_CTORS_1ST = YES
INPUT = ${SOURCE}/src INPUT = ${SOURCE}/src
USE_MDFILE_AS_MAINPAGE = ${SOURCE}/src/README.md
EXCLUDE_SYMBOLS = ${EXCLUDES} EXCLUDE_SYMBOLS = ${EXCLUDES}
RECURSIVE = YES RECURSIVE = YES
HAVE_DOT = ${USE_DOT} HAVE_DOT = ${USE_DOT}
@@ -35,18 +32,12 @@ SORT_MEMBERS_CTORS_1ST = YES
GENERATE_TREEVIEW = YES GENERATE_TREEVIEW = YES
DISABLE_INDEX = NO DISABLE_INDEX = NO
FULL_SIDEBAR = NO FULL_SIDEBAR = NO
HTML_HEADER = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/header.html HTML_HEADER = ${SOURCE}/docs/doxygen-awesome-theme/header.html
HTML_EXTRA_STYLESHEET = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome.css \ HTML_EXTRA_STYLESHEET = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome.css \
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-sidebar-only.css \ ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-sidebar-only.css \
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-sidebar-only-darkmode-toggle.css \ ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-sidebar-only-darkmode-toggle.css
${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/custom.css \
${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/theme-robot.css \
${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/theme-round.css \
${SOURCE}/docs/github-corner-disable.css
HTML_EXTRA_FILES = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-darkmode-toggle.js \ HTML_EXTRA_FILES = ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-darkmode-toggle.js \
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-fragment-copy-button.js \ ${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-interactive-toc.js
${SOURCE}/docs/doxygen-awesome-theme/doxygen-awesome-interactive-toc.js \
${SOURCE}/docs/doxygen-awesome-theme/doxygen-custom/toggle-alternative-theme.js
HTML_COLORSTYLE = LIGHT HTML_COLORSTYLE = LIGHT
HTML_COLORSTYLE_HUE = 209 HTML_COLORSTYLE_HUE = 209

View File

@@ -6,42 +6,25 @@
## Minimum Requirements ## Minimum Requirements
- [Python 3.7](https://www.python.org/downloads/) - [Python 3.7](https://www.python.org/downloads/)
- [Conan 2.20.1](https://conan.io/downloads.html) - [Conan 1.55, <2.0](https://conan.io/downloads.html)
- [CMake 3.20](https://cmake.org/download/) - [CMake 3.20, <4.0](https://cmake.org/download/)
- [**Optional**] [GCovr](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html): needed for code coverage generation - [**Optional**] [GCovr](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html): needed for code coverage generation
- [**Optional**] [CCache](https://ccache.dev/): speeds up compilation if you are going to compile Clio often - [**Optional**] [CCache](https://ccache.dev/): speeds up compilation if you are going to compile Clio often
We use our Docker image `ghcr.io/XRPLF/clio-ci` to build `Clio`, see [Building Clio with Docker](#building-clio-with-docker).
You can find information about exact compiler versions and tools in the [image's README](https://github.com/XRPLF/clio/blob/develop/docker/ci/README.md).
The following compiler version are guaranteed to work.
Any compiler with lower version may not be able to build Clio:
| Compiler | Version | | Compiler | Version |
| ----------- | ------- | | ----------- | ------- |
| GCC | 15.2 | | GCC | 12.3 |
| Clang | 19 | | Clang | 16 |
| Apple Clang | 17 | | Apple Clang | 15 |
### Conan Configuration ### Conan Configuration
By default, Conan uses `~/.conan2` as it's home folder. Clio requires `compiler.cppstd=20` in your Conan profile (`~/.conan2/profiles/default`).
You can change it by using `$CONAN_HOME` env variable.
[More info about Conan home](https://docs.conan.io/2/reference/environment.html#conan-home).
> [!TIP] > [!NOTE]
> To setup Conan automatically, you can run `.github/scripts/conan/init.sh`. > Although Clio is built using C++23, it's required to set `compiler.cppstd=20` for the time being as some of Clio's dependencies are not yet capable of building under C++23.
> This will delete Conan home directory (if it exists), set up profiles and add Artifactory remote.
The instruction below assumes that `$CONAN_HOME` is not set. **Mac apple-clang 16 example**:
#### Profiles
The default profile is the file in `~/.conan2/profiles/default`.
Here are some examples of possible profiles:
**Mac apple-clang 17 example**:
```text ```text
[settings] [settings]
@@ -50,7 +33,7 @@ build_type=Release
compiler=apple-clang compiler=apple-clang
compiler.cppstd=20 compiler.cppstd=20
compiler.libcxx=libc++ compiler.libcxx=libc++
compiler.version=17 compiler.version=16
os=Macos os=Macos
[conf] [conf]
@@ -70,19 +53,13 @@ compiler.version=12
os=Linux os=Linux
[conf] [conf]
tools.build:compiler_executables={"c": "/usr/bin/gcc-12", "cpp": "/usr/bin/g++-12"} tools.build:compiler_executables={'c': '/usr/bin/gcc-12', 'cpp': '/usr/bin/g++-12'}
``` ```
> [!NOTE] Add the following to the `~/.conan2/global.conf` file:
> Although Clio is built using C++23, it's required to set `compiler.cppstd=20` in your profile for the time being as some of Clio's dependencies are not yet capable of building under C++23.
#### global.conf file
To increase the speed of downloading and uploading packages, add the following to the `~/.conan2/global.conf` file:
```text ```text
core.download:parallel={{os.cpu_count()}} tools.info.package_id:confs = ["tools.build:cflags", "tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags"]
core.upload:parallel={{os.cpu_count()}}
``` ```
#### Artifactory #### Artifactory
@@ -90,98 +67,101 @@ core.upload:parallel={{os.cpu_count()}}
Make sure artifactory is setup with Conan. Make sure artifactory is setup with Conan.
```sh ```sh
conan remote add --index 0 xrplf https://conan.ripplex.io conan remote add --index 0 ripple http://18.143.149.228:8081/artifactory/api/conan/dev
``` ```
Now you should be able to download the prebuilt dependencies (including `xrpl` package) on supported platforms. Now you should be able to download the prebuilt `xrpl` package on some platforms.
> [!NOTE]
> You may need to edit the `~/.conan2/remotes.json` file to ensure that this newly added artifactory is listed last. Otherwise, you could see compilation errors when building the project with gcc version 13 (or newer).
Remove old packages you may have cached interactively.
```sh
conan remove xrpl
```
#### Conan lockfile #### Conan lockfile
To achieve reproducible dependencies, we use a [Conan lockfile](https://docs.conan.io/2/tutorial/versioning/lockfiles.html). To achieve reproducible dependencies, we use [Conan lockfile](https://docs.conan.io/2/tutorial/versioning/lockfiles.html).
The `conan.lock` file in the repository contains a "snapshot" of the current dependencies. The `conan.lock` file in the repository contains a "snapshot" of the current dependencies.
It is implicitly used when running `conan` commands, you don't need to specify it. It is implicitly used when running `conan` commands, you don't need to specify it.
You have to update this file every time you add a new dependency or change a revision or version of an existing dependency. You have to update this file every time you add a new dependency or change a revision or version of an existing dependency.
To update a lockfile, run from the repository root: `./.github/scripts/conan/regenerate_lockfile.sh` To do that, run the following command in the repository root:
```bash
conan lock create . -o '&:tests=True' -o '&:benchmark=True'
```
## Building Clio ## Building Clio
1. Navigate to Clio's root directory and run: Navigate to Clio's root directory and run:
```sh ```sh
mkdir build && cd build mkdir build && cd build
``` conan install .. --output-folder . --build missing --settings build_type=Release -o '&:tests=True'
# You can also add -GNinja to use Ninja build system instead of Make
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --parallel 8 # or without the number if you feel extra adventurous
```
2. Install dependencies through conan. > [!TIP]
> You can omit the `-o '&:tests=True'` if you don't want to build `clio_tests`.
```sh If successful, `conan install` will find the required packages and `cmake` will do the rest. You should see `clio_server` and `clio_tests` in the `build` directory (the current directory).
conan install .. --output-folder . --build missing --settings build_type=Release
```
> You can add `--profile:all <PROFILE_NAME>` to choose a specific conan profile. > [!TIP]
> To generate a Code Coverage report, include `-o '&:coverage=True'` in the `conan install` command above, along with `-o '&:tests=True'` to enable tests.
> After running the `cmake` commands, execute `make clio_tests-ccov`.
> The coverage report will be found at `clio_tests-llvm-cov/index.html`.
3. Configure and generate build files with CMake. <!-- markdownlint-disable-line MD028 -->
```sh
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..
```
> You can add `-GNinja` to use the Ninja build system (instead of Make).
4. Now, you can build all targets or specific ones:
```sh
# builds all targets
cmake --build . --parallel 8
# builds only clio_server target
cmake --build . --parallel 8 --target clio_server
```
You should see `clio_server` and `clio_tests` in the current directory.
> [!NOTE] > [!NOTE]
> If you've built Clio before and the build is now failing, it's likely due to updated dependencies. Try deleting the build folder and then rerunning the Conan and CMake commands mentioned above. > If you've built Clio before and the build is now failing, it's likely due to updated dependencies. Try deleting the build folder and then rerunning the Conan and CMake commands mentioned above.
### CMake options
There are several CMake options you can use to customize the build:
| CMake Option | Default | CMake Target | Description |
| --------------------- | ------- | -------------------------------------------------------- | ------------------------------------- |
| `-Dcoverage` | OFF | `clio_tests-ccov` | Enables code coverage generation |
| `-Dtests` | OFF | `clio_tests` | Enables unit tests |
| `-Dintegration_tests` | OFF | `clio_integration_tests` | Enables integration tests |
| `-Dbenchmark` | OFF | `clio_benchmark` | Enables benchmark executable |
| `-Ddocs` | OFF | `docs` | Enables API documentation generation |
| `-Dlint` | OFF | See [#clang-tidy](#using-clang-tidy-for-static-analysis) | Enables `clang-tidy` static analysis |
| `-Dsan` | N/A | N/A | Enables Sanitizer (asan, tsan, ubsan) |
| `-Dpackage` | OFF | N/A | Creates a debian package |
### Generating API docs for Clio ### Generating API docs for Clio
The API documentation for Clio is generated by [Doxygen](https://www.doxygen.nl/index.html). If you want to generate the API documentation when building Clio, make sure to install Doxygen 1.14.0 on your system. The API documentation for Clio is generated by [Doxygen](https://www.doxygen.nl/index.html). If you want to generate the API documentation when building Clio, make sure to install Doxygen 1.12.0 on your system.
To generate the API docs, please use CMake option `-Ddocs=ON` as described above and build the `docs` target. To generate the API docs:
To view the generated files, go to `build/docs/html`. 1. First, include `-o '&:docs=True'` in the conan install command. For example:
Open the `index.html` file in your browser to see the documentation pages.
![API index page](./img/doxygen-docs-output.png "API index page") ```sh
mkdir build && cd build
conan install .. --output-folder . --build missing --settings build_type=Release -o '&:tests=True' -o '&:docs=True'
```
2. Once that has completed successfully, run the `cmake` command and add the `--target docs` option:
```sh
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --parallel 8 --target docs
```
3. Go to `build/docs/html` to view the generated files.
Open the `index.html` file in your browser to see the documentation pages.
![API index page](./img/doxygen-docs-output.png "API index page")
## Building Clio with Docker ## Building Clio with Docker
It is also possible to build Clio using [Docker](https://www.docker.com/) if you don't want to install all the dependencies on your machine. It is also possible to build Clio using [Docker](https://www.docker.com/) if you don't want to install all the dependencies on your machine.
```sh ```sh
docker run -it ghcr.io/xrplf/clio-ci:14342e087ceb8b593027198bf9ef06a43833c696 docker run -it ghcr.io/xrplf/clio-ci:latest
git clone https://github.com/XRPLF/clio git clone https://github.com/XRPLF/clio
cd clio mkdir build && cd build
conan install .. --output-folder . --build missing --settings build_type=Release -o '&:tests=True'
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --parallel 8 # or without the number if you feel extra adventurous
``` ```
Follow the same steps in the [Building Clio](#building-clio) section. You can use `--profile:all gcc` or `--profile:all clang` with the `conan install` command to choose the desired compiler.
## Developing against `rippled` in standalone mode ## Developing against `rippled` in standalone mode
If you wish to develop against a `rippled` instance running in standalone mode there are a few quirks of both Clio and `rippled` that you need to keep in mind. You must: If you wish to develop against a `rippled` instance running in standalone mode there are a few quirks of both Clio and `rippled` that you need to keep in mind. You must:
@@ -233,16 +213,18 @@ Sometimes, during development, you need to build against a custom version of `li
## Using `clang-tidy` for static analysis ## Using `clang-tidy` for static analysis
The minimum [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) version required is 19.0.
Clang-tidy can be run by CMake when building the project. Clang-tidy can be run by CMake when building the project.
To achieve this, you just need to provide the option `-Dlint=ON` when generating CMake files: To achieve this, you just need to provide the option `-o '&:lint=True'` for the `conan install` command:
```sh ```sh
cmake -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -Dlint=ON .. conan install .. --output-folder . --build missing --settings build_type=Release -o '&:tests=True' -o '&:lint=True'
``` ```
By default CMake will try to find `clang-tidy` automatically in your system. By default CMake will try to find `clang-tidy` automatically in your system.
To force CMake to use your desired binary, set the `CLIO_CLANG_TIDY_BIN` environment variable to the path of the `clang-tidy` binary. For example: To force CMake to use your desired binary, set the `CLIO_CLANG_TIDY_BIN` environment variable to the path of the `clang-tidy` binary. For example:
```sh ```sh
export CLIO_CLANG_TIDY_BIN=/opt/homebrew/opt/llvm/bin/clang-tidy export CLIO_CLANG_TIDY_BIN=/opt/homebrew/opt/llvm@19/bin/clang-tidy
``` ```

View File

@@ -3,9 +3,7 @@
This document provides a list of all available Clio configuration properties in detail. This document provides a list of all available Clio configuration properties in detail.
> [!NOTE] > [!NOTE]
> Dot notation in configuration key names represents nested fields. > Dot notation in configuration key names represents nested fields. For example, **database.scylladb** refers to the _scylladb_ field inside the _database_ object. If a key name includes "[]", it indicates that the nested field is an array (e.g., etl_sources.[]).
> For example, **database.scylladb** refers to the _scylladb_ field inside the _database_ object.
> If a key name includes "[]", it indicates that the nested field is an array (e.g., etl_sources.[]).
## Configuration Details ## Configuration Details
@@ -89,14 +87,6 @@ This document provides a list of all available Clio configuration properties in
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`. - **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
- **Description**: Represents the number of threads that will be used for database operations. - **Description**: Represents the number of threads that will be used for database operations.
### database.cassandra.provider
- **Required**: True
- **Type**: string
- **Default value**: `cassandra`
- **Constraints**: The value must be one of the following: `cassandra`, `aws_keyspace`.
- **Description**: The specific database backend provider we are using.
### database.cassandra.core_connections_per_host ### database.cassandra.core_connections_per_host
- **Required**: True - **Required**: True
@@ -165,7 +155,7 @@ This document provides a list of all available Clio configuration properties in
- **Required**: True - **Required**: True
- **Type**: boolean - **Type**: boolean
- **Default value**: `False` - **Default value**: `True`
- **Constraints**: None - **Constraints**: None
- **Description**: If set to `True`, allows Clio to start without any ETL source. - **Description**: If set to `True`, allows Clio to start without any ETL source.
@@ -293,7 +283,7 @@ This document provides a list of all available Clio configuration properties in
- **Required**: True - **Required**: True
- **Type**: int - **Type**: int
- **Default value**: `1000` - **Default value**: `1`
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`. - **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
- **Description**: The maximum size of the server's request queue. If set to `0`, this means there is no queue size limit. - **Description**: The maximum size of the server's request queue. If set to `0`, this means there is no queue size limit.
@@ -337,27 +327,11 @@ This document provides a list of all available Clio configuration properties in
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`. - **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
- **Description**: Maximum queue size for sending subscription data to clients. This queue buffers data when a client is slow to receive it, ensuring delivery once the client is ready. - **Description**: Maximum queue size for sending subscription data to clients. This queue buffers data when a client is slow to receive it, ensuring delivery once the client is ready.
### server.proxy.ips.[]
- **Required**: True
- **Type**: string
- **Default value**: None
- **Constraints**: None
- **Description**: List of proxy ip addresses. When Clio receives a request from proxy it will use `Forwarded` value (if any) as client ip. When this option is used together with `server.proxy.tokens` Clio will identify proxy by ip or by token.
### server.proxy.tokens.[]
- **Required**: True
- **Type**: string
- **Default value**: None
- **Constraints**: None
- **Description**: List of tokens in identifying request as a request from proxy. Token should be provided in `X-Proxy-Token` header, e.g. `X-Proxy-Token: <very_secret_token>'. When Clio receives a request from proxy it will use 'Forwarded` value (if any) to get client ip. When this option is used together with 'server.proxy.ips' Clio will identify proxy by ip or by token.
### prometheus.enabled ### prometheus.enabled
- **Required**: True - **Required**: True
- **Type**: boolean - **Type**: boolean
- **Default value**: `True` - **Default value**: `False`
- **Constraints**: None - **Constraints**: None
- **Description**: Enables or disables Prometheus metrics. - **Description**: Enables or disables Prometheus metrics.
@@ -365,7 +339,7 @@ This document provides a list of all available Clio configuration properties in
- **Required**: True - **Required**: True
- **Type**: boolean - **Type**: boolean
- **Default value**: `True` - **Default value**: `False`
- **Constraints**: None - **Constraints**: None
- **Description**: Enables or disables compression of Prometheus responses. - **Description**: Enables or disables compression of Prometheus responses.
@@ -391,7 +365,7 @@ This document provides a list of all available Clio configuration properties in
- **Type**: double - **Type**: double
- **Default value**: `10` - **Default value**: `10`
- **Constraints**: The value must be a positive double number. - **Constraints**: The value must be a positive double number.
- **Description**: The number of seconds the server waits to shutdown gracefully. If Clio does not shutdown gracefully after the specified value, it will be killed instead. - **Description**: The number of milliseconds the server waits to shutdown gracefully. If Clio does not shutdown gracefully after the specified value, it will be killed instead.
### cache.num_diffs ### cache.num_diffs
@@ -441,31 +415,7 @@ This document provides a list of all available Clio configuration properties in
- **Constraints**: The value must be one of the following: `sync`, `async`, `none`. - **Constraints**: The value must be one of the following: `sync`, `async`, `none`.
- **Description**: The strategy used for Cache loading. - **Description**: The strategy used for Cache loading.
### cache.file.path ### log_channels.[].channel
- **Required**: False
- **Type**: string
- **Default value**: None
- **Constraints**: None
- **Description**: The path to a file where cache will be saved to on shutdown and loaded from on startup. If the file couldn't be read Clio will load cache as usual (from DB or from rippled).
### cache.file.max_sequence_age
- **Required**: True
- **Type**: int
- **Default value**: `5000`
- **Constraints**: None
- **Description**: Max allowed difference between the latest sequence in DB and in cache file. If the cache file is too old (contains too low latest sequence) Clio will reject using it.
### cache.file.async_save
- **Required**: True
- **Type**: boolean
- **Default value**: `False`
- **Constraints**: None
- **Description**: When false, Clio waits for cache saving to finish before shutting down. When true, cache saving runs in parallel with other shutdown operations.
### log.channels.[].channel
- **Required**: False - **Required**: False
- **Type**: string - **Type**: string
@@ -473,63 +423,39 @@ This document provides a list of all available Clio configuration properties in
- **Constraints**: The value must be one of the following: `General`, `WebServer`, `Backend`, `RPC`, `ETL`, `Subscriptions`, `Performance`, `Migration`. - **Constraints**: The value must be one of the following: `General`, `WebServer`, `Backend`, `RPC`, `ETL`, `Subscriptions`, `Performance`, `Migration`.
- **Description**: The name of the log channel. - **Description**: The name of the log channel.
### log.channels.[].level ### log_channels.[].log_level
- **Required**: False - **Required**: False
- **Type**: string - **Type**: string
- **Default value**: None - **Default value**: None
- **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`. - **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`, `count`.
- **Description**: The log level for the specific log channel. - **Description**: The log level for the specific log channel.
### log.level ### log_level
- **Required**: True - **Required**: True
- **Type**: string - **Type**: string
- **Default value**: `info` - **Default value**: `info`
- **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`. - **Constraints**: The value must be one of the following: `trace`, `debug`, `info`, `warning`, `error`, `fatal`, `count`.
- **Description**: The general logging level of Clio. This level is applied to all log channels that do not have an explicitly defined logging level. - **Description**: The general logging level of Clio. This level is applied to all log channels that do not have an explicitly defined logging level.
### log.format ### log_format
- **Required**: True - **Required**: True
- **Type**: string - **Type**: string
- **Default value**: `%Y-%m-%d %H:%M:%S.%f %^%3!l:%n%$ - %v` - **Default value**: `%TimeStamp% (%SourceLocation%) [%ThreadID%] %Channel%:%Severity% %Message%`
- **Constraints**: None - **Constraints**: None
- **Description**: The format string for log messages using spdlog format patterns. - **Description**: The format string for log messages. The format is described here: <https://www.boost.org/doc/libs/1_83_0/libs/log/doc/html/log/tutorial/formatters.html>.
Each of the variables expands like so: ### log_to_console
- `%Y-%m-%d %H:%M:%S.%f`: The full date and time of the log entry with microsecond precision
- `%^`: Start color range
- `%3!l`: The severity (aka log level) the entry was sent at stripped to 3 characters
- `%n`: The logger name (channel) that this log entry was sent to
- `%$`: End color range
- `%v`: The actual log message
Some additional variables that might be useful:
- `%@`: A partial path to the C++ file and the line number in the said file (`src/file/path:linenumber`)
- `%t`: The ID of the thread the log entry is written from
Documentation can be found at: <https://github.com/gabime/spdlog/wiki/Custom-formatting>.
### log.is_async
- **Required**: True - **Required**: True
- **Type**: boolean - **Type**: boolean
- **Default value**: `True` - **Default value**: `True`
- **Constraints**: None - **Constraints**: None
- **Description**: Whether spdlog is asynchronous or not.
### log.enable_console
- **Required**: True
- **Type**: boolean
- **Default value**: `False`
- **Constraints**: None
- **Description**: Enables or disables logging to the console. - **Description**: Enables or disables logging to the console.
### log.directory ### log_directory
- **Required**: False - **Required**: False
- **Type**: string - **Type**: string
@@ -537,7 +463,7 @@ Documentation can be found at: <https://github.com/gabime/spdlog/wiki/Custom-for
- **Constraints**: None - **Constraints**: None
- **Description**: The directory path for the log files. - **Description**: The directory path for the log files.
### log.rotation_size ### log_rotation_size
- **Required**: True - **Required**: True
- **Type**: int - **Type**: int
@@ -545,15 +471,23 @@ Documentation can be found at: <https://github.com/gabime/spdlog/wiki/Custom-for
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`. - **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
- **Description**: The log rotation size in megabytes. When the log file reaches this particular size, a new log file starts. - **Description**: The log rotation size in megabytes. When the log file reaches this particular size, a new log file starts.
### log.directory_max_files ### log_directory_max_size
- **Required**: True - **Required**: True
- **Type**: int - **Type**: int
- **Default value**: `25` - **Default value**: `51200`
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`. - **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
- **Description**: The maximum number of log files in the directory. - **Description**: The maximum size of the log directory in megabytes.
### log.tag_style ### log_rotation_hour_interval
- **Required**: True
- **Type**: int
- **Default value**: `12`
- **Constraints**: The minimum value is `1`. The maximum value is `4294967295`.
- **Description**: Represents the interval (in hours) for log rotation. If the current log file reaches this value in logging, a new log file starts.
### log_tag_style
- **Required**: True - **Required**: True
- **Type**: string - **Type**: string
@@ -573,7 +507,7 @@ Documentation can be found at: <https://github.com/gabime/spdlog/wiki/Custom-for
- **Required**: True - **Required**: True
- **Type**: boolean - **Type**: boolean
- **Default value**: `False` - **Default value**: `True`
- **Constraints**: None - **Constraints**: None
- **Description**: Indicates if the server is allowed to write data to the database. - **Description**: Indicates if the server is allowed to write data to the database.

View File

@@ -5,6 +5,7 @@
Clio needs access to a `rippled` server in order to work. The following configurations are required for Clio and `rippled` to communicate: Clio needs access to a `rippled` server in order to work. The following configurations are required for Clio and `rippled` to communicate:
1. In the Clio config file, provide the following: 1. In the Clio config file, provide the following:
- The IP of the `rippled` server - The IP of the `rippled` server
- The port on which `rippled` is accepting unencrypted WebSocket connections - The port on which `rippled` is accepting unencrypted WebSocket connections
@@ -12,6 +13,7 @@ Clio needs access to a `rippled` server in order to work. The following configur
- The port on which `rippled` is handling gRPC requests - The port on which `rippled` is handling gRPC requests
2. In the `rippled` config file, you need to open: 2. In the `rippled` config file, you need to open:
- A port to accept unencrypted WebSocket connections - A port to accept unencrypted WebSocket connections
- A port to handle gRPC requests, with the IP(s) of Clio specified in the `secure_gateway` entry - A port to handle gRPC requests, with the IP(s) of Clio specified in the `secure_gateway` entry
@@ -88,15 +90,13 @@ Exactly equal password gains admin rights for the request or a websocket connect
Clio can cache requests to ETL sources to reduce the load on the ETL source. Clio can cache requests to ETL sources to reduce the load on the ETL source.
Only following commands are cached: `server_info`, `server_state`, `server_definitions`, `fee`, `ledger_closed`. Only following commands are cached: `server_info`, `server_state`, `server_definitions`, `fee`, `ledger_closed`.
By default the forwarding cache is off. By default the forwarding cache is off.
To enable the caching for a source, `forwarding.cache_timeout` value should be added to the configuration file, e.g.: To enable the caching for a source, `forwarding_cache_timeout` value should be added to the configuration file, e.g.:
```json ```json
"forwarding": { "forwarding_cache_timeout": 0.250,
"cache_timeout": 0.250,
}
``` ```
`forwarding.cache_timeout` defines for how long (in seconds) a cache entry will be valid after being placed into the cache. `forwarding_cache_timeout` defines for how long (in seconds) a cache entry will be valid after being placed into the cache.
Zero value turns off the cache feature. Zero value turns off the cache feature.
## Graceful shutdown (not fully implemented yet) ## Graceful shutdown (not fully implemented yet)

View File

@@ -1,10 +1,29 @@
// SPDX-License-Identifier: MIT
/** /**
Doxygen Awesome Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css https://github.com/jothepro/doxygen-awesome-css
Copyright (c) 2021 - 2025 jothepro MIT License
Copyright (c) 2021 - 2023 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/ */

View File

@@ -1,66 +0,0 @@
// SPDX-License-Identifier: MIT
/**
Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css
Copyright (c) 2022 - 2025 jothepro
*/
class DoxygenAwesomeFragmentCopyButton extends HTMLElement {
constructor() {
super();
this.onclick=this.copyContent
}
static title = "Copy to clipboard"
static copyIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M23.04,10.322c0,-2.582 -2.096,-4.678 -4.678,-4.678l-6.918,-0c-2.582,-0 -4.678,2.096 -4.678,4.678c0,-0 0,8.04 0,8.04c0,2.582 2.096,4.678 4.678,4.678c0,-0 6.918,-0 6.918,-0c2.582,-0 4.678,-2.096 4.678,-4.678c0,-0 0,-8.04 0,-8.04Zm-2.438,-0l-0,8.04c-0,1.236 -1.004,2.24 -2.24,2.24l-6.918,-0c-1.236,-0 -2.239,-1.004 -2.239,-2.24l-0,-8.04c-0,-1.236 1.003,-2.24 2.239,-2.24c0,0 6.918,0 6.918,0c1.236,0 2.24,1.004 2.24,2.24Z"/><path d="M5.327,16.748c-0,0.358 -0.291,0.648 -0.649,0.648c0,0 0,0 0,0c-2.582,0 -4.678,-2.096 -4.678,-4.678c0,0 0,-8.04 0,-8.04c0,-2.582 2.096,-4.678 4.678,-4.678l6.918,0c2.168,0 3.994,1.478 4.523,3.481c0.038,0.149 0.005,0.306 -0.09,0.428c-0.094,0.121 -0.239,0.191 -0.392,0.191c-0.451,0.005 -1.057,0.005 -1.457,0.005c-0.238,0 -0.455,-0.14 -0.553,-0.357c-0.348,-0.773 -1.128,-1.31 -2.031,-1.31c-0,0 -6.918,0 -6.918,0c-1.236,0 -2.24,1.004 -2.24,2.24l0,8.04c0,1.236 1.004,2.24 2.24,2.24l0,-0c0.358,-0 0.649,0.29 0.649,0.648c-0,0.353 -0,0.789 -0,1.142Z" style="fill-opacity:0.6;"/></svg>`
static successIcon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path d="M8.084,16.111c-0.09,0.09 -0.212,0.141 -0.34,0.141c-0.127,-0 -0.249,-0.051 -0.339,-0.141c-0.746,-0.746 -2.538,-2.538 -3.525,-3.525c-0.375,-0.375 -0.983,-0.375 -1.357,0c-0.178,0.178 -0.369,0.369 -0.547,0.547c-0.375,0.375 -0.375,0.982 -0,1.357c1.135,1.135 3.422,3.422 4.75,4.751c0.27,0.27 0.637,0.421 1.018,0.421c0.382,0 0.749,-0.151 1.019,-0.421c2.731,-2.732 10.166,-10.167 12.454,-12.455c0.375,-0.375 0.375,-0.982 -0,-1.357c-0.178,-0.178 -0.369,-0.369 -0.547,-0.547c-0.375,-0.375 -0.982,-0.375 -1.357,0c-2.273,2.273 -9.567,9.567 -11.229,11.229Z"/></svg>`
static successDuration = 980
static init() {
$(function() {
$(document).ready(function() {
if(navigator.clipboard) {
const fragments = document.getElementsByClassName("fragment")
for(const fragment of fragments) {
const fragmentWrapper = document.createElement("div")
fragmentWrapper.className = "doxygen-awesome-fragment-wrapper"
const fragmentCopyButton = document.createElement("doxygen-awesome-fragment-copy-button")
fragmentCopyButton.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon
fragmentCopyButton.title = DoxygenAwesomeFragmentCopyButton.title
fragment.parentNode.replaceChild(fragmentWrapper, fragment)
fragmentWrapper.appendChild(fragment)
fragmentWrapper.appendChild(fragmentCopyButton)
}
}
})
})
}
copyContent() {
const content = this.previousSibling.cloneNode(true)
// filter out line number from file listings
content.querySelectorAll(".lineno, .ttc").forEach((node) => {
node.remove()
})
let textContent = content.textContent
// remove trailing newlines that appear in file listings
let numberOfTrailingNewlines = 0
while(textContent.charAt(textContent.length - (numberOfTrailingNewlines + 1)) == '\n') {
numberOfTrailingNewlines++;
}
textContent = textContent.substring(0, textContent.length - numberOfTrailingNewlines)
navigator.clipboard.writeText(textContent);
this.classList.add("success")
this.innerHTML = DoxygenAwesomeFragmentCopyButton.successIcon
window.setTimeout(() => {
this.classList.remove("success")
this.innerHTML = DoxygenAwesomeFragmentCopyButton.copyIcon
}, DoxygenAwesomeFragmentCopyButton.successDuration);
}
}
customElements.define("doxygen-awesome-fragment-copy-button", DoxygenAwesomeFragmentCopyButton)

View File

@@ -1,10 +1,29 @@
// SPDX-License-Identifier: MIT
/** /**
Doxygen Awesome Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css https://github.com/jothepro/doxygen-awesome-css
Copyright (c) 2022 - 2025 jothepro MIT License
Copyright (c) 2022 - 2023 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/ */
@@ -36,7 +55,9 @@ class DoxygenAwesomeInteractiveToc {
headerNode: document.getElementById(id) headerNode: document.getElementById(id)
}) })
document.getElementById("doc-content")?.addEventListener("scroll",this.throttle(DoxygenAwesomeInteractiveToc.update, 100)) document.getElementById("doc-content")?.addEventListener("scroll", () => {
DoxygenAwesomeInteractiveToc.update()
})
}) })
DoxygenAwesomeInteractiveToc.update() DoxygenAwesomeInteractiveToc.update()
} }
@@ -57,16 +78,4 @@ class DoxygenAwesomeInteractiveToc {
active?.classList.add("active") active?.classList.add("active")
active?.classList.remove("aboveActive") active?.classList.remove("aboveActive")
} }
static throttle(func, delay) {
let lastCall = 0;
return function (...args) {
const now = new Date().getTime();
if (now - lastCall < delay) {
return;
}
lastCall = now;
return setTimeout(() => {func(...args)}, delay);
};
}
} }

View File

@@ -1,10 +1,30 @@
/* SPDX-License-Identifier: MIT */
/** /**
Doxygen Awesome Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css https://github.com/jothepro/doxygen-awesome-css
Copyright (c) 2021 - 2025 jothepro MIT License
Copyright (c) 2021 - 2023 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/ */

View File

@@ -1,10 +1,29 @@
/* SPDX-License-Identifier: MIT */
/** /**
Doxygen Awesome Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css https://github.com/jothepro/doxygen-awesome-css
Copyright (c) 2021 - 2025 jothepro MIT License
Copyright (c) 2021 - 2023 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/ */
@@ -41,6 +60,10 @@ html {
height: calc(100vh - var(--top-height)) !important; height: calc(100vh - var(--top-height)) !important;
} }
#nav-tree {
padding: 0;
}
#top { #top {
display: block; display: block;
border-bottom: none; border-bottom: none;
@@ -50,24 +73,22 @@ html {
overflow: hidden; overflow: hidden;
background: var(--side-nav-background); background: var(--side-nav-background);
} }
#main-nav { #main-nav {
float: left; float: left;
padding-right: 0; padding-right: 0;
} }
.ui-resizable-handle { .ui-resizable-handle {
display: none; cursor: default;
} width: 1px !important;
background: var(--separator-color);
.ui-resizable-e { box-shadow: 0 calc(-2 * var(--top-height)) 0 0 var(--separator-color);
width: 0;
} }
#nav-path { #nav-path {
position: fixed; position: fixed;
right: 0; right: 0;
left: calc(var(--side-nav-fixed-width) + 1px); left: var(--side-nav-fixed-width);
bottom: 0; bottom: 0;
width: auto; width: auto;
} }
@@ -92,14 +113,4 @@ html {
left: var(--spacing-medium) !important; left: var(--spacing-medium) !important;
right: auto; right: auto;
} }
#nav-sync {
bottom: 4px;
right: auto;
left: 300px;
width: 35px;
top: auto !important;
user-select: none;
position: fixed
}
} }

View File

@@ -1,10 +1,29 @@
/* SPDX-License-Identifier: MIT */
/** /**
Doxygen Awesome Doxygen Awesome
https://github.com/jothepro/doxygen-awesome-css https://github.com/jothepro/doxygen-awesome-css
Copyright (c) 2021 - 2025 jothepro MIT License
Copyright (c) 2021 - 2023 jothepro
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/ */
@@ -13,9 +32,6 @@ html {
--primary-color: #1779c4; --primary-color: #1779c4;
--primary-dark-color: #335c80; --primary-dark-color: #335c80;
--primary-light-color: #70b1e9; --primary-light-color: #70b1e9;
--on-primary-color: #ffffff;
--link-color: var(--primary-color);
/* page base colors */ /* page base colors */
--page-background-color: #ffffff; --page-background-color: #ffffff;
@@ -26,15 +42,14 @@ html {
--separator-color: #dedede; --separator-color: #dedede;
/* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */ /* border radius for all rounded components. Will affect many components, like dropdowns, memitems, codeblocks, ... */
--border-radius-large: 10px; --border-radius-large: 8px;
--border-radius-small: 5px; --border-radius-small: 4px;
--border-radius-medium: 8px; --border-radius-medium: 6px;
/* default spacings. Most components reference these values for spacing, to provide uniform spacing on the page. */ /* default spacings. Most components reference these values for spacing, to provide uniform spacing on the page. */
--spacing-small: 5px; --spacing-small: 5px;
--spacing-medium: 10px; --spacing-medium: 10px;
--spacing-large: 16px; --spacing-large: 16px;
--spacing-xlarge: 20px;
/* default box shadow used for raising an element above the normal content. Used in dropdowns, search result, ... */ /* default box shadow used for raising an element above the normal content. Used in dropdowns, search result, ... */
--box-shadow: 0 2px 8px 0 rgba(0,0,0,.075); --box-shadow: 0 2px 8px 0 rgba(0,0,0,.075);
@@ -98,7 +113,7 @@ html {
*/ */
--menu-display: block; --menu-display: block;
--menu-focus-foreground: var(--on-primary-color); --menu-focus-foreground: var(--page-background-color);
--menu-focus-background: var(--primary-color); --menu-focus-background: var(--primary-color);
--menu-selected-background: rgba(0,0,0,.05); --menu-selected-background: rgba(0,0,0,.05);
@@ -295,11 +310,10 @@ body {
font-size: var(--page-font-size); font-size: var(--page-font-size);
} }
body, table, div, p, dl, #nav-tree .label, #nav-tree a, .title, body, table, div, p, dl, #nav-tree .label, .title,
.sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname, .sm-dox a, .sm-dox a:hover, .sm-dox a:focus, #projectname,
.SelectItem, #MSearchField, .navpath li.navelem a, .SelectItem, #MSearchField, .navpath li.navelem a,
.navpath li.navelem a:hover, p.reference, p.definition, div.toc li, div.toc h3, .navpath li.navelem a:hover, p.reference, p.definition, div.toc li, div.toc h3 {
#page-nav ul.page-outline li a {
font-family: var(--font-family); font-family: var(--font-family);
} }
@@ -318,13 +332,8 @@ p.reference, p.definition {
} }
a:link, a:visited, a:hover, a:focus, a:active { a:link, a:visited, a:hover, a:focus, a:active {
color: var(--link-color) !important; color: var(--primary-color) !important;
font-weight: 500; font-weight: 500;
background: none;
}
a:hover {
text-decoration: underline;
} }
a.anchor { a.anchor {
@@ -339,8 +348,6 @@ a.anchor {
#top { #top {
background: var(--header-background); background: var(--header-background);
border-bottom: 1px solid var(--separator-color); border-bottom: 1px solid var(--separator-color);
position: relative;
z-index: 99;
} }
@media screen and (min-width: 768px) { @media screen and (min-width: 768px) {
@@ -355,7 +362,6 @@ a.anchor {
#main-nav { #main-nav {
flex-grow: 5; flex-grow: 5;
padding: var(--spacing-small) var(--spacing-medium); padding: var(--spacing-small) var(--spacing-medium);
border-bottom: 0;
} }
#titlearea { #titlearea {
@@ -435,36 +441,19 @@ a.anchor {
} }
.sm-dox a span.sub-arrow { .sm-dox a span.sub-arrow {
top: 15px; border-color: var(--header-foreground) transparent transparent transparent;
right: 10px;
box-sizing: content-box;
padding: 0;
margin: 0;
display: inline-block;
width: 5px;
height: 5px;
transform: rotate(45deg);
border-width: 0;
border-right: 2px solid var(--header-foreground);
border-bottom: 2px solid var(--header-foreground);
background: none;
} }
.sm-dox a:hover span.sub-arrow { .sm-dox a:hover span.sub-arrow {
border-color: var(--menu-focus-foreground); border-color: var(--menu-focus-foreground) transparent transparent transparent;
background: none;
} }
.sm-dox ul a span.sub-arrow { .sm-dox ul a span.sub-arrow {
transform: rotate(-45deg); border-color: transparent transparent transparent var(--page-foreground-color);
border-width: 0;
border-right: 2px solid var(--header-foreground);
border-bottom: 2px solid var(--header-foreground);
} }
.sm-dox ul a:hover span.sub-arrow { .sm-dox ul a:hover span.sub-arrow {
border-color: var(--menu-focus-foreground); border-color: transparent transparent transparent var(--menu-focus-foreground);
background: none;
} }
} }
@@ -491,7 +480,7 @@ a.anchor {
.sm-dox ul a { .sm-dox ul a {
color: var(--page-foreground-color) !important; color: var(--page-foreground-color) !important;
background: none; background: var(--page-background-color);
font-size: var(--navigation-font-size); font-size: var(--navigation-font-size);
} }
@@ -563,13 +552,6 @@ a.anchor {
box-shadow: none; box-shadow: none;
display: block; display: block;
margin-top: 0; margin-top: 0;
margin-right: 0;
}
@media (min-width: 768px) {
.sm-dox li {
padding: 0;
}
} }
/* until Doxygen 1.9.4 */ /* until Doxygen 1.9.4 */
@@ -591,17 +573,6 @@ a.anchor {
padding-left: 0 padding-left: 0
} }
/* Doxygen 1.14.0 */
.search-icon::before {
background: none;
top: 5px;
}
.search-icon::after {
background: none;
top: 12px;
}
.SelectionMark { .SelectionMark {
user-select: none; user-select: none;
} }
@@ -805,15 +776,12 @@ html.dark-mode iframe#MSearchResults {
*/ */
#side-nav { #side-nav {
padding: 0 !important;
background: var(--side-nav-background);
min-width: 8px; min-width: 8px;
max-width: 50vw; max-width: 50vw;
} }
#nav-tree, #top {
border-right: 1px solid var(--separator-color);
}
@media screen and (max-width: 767px) { @media screen and (max-width: 767px) {
#side-nav { #side-nav {
display: none; display: none;
@@ -822,95 +790,34 @@ html.dark-mode iframe#MSearchResults {
#doc-content { #doc-content {
margin-left: 0 !important; margin-left: 0 !important;
} }
#top {
border-right: none;
}
} }
#nav-tree { #nav-tree {
background: var(--side-nav-background); background: transparent;
margin-right: -1px; margin-right: 1px;
padding: 0;
} }
#nav-tree .label { #nav-tree .label {
font-size: var(--navigation-font-size); font-size: var(--navigation-font-size);
line-height: var(--tree-item-height);
}
#nav-tree span.label a:hover {
background: none;
} }
#nav-tree .item { #nav-tree .item {
height: var(--tree-item-height); height: var(--tree-item-height);
line-height: var(--tree-item-height); line-height: var(--tree-item-height);
overflow: hidden;
text-overflow: ellipsis;
margin: 0;
padding: 0;
}
#nav-tree-contents {
margin: 0;
}
#main-menu > li:last-child {
height: auto;
}
#nav-tree .item > a:focus {
outline: none;
} }
#nav-sync { #nav-sync {
bottom: var(--spacing-medium); bottom: 12px;
right: var(--spacing-medium) !important; right: 12px;
top: auto !important; top: auto !important;
user-select: none; user-select: none;
} }
div.nav-sync-icon {
border: 1px solid var(--separator-color);
border-radius: var(--border-radius-medium);
background: var(--page-background-color);
width: 30px;
height: 20px;
}
div.nav-sync-icon:hover {
background: var(--page-background-color);
}
span.sync-icon-left, div.nav-sync-icon:hover span.sync-icon-left {
border-left: 2px solid var(--primary-color);
border-top: 2px solid var(--primary-color);
top: 5px;
left: 6px;
}
span.sync-icon-right, div.nav-sync-icon:hover span.sync-icon-right {
border-right: 2px solid var(--primary-color);
border-bottom: 2px solid var(--primary-color);
top: 5px;
left: initial;
right: 6px;
}
div.nav-sync-icon.active::after, div.nav-sync-icon.active:hover::after {
border-top: 2px solid var(--primary-color);
top: 9px;
left: 6px;
width: 19px;
}
#nav-tree .selected { #nav-tree .selected {
text-shadow: none; text-shadow: none;
background-image: none; background-image: none;
background-color: transparent; background-color: transparent;
position: relative; position: relative;
color: var(--primary-color) !important;
font-weight: 500;
} }
#nav-tree .selected::after { #nav-tree .selected::after {
@@ -936,27 +843,9 @@ div.nav-sync-icon.active::after, div.nav-sync-icon.active:hover::after {
#nav-tree .arrow { #nav-tree .arrow {
opacity: var(--side-nav-arrow-opacity); opacity: var(--side-nav-arrow-opacity);
background: none;
} }
#nav-tree span.arrowhead { .arrow {
margin: 0 0 1px 2px;
}
span.arrowhead {
border-color: var(--primary-light-color);
}
.selected span.arrowhead {
border-color: var(--primary-color);
}
#nav-tree-contents > ul > li:first-child > div > a {
opacity: 0;
pointer-events: none;
}
.contents .arrow {
color: inherit; color: inherit;
cursor: pointer; cursor: pointer;
font-size: 45%; font-size: 45%;
@@ -964,7 +853,7 @@ span.arrowhead {
margin-right: 2px; margin-right: 2px;
font-family: serif; font-family: serif;
height: auto; height: auto;
padding-bottom: 4px; text-align: right;
} }
#nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow { #nav-tree div.item:hover .arrow, #nav-tree a:focus .arrow {
@@ -978,11 +867,9 @@ span.arrowhead {
} }
.ui-resizable-e { .ui-resizable-e {
background: none; width: 4px;
} background: transparent;
box-shadow: inset -1px 0 0 0 var(--separator-color);
.ui-resizable-e:hover {
background: var(--separator-color);
} }
/* /*
@@ -991,7 +878,7 @@ span.arrowhead {
div.header { div.header {
border-bottom: 1px solid var(--separator-color); border-bottom: 1px solid var(--separator-color);
background: none; background-color: var(--page-background-color);
background-image: none; background-image: none;
} }
@@ -1030,7 +917,7 @@ div.headertitle {
div.header .title { div.header .title {
font-weight: 600; font-weight: 600;
font-size: 225%; font-size: 225%;
padding: var(--spacing-medium) var(--spacing-xlarge); padding: var(--spacing-medium) var(--spacing-large);
word-break: break-word; word-break: break-word;
} }
@@ -1047,10 +934,9 @@ td.memSeparator {
span.mlabel { span.mlabel {
background: var(--primary-color); background: var(--primary-color);
color: var(--on-primary-color);
border: none; border: none;
padding: 4px 9px; padding: 4px 9px;
border-radius: var(--border-radius-large); border-radius: 12px;
margin-right: var(--spacing-medium); margin-right: var(--spacing-medium);
} }
@@ -1059,7 +945,7 @@ span.mlabel:last-of-type {
} }
div.contents { div.contents {
padding: 0 var(--spacing-xlarge); padding: 0 var(--spacing-large);
} }
div.contents p, div.contents li { div.contents p, div.contents li {
@@ -1070,16 +956,6 @@ div.contents div.dyncontent {
margin: var(--spacing-medium) 0; margin: var(--spacing-medium) 0;
} }
@media screen and (max-width: 767px) {
div.contents {
padding: 0 var(--spacing-large);
}
div.header .title {
padding: var(--spacing-medium) var(--spacing-large);
}
}
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
html:not(.light-mode) div.contents div.dyncontent img, html:not(.light-mode) div.contents div.dyncontent img,
html:not(.light-mode) div.contents center img, html:not(.light-mode) div.contents center img,
@@ -1103,7 +979,7 @@ html.dark-mode div.contents .dotgraph iframe
filter: brightness(89%) hue-rotate(180deg) invert(); filter: brightness(89%) hue-rotate(180deg) invert();
} }
td h2.groupheader, h2.groupheader { h2.groupheader {
border-bottom: 0px; border-bottom: 0px;
color: var(--page-foreground-color); color: var(--page-foreground-color);
box-shadow: box-shadow:
@@ -1164,7 +1040,7 @@ blockquote::after {
blockquote p { blockquote p {
margin: var(--spacing-small) 0 var(--spacing-medium) 0; margin: var(--spacing-small) 0 var(--spacing-medium) 0;
} }
.paramname, .paramname em { .paramname {
font-weight: 600; font-weight: 600;
color: var(--primary-dark-color); color: var(--primary-dark-color);
} }
@@ -1214,7 +1090,7 @@ div.contents .toc {
border: 0; border: 0;
border-left: 1px solid var(--separator-color); border-left: 1px solid var(--separator-color);
border-radius: 0; border-radius: 0;
background-color: var(--page-background-color); background-color: transparent;
box-shadow: none; box-shadow: none;
position: sticky; position: sticky;
top: var(--toc-sticky-top); top: var(--toc-sticky-top);
@@ -1322,115 +1198,24 @@ div.toc li a.aboveActive {
} }
} }
/*
Page Outline (Doxygen >= 1.14.0)
*/
#page-nav {
background: var(--page-background-color);
border-left: 1px solid var(--separator-color);
}
#page-nav #page-nav-resize-handle {
background: var(--separator-color);
}
#page-nav #page-nav-resize-handle::after {
border-left: 1px solid var(--primary-color);
border-right: 1px solid var(--primary-color);
}
#page-nav #page-nav-tree #page-nav-contents {
top: var(--spacing-large);
}
#page-nav ul.page-outline {
margin: 0;
padding: 0;
}
#page-nav ul.page-outline li a {
font-size: var(--toc-font-size) !important;
color: var(--page-secondary-foreground-color) !important;
display: inline-block;
line-height: calc(2 * var(--toc-font-size));
}
#page-nav ul.page-outline li a a.anchorlink {
display: none;
}
#page-nav ul.page-outline li.vis ~ * a {
color: var(--page-foreground-color) !important;
}
#page-nav ul.page-outline li.vis:not(.vis ~ .vis) a, #page-nav ul.page-outline li a:hover {
color: var(--primary-color) !important;
}
#page-nav ul.page-outline .vis {
background: var(--page-background-color);
position: relative;
}
#page-nav ul.page-outline .vis::after {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 4px;
background: var(--page-secondary-foreground-color);
}
#page-nav ul.page-outline .vis:not(.vis ~ .vis)::after {
top: 1px;
border-top-right-radius: var(--border-radius-small);
}
#page-nav ul.page-outline .vis:not(:has(~ .vis))::after {
bottom: 1px;
border-bottom-right-radius: var(--border-radius-small);
}
#page-nav ul.page-outline .arrow {
display: inline-block;
}
#page-nav ul.page-outline .arrow span {
display: none;
}
@media screen and (max-width: 767px) {
#container {
grid-template-columns: initial !important;
}
#page-nav {
display: none;
}
}
/* /*
Code & Fragments Code & Fragments
*/ */
code, div.fragment, pre.fragment, span.tt { code, div.fragment, pre.fragment {
border-radius: var(--border-radius-small);
border: 1px solid var(--separator-color); border: 1px solid var(--separator-color);
overflow: hidden; overflow: hidden;
} }
code, span.tt { code {
display: inline; display: inline;
background: var(--code-background); background: var(--code-background);
color: var(--code-foreground); color: var(--code-foreground);
padding: 2px 6px; padding: 2px 6px;
border-radius: var(--border-radius-small);
} }
div.fragment, pre.fragment { div.fragment, pre.fragment {
border-radius: var(--border-radius-medium);
margin: var(--spacing-medium) 0; margin: var(--spacing-medium) 0;
padding: calc(var(--spacing-large) - (var(--spacing-large) / 6)) var(--spacing-large); padding: calc(var(--spacing-large) - (var(--spacing-large) / 6)) var(--spacing-large);
background: var(--fragment-background); background: var(--fragment-background);
@@ -1488,7 +1273,7 @@ div.fragment, pre.fragment {
} }
} }
code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span, span.tt { code, code a, pre.fragment, div.fragment, div.fragment .line, div.fragment span, div.fragment .line a, div.fragment .line span {
font-family: var(--font-family-monospace); font-family: var(--font-family-monospace);
font-size: var(--code-font-size) !important; font-size: var(--code-font-size) !important;
} }
@@ -1562,10 +1347,6 @@ div.line.glow {
dl warning, attention, note, deprecated, bug, ... dl warning, attention, note, deprecated, bug, ...
*/ */
dl {
line-height: calc(1.65 * var(--page-font-size));
}
dl.bug dt a, dl.deprecated dt a, dl.todo dt a { dl.bug dt a, dl.deprecated dt a, dl.todo dt a {
font-weight: bold !important; font-weight: bold !important;
} }
@@ -1731,7 +1512,6 @@ div.memitem {
border-top-right-radius: var(--border-radius-medium); border-top-right-radius: var(--border-radius-medium);
border-bottom-right-radius: var(--border-radius-medium); border-bottom-right-radius: var(--border-radius-medium);
border-bottom-left-radius: var(--border-radius-medium); border-bottom-left-radius: var(--border-radius-medium);
border-top-left-radius: 0;
overflow: hidden; overflow: hidden;
display: block !important; display: block !important;
} }
@@ -1963,7 +1743,7 @@ table.fieldtable th {
color: var(--tablehead-foreground); color: var(--tablehead-foreground);
} }
table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fieldinit, .fieldtable td.fielddoc, .fieldtable th { table.fieldtable td.fieldtype, .fieldtable td.fieldname, .fieldtable td.fielddoc, .fieldtable th {
border-bottom: 1px solid var(--separator-color); border-bottom: 1px solid var(--separator-color);
border-right: 1px solid var(--separator-color); border-right: 1px solid var(--separator-color);
} }
@@ -1998,10 +1778,8 @@ table.memberdecls tr[class^='memitem'] .memTemplParams {
white-space: normal; white-space: normal;
} }
table.memberdecls tr.heading + tr[class^='memitem'] td.memItemLeft, table.memberdecls .memItemLeft,
table.memberdecls tr.heading + tr[class^='memitem'] td.memItemRight, table.memberdecls .memItemRight,
table.memberdecls td.memItemLeft,
table.memberdecls td.memItemRight,
table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemLeft,
table.memberdecls .memTemplItemRight, table.memberdecls .memTemplItemRight,
table.memberdecls .memTemplParams { table.memberdecls .memTemplParams {
@@ -2013,34 +1791,8 @@ table.memberdecls .memTemplParams {
background-color: var(--fragment-background); background-color: var(--fragment-background);
} }
@media screen and (min-width: 768px) {
tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight {
border-top-right-radius: var(--border-radius-small);
}
table.memberdecls tr:last-child td.memItemRight, table.memberdecls tr:last-child td.mdescRight, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemRight, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemRight, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescRight, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescRight {
border-bottom-right-radius: var(--border-radius-small);
}
table.memberdecls tr:last-child td.memItemLeft, table.memberdecls tr:last-child td.mdescLeft, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemLeft, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescLeft {
border-bottom-left-radius: var(--border-radius-small);
}
tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft {
border-top-left-radius: var(--border-radius-small);
}
}
table.memname td.memname {
font-size: var(--memname-font-size);
}
table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemLeft,
table.memberdecls .template .memItemLeft, table.memberdecls .memTemplItemRight {
table.memberdecls .memTemplItemRight,
table.memberdecls .template .memItemRight {
padding-top: 2px; padding-top: 2px;
} }
@@ -2052,13 +1804,13 @@ table.memberdecls .memTemplParams {
padding-bottom: var(--spacing-small); padding-bottom: var(--spacing-small);
} }
table.memberdecls .memTemplItemLeft, table.memberdecls .template .memItemLeft { table.memberdecls .memTemplItemLeft {
border-radius: 0 0 0 var(--border-radius-small); border-radius: 0 0 0 var(--border-radius-small);
border-left: 1px solid var(--separator-color); border-left: 1px solid var(--separator-color);
border-top: 0; border-top: 0;
} }
table.memberdecls .memTemplItemRight, table.memberdecls .template .memItemRight { table.memberdecls .memTemplItemRight {
border-radius: 0 0 var(--border-radius-small) 0; border-radius: 0 0 var(--border-radius-small) 0;
border-right: 1px solid var(--separator-color); border-right: 1px solid var(--separator-color);
padding-left: 0; padding-left: 0;
@@ -2084,14 +1836,8 @@ table.memberdecls .mdescLeft, table.memberdecls .mdescRight {
background: none; background: none;
color: var(--page-foreground-color); color: var(--page-foreground-color);
padding: var(--spacing-small) 0; padding: var(--spacing-small) 0;
border: 0;
} }
table.memberdecls [class^="memdesc"] {
box-shadow: none;
}
table.memberdecls .memItemLeft, table.memberdecls .memItemLeft,
table.memberdecls .memTemplItemLeft { table.memberdecls .memTemplItemLeft {
padding-right: var(--spacing-medium); padding-right: var(--spacing-medium);
@@ -2114,10 +1860,6 @@ table.memberdecls .inherit_header td {
color: var(--page-secondary-foreground-color); color: var(--page-secondary-foreground-color);
} }
table.memberdecls span.dynarrow {
left: 10px;
}
table.memberdecls img[src="closed.png"], table.memberdecls img[src="closed.png"],
table.memberdecls img[src="open.png"], table.memberdecls img[src="open.png"],
div.dynheader img[src="open.png"], div.dynheader img[src="open.png"],
@@ -2134,10 +1876,6 @@ div.dynheader img[src="closed.png"] {
transition: transform var(--animation-duration) ease-out; transition: transform var(--animation-duration) ease-out;
} }
tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft, tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight {
border-top: 1px solid var(--separator-color);
}
table.memberdecls img { table.memberdecls img {
margin-right: 10px; margin-right: 10px;
} }
@@ -2162,10 +1900,7 @@ div.dynheader img[src="closed.png"] {
table.memberdecls .mdescRight, table.memberdecls .mdescRight,
table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemLeft,
table.memberdecls .memTemplItemRight, table.memberdecls .memTemplItemRight,
table.memberdecls .memTemplParams, table.memberdecls .memTemplParams {
table.memberdecls .template .memItemLeft,
table.memberdecls .template .memItemRight,
table.memberdecls .template .memParams {
display: block; display: block;
text-align: left; text-align: left;
padding-left: var(--spacing-large); padding-left: var(--spacing-large);
@@ -2178,14 +1913,12 @@ div.dynheader img[src="closed.png"] {
table.memberdecls .memItemLeft, table.memberdecls .memItemLeft,
table.memberdecls .mdescLeft, table.memberdecls .mdescLeft,
table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemLeft {
table.memberdecls .template .memItemLeft { border-bottom: 0;
border-bottom: 0 !important; padding-bottom: 0;
padding-bottom: 0 !important;
} }
table.memberdecls .memTemplItemLeft, table.memberdecls .memTemplItemLeft {
table.memberdecls .template .memItemLeft {
padding-top: 0; padding-top: 0;
} }
@@ -2195,12 +1928,10 @@ div.dynheader img[src="closed.png"] {
table.memberdecls .memItemRight, table.memberdecls .memItemRight,
table.memberdecls .mdescRight, table.memberdecls .mdescRight,
table.memberdecls .memTemplItemRight, table.memberdecls .memTemplItemRight {
table.memberdecls .template .memItemRight { border-top: 0;
border-top: 0 !important; padding-top: 0;
padding-top: 0 !important;
padding-right: var(--spacing-large); padding-right: var(--spacing-large);
padding-bottom: var(--spacing-medium);
overflow-x: auto; overflow-x: auto;
} }
@@ -2235,22 +1966,6 @@ div.dynheader img[src="closed.png"] {
max-height: 200px; max-height: 200px;
} }
} }
tr.heading + tr[class^='memitem'] td.memItemRight, tr.groupHeader + tr[class^='memitem'] td.memItemRight, tr.inherit_header + tr[class^='memitem'] td.memItemRight {
border-top-right-radius: 0;
}
table.memberdecls tr:last-child td.memItemRight, table.memberdecls tr:last-child td.mdescRight, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemRight, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemRight, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescRight, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescRight {
border-bottom-right-radius: 0;
}
table.memberdecls tr:last-child td.memItemLeft, table.memberdecls tr:last-child td.mdescLeft, table.memberdecls tr[class^='memitem']:has(+ tr.groupHeader) td.memItemLeft, table.memberdecls tr[class^='memitem']:has(+ tr.inherit_header) td.memItemLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.groupHeader) td.mdescLeft, table.memberdecls tr[class^='memdesc']:has(+ tr.inherit_header) td.mdescLeft {
border-bottom-left-radius: 0;
}
tr.heading + tr[class^='memitem'] td.memItemLeft, tr.groupHeader + tr[class^='memitem'] td.memItemLeft, tr.inherit_header + tr[class^='memitem'] td.memItemLeft {
border-top-left-radius: 0;
}
} }
@@ -2267,16 +1982,14 @@ hr {
} }
.contents hr { .contents hr {
box-shadow: 100px 0 var(--separator-color), box-shadow: 100px 0 0 var(--separator-color),
-100px 0 var(--separator-color), -100px 0 0 var(--separator-color),
500px 0 var(--separator-color), 500px 0 0 var(--separator-color),
-500px 0 var(--separator-color), -500px 0 0 var(--separator-color),
900px 0 var(--separator-color), 1500px 0 0 var(--separator-color),
-900px 0 var(--separator-color), -1500px 0 0 var(--separator-color),
1400px 0 var(--separator-color), 2000px 0 0 var(--separator-color),
-1400px 0 var(--separator-color), -2000px 0 0 var(--separator-color);
1900px 0 var(--separator-color),
-1900px 0 var(--separator-color);
} }
.contents img, .contents .center, .contents center, .contents div.image object { .contents img, .contents .center, .contents center, .contents div.image object {
@@ -2439,7 +2152,9 @@ div.qindex {
background: var(--page-background-color); background: var(--page-background-color);
border: none; border: none;
border-top: 1px solid var(--separator-color); border-top: 1px solid var(--separator-color);
border-bottom: 1px solid var(--separator-color);
border-bottom: 0; border-bottom: 0;
box-shadow: 0 0.75px 0 var(--separator-color);
font-size: var(--navigation-font-size); font-size: var(--navigation-font-size);
} }
@@ -2468,10 +2183,6 @@ address.footer {
color: var(--primary-color) !important; color: var(--primary-color) !important;
} }
.navpath li.navelem a:hover {
text-shadow: none;
}
.navpath li.navelem b { .navpath li.navelem b {
color: var(--primary-dark-color); color: var(--primary-dark-color);
font-weight: 500; font-weight: 500;
@@ -2490,11 +2201,7 @@ li.navelem:first-child:before {
display: none; display: none;
} }
#nav-path ul { #nav-path li.navelem:after {
padding-left: 0;
}
#nav-path li.navelem:has(.el):after {
content: ''; content: '';
border: 5px solid var(--page-background-color); border: 5px solid var(--page-background-color);
border-bottom-color: transparent; border-bottom-color: transparent;
@@ -2505,21 +2212,7 @@ li.navelem:first-child:before {
margin-left: 6px; margin-left: 6px;
} }
#nav-path li.navelem:not(:has(.el)):after { #nav-path li.navelem:before {
background: var(--page-background-color);
box-shadow: 1px -1px 0 1px var(--separator-color);
border-radius: 0 var(--border-radius-medium) 0 50px;
}
#nav-path li.navelem:not(:has(.el)) {
margin-left: 0;
}
#nav-path li.navelem:not(:has(.el)):hover, #nav-path li.navelem:not(:has(.el)):hover:after {
background-color: var(--separator-color);
}
#nav-path li.navelem:has(.el):before {
content: ''; content: '';
border: 5px solid var(--separator-color); border: 5px solid var(--separator-color);
border-bottom-color: transparent; border-bottom-color: transparent;
@@ -2645,7 +2338,7 @@ doxygen-awesome-dark-mode-toggle {
height: var(--searchbar-height); height: var(--searchbar-height);
background: none; background: none;
border: none; border: none;
border-radius: var(--searchbar-border-radius); border-radius: var(--searchbar-height);
vertical-align: middle; vertical-align: middle;
text-align: center; text-align: center;
line-height: var(--searchbar-height); line-height: var(--searchbar-height);
@@ -2830,7 +2523,6 @@ h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a.
float: left; float: left;
white-space: nowrap; white-space: nowrap;
font-weight: normal; font-weight: normal;
font-family: var(--font-family);
padding: calc(var(--spacing-large) / 2) var(--spacing-large); padding: calc(var(--spacing-large) / 2) var(--spacing-large);
border-radius: var(--border-radius-medium); border-radius: var(--border-radius-medium);
transition: background-color var(--animation-duration) ease-in-out, font-weight var(--animation-duration) ease-in-out; transition: background-color var(--animation-duration) ease-in-out, font-weight var(--animation-duration) ease-in-out;
@@ -2975,46 +2667,3 @@ h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a.
border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0; border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0;
} }
} }
/*
Bordered image
*/
html.dark-mode .darkmode_inverted_image img, /* < doxygen 1.9.3 */
html.dark-mode .darkmode_inverted_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ {
filter: brightness(89%) hue-rotate(180deg) invert();
}
.bordered_image {
border-radius: var(--border-radius-small);
border: 1px solid var(--separator-color);
display: inline-block;
overflow: hidden;
}
.bordered_image:empty {
border: none;
}
html.dark-mode .bordered_image img, /* < doxygen 1.9.3 */
html.dark-mode .bordered_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ {
border-radius: var(--border-radius-small);
}
/*
Button
*/
.primary-button {
display: inline-block;
cursor: pointer;
background: var(--primary-color);
color: var(--page-background-color) !important;
border-radius: var(--border-radius-medium);
padding: var(--spacing-small) var(--spacing-medium);
text-decoration: none;
}
.primary-button:hover {
background: var(--primary-dark-color);
}

View File

@@ -1,129 +0,0 @@
.github-corner svg {
fill: var(--primary-light-color);
color: var(--page-background-color);
width: 72px;
height: 72px;
}
@media screen and (max-width: 767px) {
.github-corner svg {
width: 50px;
height: 50px;
}
#projectnumber {
margin-right: 22px;
}
}
.title_screenshot {
filter: drop-shadow(0px 3px 10px rgba(0,0,0,0.22));
max-width: 500px;
margin: var(--spacing-large) 0;
}
.title_screenshot .caption {
display: none;
}
#theme-selection {
position: fixed;
bottom: 0;
left: 0;
background: var(--side-nav-background);
padding: 5px 2px 5px 8px;
box-shadow: 0 -4px 4px -2px var(--side-nav-background);
display: flex;
}
#theme-selection label {
border: 1px solid var(--separator-color);
border-right: 0;
color: var(--page-foreground-color);
font-size: var(--toc-font-size);
padding: 0 8px;
display: inline-block;
height: 22px;
box-sizing: border-box;
border-radius: var(--border-radius-medium) 0 0 var(--border-radius-medium);
line-height: 20px;
background: var(--page-background-color);
opacity: 0.7;
}
@media (prefers-color-scheme: dark) {
html:not(.light-mode) #theme-select {
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23aaaaaa'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat;
background-size: 8px;
background-position: calc(100% - 6px) 65%;
background-color: var(--page-background-color);
}
}
html.dark-mode #theme-select {
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23aaaaaa'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat;
background-size: 8px;
background-position: calc(100% - 6px) 65%;
background-color: var(--page-background-color);
}
#theme-select {
border: 1px solid var(--separator-color);
border-radius: 0 var(--border-radius-medium) var(--border-radius-medium) 0;
padding: 0;
height: 22px;
font-size: var(--toc-font-size);
font-family: var(--font-family);
width: 215px;
color: var(--primary-color);
border-left: 0;
display: inline-block;
opacity: 0.7;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23888888'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat;
background-size: 8px;
background-position: calc(100% - 6px) 65%;
background-repeat: no-repeat;
background-color: var(--page-background-color);
}
#theme-selection:hover #theme-select, #theme-selection:hover label {
opacity: 1;
}
#nav-tree-contents {
margin-bottom: 30px;
}
@media screen and (max-width: 767px) {
#theme-selection {
box-shadow: none;
background: none;
height: 20px;
}
#theme-select {
width: 80px;
opacity: 1;
}
#theme-selection label {
opacity: 1;
}
#nav-path ul li.navelem:first-child {
margin-left: 160px;
}
ul li.footer:not(:first-child) {
display: none;
}
#nav-path {
position: fixed;
bottom: 0;
background: var(--page-background-color);
}
}

Some files were not shown because too many files have changed in this diff Show More