Compare commits

..

7 Commits

Author SHA1 Message Date
Pratik Mankawde
f2ec087fe2 build only
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-23 11:21:43 +00:00
Pratik Mankawde
a6b0671f21 cleanup one more include
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 14:07:06 +00:00
Pratik Mankawde
9d08722cd0 minor change
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 12:43:18 +00:00
Pratik Mankawde
6e17998acb ordering changes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 12:15:18 +00:00
Pratik Mankawde
72ad34d214 more changes
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 11:46:20 +00:00
Pratik Mankawde
c9dd2d73e2 Merge remote-tracking branch 'origin/develop' into pratik/Move-includes-to-cpp-files 2026-01-22 11:05:03 +00:00
Pratik Mankawde
63d91b24b9 first itr
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
2026-01-22 11:03:40 +00:00
1724 changed files with 77113 additions and 118473 deletions

View File

@@ -37,7 +37,7 @@ BinPackParameters: false
BreakBeforeBinaryOperators: false BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true BreakConstructorInitializersBeforeComma: true
ColumnLimit: 100 ColumnLimit: 80
CommentPragmas: "^ IWYU pragma:" CommentPragmas: "^ IWYU pragma:"
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4 ConstructorInitializerIndentWidth: 4

View File

@@ -1,201 +0,0 @@
---
# This entire group of checks was applied to all cpp files but not all header files.
# ---
Checks: "-*,
bugprone-argument-comment,
bugprone-assert-side-effect,
bugprone-bad-signal-to-kill-thread,
bugprone-bool-pointer-implicit-conversion,
bugprone-casting-through-void,
bugprone-chained-comparison,
bugprone-compare-pointer-to-member-virtual-function,
bugprone-copy-constructor-init,
# bugprone-crtp-constructor-accessibility, # has issues
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
# bugprone-empty-catch, # has issues
bugprone-fold-init-type,
# bugprone-forward-declaration-namespace, # has issues
# bugprone-inaccurate-erase,
# bugprone-inc-dec-in-conditions,
# bugprone-incorrect-enable-if,
# bugprone-incorrect-roundings,
# bugprone-infinite-loop,
# bugprone-integer-division,
bugprone-lambda-function-name,
# bugprone-macro-parentheses, # has issues
bugprone-macro-repeated-side-effects,
bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-arithmetic-in-alloc,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
# bugprone-multi-level-implicit-pointer-conversion, # has issues
bugprone-multiple-new-in-one-expression,
bugprone-multiple-statement-macro,
bugprone-no-escape,
bugprone-non-zero-enum-to-bool-conversion,
bugprone-optional-value-conversion,
bugprone-parent-virtual-call,
bugprone-pointer-arithmetic-on-polymorphic-object,
bugprone-posix-return,
bugprone-redundant-branch-condition,
# bugprone-reserved-identifier, # has issues
# bugprone-return-const-ref-from-parameter, # has issues
bugprone-shared-ptr-array-mismatch,
bugprone-signal-handler,
bugprone-signed-char-misuse,
bugprone-sizeof-container,
# bugprone-sizeof-expression, # has issues
bugprone-spuriously-wake-up-functions,
bugprone-standalone-empty,
bugprone-string-constructor,
bugprone-string-integer-assignment,
bugprone-string-literal-with-embedded-nul,
bugprone-stringview-nullptr,
bugprone-suspicious-enum-usage,
bugprone-suspicious-include,
bugprone-suspicious-memory-comparison,
bugprone-suspicious-memset-usage,
bugprone-suspicious-missing-comma,
bugprone-suspicious-realloc-usage,
bugprone-suspicious-semicolon,
bugprone-suspicious-string-compare,
bugprone-suspicious-stringview-data-usage,
bugprone-swapped-arguments,
# bugprone-switch-missing-default-case, # has issues
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
bugprone-too-small-loop-variable,
# bugprone-unchecked-optional-access, # see https://github.com/XRPLF/rippled/pull/6502
bugprone-undefined-memory-manipulation,
bugprone-undelegated-constructor,
bugprone-unhandled-exception-at-new,
bugprone-unhandled-self-assignment,
bugprone-unique-ptr-array-mismatch,
bugprone-unsafe-functions,
# bugprone-use-after-move, # has issues
bugprone-unused-raii,
bugprone-unused-return-value,
bugprone-unused-local-non-trivial-variable,
bugprone-virtual-near-miss,
cppcoreguidelines-init-variables,
cppcoreguidelines-misleading-capture-default-by-value,
cppcoreguidelines-no-suspend-with-lock,
cppcoreguidelines-pro-type-member-init,
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-rvalue-reference-param-not-moved,
cppcoreguidelines-use-default-member-init,
cppcoreguidelines-virtual-class-destructor,
hicpp-ignored-remove-result,
misc-const-correctness,
misc-definitions-in-headers,
misc-header-include-cycle,
misc-misplaced-const,
misc-redundant-expression,
misc-static-assert,
misc-throw-by-value-catch-by-reference,
misc-unused-alias-decls,
misc-unused-using-decls,
modernize-deprecated-headers,
modernize-make-shared,
modernize-make-unique,
llvm-namespace-comment,
performance-faster-string-find,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-vector-operation,
performance-move-const-arg,
performance-move-constructor-init,
performance-no-automatic-move,
performance-trivially-destructible,
# readability-avoid-nested-conditional-operator, # has issues
# readability-avoid-return-with-void-value, # has issues
# readability-braces-around-statements, # has issues
# readability-const-return-type, # has issues
# readability-container-contains, # has issues
# readability-container-size-empty, # has issues
# readability-convert-member-functions-to-static, # has issues
readability-duplicate-include,
# readability-else-after-return, # has issues
# readability-enum-initial-value, # has issues
# readability-implicit-bool-conversion, # has issues
# readability-make-member-function-const, # has issues
# readability-math-missing-parentheses, # has issues
readability-misleading-indentation,
readability-non-const-parameter,
# readability-redundant-casting, # has issues
# readability-redundant-declaration, # has issues
# readability-redundant-inline-specifier, # has issues
# readability-redundant-member-init, # has issues
readability-redundant-string-init,
readability-reference-to-constructed-temporary,
# readability-simplify-boolean-expr, # has issues
# readability-static-definition-in-anonymous-namespace, # has issues
# readability-suspicious-call-argument, # has issues
readability-use-std-min-max
"
# ---
# other checks that have issues that need to be resolved:
#
# misc-include-cleaner,
#
# readability-inconsistent-declaration-parameter-name, # in this codebase this check will break a lot of arg names
# readability-static-accessed-through-instance, # this check is probably unnecessary. it makes the code less readable
# readability-identifier-naming, # https://github.com/XRPLF/rippled/pull/6571
#
# modernize-concat-nested-namespaces,
# modernize-pass-by-value,
# modernize-type-traits,
# modernize-use-designated-initializers,
# modernize-use-emplace,
# modernize-use-equals-default,
# modernize-use-equals-delete,
# modernize-use-override,
# modernize-use-ranges,
# modernize-use-starts-ends-with,
# modernize-use-std-numbers,
# modernize-use-using,
# ---
#
CheckOptions:
readability-braces-around-statements.ShortStatementLines: 2
# readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
# readability-identifier-naming.ClassCase: CamelCase
# readability-identifier-naming.StructCase: CamelCase
# readability-identifier-naming.UnionCase: CamelCase
# readability-identifier-naming.EnumCase: CamelCase
# readability-identifier-naming.EnumConstantCase: CamelCase
# readability-identifier-naming.ScopedEnumConstantCase: CamelCase
# readability-identifier-naming.GlobalConstantCase: UPPER_CASE
# readability-identifier-naming.GlobalConstantPrefix: "k"
# readability-identifier-naming.GlobalVariableCase: CamelCase
# readability-identifier-naming.GlobalVariablePrefix: "g"
# readability-identifier-naming.ConstexprFunctionCase: camelBack
# readability-identifier-naming.ConstexprMethodCase: camelBack
# readability-identifier-naming.ClassMethodCase: camelBack
# readability-identifier-naming.ClassMemberCase: camelBack
# readability-identifier-naming.ClassConstantCase: UPPER_CASE
# readability-identifier-naming.ClassConstantPrefix: "k"
# readability-identifier-naming.StaticConstantCase: UPPER_CASE
# readability-identifier-naming.StaticConstantPrefix: "k"
# readability-identifier-naming.StaticVariableCase: UPPER_CASE
# readability-identifier-naming.StaticVariablePrefix: "k"
# readability-identifier-naming.ConstexprVariableCase: UPPER_CASE
# readability-identifier-naming.ConstexprVariablePrefix: "k"
# readability-identifier-naming.LocalConstantCase: camelBack
# readability-identifier-naming.LocalVariableCase: camelBack
# readability-identifier-naming.TemplateParameterCase: CamelCase
# readability-identifier-naming.ParameterCase: camelBack
# readability-identifier-naming.FunctionCase: camelBack
# readability-identifier-naming.MemberCase: camelBack
# readability-identifier-naming.PrivateMemberSuffix: _
# readability-identifier-naming.ProtectedMemberSuffix: _
# readability-identifier-naming.PublicMemberSuffix: ""
# readability-identifier-naming.FunctionIgnoredRegexp: ".*tag_invoke.*"
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
# misc-include-cleaner.IgnoreHeaders: '.*/(detail|impl)/.*;.*(expected|unexpected).*;.*ranges_lower_bound\.h;time.h;stdlib.h;__chrono/.*;fmt/chrono.h;boost/uuid/uuid_hash.hpp'
#
HeaderFilterRegex: '^.*/(test|xrpl|xrpld)/.*\.(h|hpp)$'
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$'
WarningsAsErrors: "*"

View File

@@ -1,14 +1,14 @@
ignorePaths: ignorePaths:
- build/** - build/**
- src/libxrpl/crypto - src/libxrpl/crypto
- src/test/** # Will be removed in the future
- CMakeUserPresets.json - CMakeUserPresets.json
- Doxyfile - Doxyfile
- docs/**/*.puml - docs/**/*.puml
- cmake/** - cmake/**
- LICENSE.md - LICENSE.md
- .clang-tidy
language: en language: en
allowCompoundWords: true # TODO (#6334) allowCompoundWords: true
ignoreRandomStrings: true ignoreRandomStrings: true
minWordLength: 5 minWordLength: 5
dictionaries: dictionaries:
@@ -16,29 +16,20 @@ dictionaries:
- en_US - en_US
- en_GB - en_GB
ignoreRegExpList: ignoreRegExpList:
- /\b[rs][1-9A-HJ-NP-Za-km-z]{25,34}/g # addresses and seeds - /[rs][1-9A-HJ-NP-Za-km-z]{25,34}/g # addresses and seeds
- /\bC[A-Z0-9]{15}/g # CTIDs - /(XRPL|BEAST)_[A-Z_0-9]+_H_INCLUDED+/g # include guards
- /\b(XRPL|BEAST)_[A-Z_0-9]+_H_INCLUDED+/g # include guards - /(XRPL|BEAST)_[A-Z_0-9]+_H+/g # include guards
- /\b(XRPL|BEAST)_[A-Z_0-9]+_H+/g # include guards
- /::[a-z:_]+/g # things from other namespaces - /::[a-z:_]+/g # things from other namespaces
- /\blib[a-z]+/g # libraries - /lib[a-z]+/g # libraries
- /\b[0-9]{4}-[0-9]{2}-[0-9]{2}[,:][A-Za-zÀ-ÖØ-öø-ÿ.\s]+/g # copyright dates - /[0-9]{4}-[0-9]{2}-[0-9]{2}[,:][A-Za-zÀ-ÖØ-öø-ÿ.\s]+/g # copyright dates
- /\b[0-9]{4}[,:]?\s*[A-Za-zÀ-ÖØ-öø-ÿ.\s]+/g # copyright years - /[0-9]{4}[,:]?\s*[A-Za-zÀ-ÖØ-öø-ÿ.\s]+/g # copyright years
- /\[[A-Za-z0-9-]+\]\(https:\/\/github.com\/[A-Za-z0-9-]+\)/g # Github usernames - /\[[A-Za-z0-9-]+\]\(https:\/\/github.com\/[A-Za-z0-9-]+\)/g # Github usernames
- /-[DWw][a-zA-Z0-9_-]+=/g # compile flags - /-[DWw][a-zA-Z0-9_-]+=/g # compile flags
- /[\['"`]-[DWw][a-zA-Z0-9_-]+['"`\]]/g # compile flags - /[\['"`]-[DWw][a-zA-Z0-9_-]+['"`\]]/g # compile flags
- ABCDEFGHIJKLMNOPQRSTUVWXYZ
- ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
overrides:
- filename: "**/*_test.cpp" # all test files
ignoreRegExpList:
- /"[^"]*"/g # double-quoted strings
- /'[^']*'/g # single-quoted strings
- /`[^`]*`/g # backtick strings
suggestWords: suggestWords:
- xprl->xrpl - xprl->xrpl
- xprld->xrpld # cspell: disable-line not sure what this problem is.... - xprld->xrpld
- unsynched->unsynced # cspell: disable-line not sure what this problem is.... - unsynched->unsynced
- synched->synced - synched->synced
- synch->sync - synch->sync
words: words:
@@ -60,7 +51,6 @@ words:
- Britto - Britto
- Btrfs - Btrfs
- canonicality - canonicality
- changespq
- checkme - checkme
- choco - choco
- chrono - chrono
@@ -99,7 +89,6 @@ words:
- endmacro - endmacro
- exceptioned - exceptioned
- Falco - Falco
- fcontext
- finalizers - finalizers
- firewalled - firewalled
- fmtdur - fmtdur
@@ -112,25 +101,19 @@ words:
- gpgcheck - gpgcheck
- gpgkey - gpgkey
- hotwallet - hotwallet
- hwaddress
- hwrap
- ifndef - ifndef
- inequation - inequation
- insuf - insuf
- insuff - insuff
- invasively
- iou - iou
- ious - ious
- isrdc - isrdc
- itype - itype
- jemalloc - jemalloc
- jlog - jlog
- jtnofill
- keylet - keylet
- keylets - keylets
- keyvadb - keyvadb
- kwarg
- kwargs
- ledgerentry - ledgerentry
- ledgerhash - ledgerhash
- ledgerindex - ledgerindex
@@ -152,7 +135,6 @@ words:
- Metafuncton - Metafuncton
- misprediction - misprediction
- mptbalance - mptbalance
- MPTDEX
- mptflags - mptflags
- mptid - mptid
- mptissuance - mptissuance
@@ -162,7 +144,6 @@ words:
- mptokenissuance - mptokenissuance
- mptokens - mptokens
- mpts - mpts
- mtgox
- multisig - multisig
- multisign - multisign
- multisigned - multisigned
@@ -175,11 +156,6 @@ words:
- nftokens - nftokens
- nftpage - nftpage
- nikb - nikb
- nixfmt
- nixos
- nixpkgs
- NOLINT
- NOLINTNEXTLINE
- nonxrp - nonxrp
- noripple - noripple
- nudb - nudb
@@ -187,7 +163,6 @@ words:
- nunl - nunl
- Nyffenegger - Nyffenegger
- ostr - ostr
- pargs
- partitioner - partitioner
- paychan - paychan
- paychans - paychans
@@ -195,7 +170,6 @@ words:
- perminute - perminute
- permissioned - permissioned
- pointee - pointee
- populator
- preauth - preauth
- preauthorization - preauthorization
- preauthorize - preauthorize
@@ -204,9 +178,7 @@ words:
- protobuf - protobuf
- protos - protos
- ptrs - ptrs
- pushd
- pyenv - pyenv
- pyparsing
- qalloc - qalloc
- queuable - queuable
- Raphson - Raphson
@@ -232,7 +204,6 @@ words:
- seqit - seqit
- sf - sf
- SFIELD - SFIELD
- sfields
- shamap - shamap
- shamapitem - shamapitem
- sidechain - sidechain
@@ -297,7 +268,6 @@ words:
- venv - venv
- vfalco - vfalco
- vinnie - vinnie
- wasmi
- wextra - wextra
- wptr - wptr
- writeme - writeme

View File

@@ -1,101 +0,0 @@
# Custom CMake command definitions for gersemi formatting.
# These stubs teach gersemi the signatures of project-specific commands
# so it can format their invocations correctly.
function(git_branch branch_val)
endfunction()
function(isolate_headers target A B scope)
endfunction()
function(create_symbolic_link target link)
endfunction()
function(xrpl_add_test name)
endfunction()
macro(exclude_from_default target_)
endmacro()
macro(exclude_if_included target_)
endmacro()
function(target_protobuf_sources target prefix)
set(options APPEND_PATH DESCRIPTORS)
set(oneValueArgs
LANGUAGE
OUT_VAR
EXPORT_MACRO
TARGET
PROTOC_OUT_DIR
PLUGIN
PLUGIN_OPTIONS
PROTOC_EXE
)
set(multiValueArgs
PROTOS
IMPORT_DIRS
GENERATE_EXTENSIONS
PROTOC_OPTIONS
DEPENDENCIES
)
cmake_parse_arguments(
THIS_FUNCTION_PREFIX
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
endfunction()
function(add_module parent name)
endfunction()
function(setup_protocol_autogen)
endfunction()
function(target_link_modules parent scope)
endfunction()
function(setup_target_for_coverage_gcovr)
set(options NONE)
set(oneValueArgs BASE_DIRECTORY NAME FORMAT)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments(
THIS_FUNCTION_PREFIX
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
endfunction()
function(add_code_coverage_to_target name scope)
endfunction()
function(verbose_find_path variable name)
set(options
NO_CACHE
REQUIRED
OPTIONAL
NO_DEFAULT_PATH
NO_PACKAGE_ROOT_PATH
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH
NO_CMAKE_INSTALL_PREFIX
CMAKE_FIND_ROOT_PATH_BOTH
ONLY_CMAKE_FIND_ROOT_PATH
NO_CMAKE_FIND_ROOT_PATH
)
set(oneValueArgs REGISTRY_VIEW VALIDATOR DOC)
set(multiValueArgs NAMES HINTS PATHS PATH_SUFFIXES)
cmake_parse_arguments(
THIS_FUNCTION_PREFIX
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
endfunction()

View File

@@ -1 +0,0 @@
definitions: [.gersemi]

View File

@@ -1,79 +1,16 @@
# This feature requires Git >= 2.24 # This feature requires Git >= 2.24
# To use it by default in git blame: # To use it by default in git blame:
# git config blame.ignoreRevsFile .git-blame-ignore-revs # git config blame.ignoreRevsFile .git-blame-ignore-revs
# This file is sorted in reverse chronological order, with the most recent commits at the top.
# The commits listed here are ignored by git blame, which is useful for formatting-only commits that would otherwise obscure the history of changes to a file.
# refactor: Enable remaining clang-tidy `cppcoreguidelines` checks (#6538)
72f4cb097f626b08b02fc3efcb4aa11cb2e7adb8
# refactor: Rename system name from 'ripple' to 'xrpld' (#6347)
ffea3977f0b771fe8e43a8f74e4d393d63a7afd8
# refactor: Update transaction folder structure (#6483)
5865bd017f777491b4a956f9210be0c4161f5442
# chore: Use gersemi instead of ancient cmake-format (#6486)
0c74270b055133a57a497b5c9fc5a75f7647b1f4
# chore: Apply clang-format width 100 (#6387)
2c1fad102353e11293e3edde1c043224e7d3e983
# chore: Set clang-format width to 100 in config file (#6387)
25cca465538a56cce501477f9e5e2c1c7ea2d84c
# chore: Set cmake-format width to 100 (#6386)
469ce9f291a4480c38d4ee3baca5136b2f053cd0
# refactor: Modularize app/tx (#6228)
0976b2b68b64972af8e6e7c497900b5bce9fe22f
# chore: Update clang-format to 21.1.8 (#6352)
958d8f375453d80bb1aa4c293b5102c045a3e4b4
# refactor: Replace include guards by '#pragma once' (#6322)
34ef577604782ca8d6e1c17df8bd7470990a52ff
# chore: Format all cmake files without comments (#6294)
fe9c8d568fcf6ac21483024e01f58962dd5c8260
# chore: Add cmake-format pre-commit hook (#6279)
a0e09187b9370805d027c611a7e9ff5a0125282a
# chore: Set ColumnLimit to 120 in clang-format (#6288)
5f638f55536def0d88b970d1018a465a238e55f4
# refactor: Fix typos in comments, configure cspell (#6164)
3c9f5b62525cb1d6ca1153eeb10433db7d7379fd
# refactor: Rename `rippled.cfg` to `xrpld.cfg` (#6098)
3d1b3a49b3601a0a7037fa0b19d5df7b5e0e2fc1
# refactor: Rename `ripple` namespace to `xrpl` (#5982)
1eb0fdac6543706b4b9ddca57fd4102928a1f871
# refactor: Rename `rippled` binary to `xrpld` (#5983)
9eb84a561ef8bb066d89f098bd9b4ac71baed67c
# refactor: Replaces secp256k1 source by Conan package (#6089)
813bc4d9491b078bb950f8255f93b02f71320478
# refactor: Remove unnecessary copyright notices already covered by LICENSE.md (#5929)
1d42c4f6de6bf01d1286fc7459b17a37a5189e88
# refactor: Rename `RIPPLE_` and `RIPPLED_` definitions to `XRPL_` (#5821)
ada83564d894829424b0f4d922b0e737e07abbf7
# refactor: Modularize shamap and nodestore (#5668)
8eb233c2ea8ad5a159be73b77f0f5e1496d547ac
# refactor: Modularise ledger (#5493)
dc8b37a52448b005153c13a7f046ad494128cf94
# chore: Update clang-format and prettier with pre-commit (#5709)
c14ce956adeabe476ad73c18d73103f347c9c613
# chore: Fix file formatting (#5718)
896b8c3b54a22b0497cb0d1ce95e1095f9a227ce
# chore: Reverts formatting changes to external files, adds formatting changes to proto files (#5711)
b13370ac0d207217354f1fc1c29aef87769fb8a1
# chore: Run prettier on all files (#5657)
97f0747e103f13e26e45b731731059b32f7679ac
# Reformat code with clang-format-18
552377c76f55b403a1c876df873a23d780fcc81c
# Recompute loops (#4997)
d028005aa6319338b0adae1aebf8abe113162960
# Rewrite includes (#4997)
1d23148e6dd53957fcb6205c07a5c6cd7b64d50c
# Rearrange sources (#4997)
e416ee72ca26fa0c09d2aee1b68bdfb2b7046eed
# Move CMake directory (#4997)
2e902dee53aab2a8f27f32971047bb81e022f94f
# Rewrite includes
0eebe6a5f4246fced516d52b83ec4e7f47373edd
# Format formerly .hpp files
760f16f56835663d9286bd29294d074de26a7ba6
# Rename .hpp to .h
241b9ddde9e11beb7480600fd5ed90e1ef109b21
# Consolidate external libraries
e2384885f5f630c8f0ffe4bf21a169b433a16858
# Format first-party source according to .clang-format
50760c693510894ca368e90369b0cc2dabfd07f3 50760c693510894ca368e90369b0cc2dabfd07f3
e2384885f5f630c8f0ffe4bf21a169b433a16858
241b9ddde9e11beb7480600fd5ed90e1ef109b21
760f16f56835663d9286bd29294d074de26a7ba6
0eebe6a5f4246fced516d52b83ec4e7f47373edd
2189cc950c0cebb89e4e2fa3b2d8817205bf7cef
b9d007813378ad0ff45660dc07285b823c7e9855
fe9a5365b8a52d4acc42eb27369247e6f238a4f9
9a93577314e6a8d4b4a8368cc9d2b15a5d8303e8
552377c76f55b403a1c876df873a23d780fcc81c
97f0747e103f13e26e45b731731059b32f7679ac
b13370ac0d207217354f1fc1c29aef87769fb8a1
896b8c3b54a22b0497cb0d1ce95e1095f9a227ce

8
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,8 @@
# Allow anyone to review any change by default.
*
# Require the rpc-reviewers team to review changes to the rpc code.
include/xrpl/protocol/ @xrplf/rpc-reviewers
src/libxrpl/protocol/ @xrplf/rpc-reviewers
src/xrpld/rpc/ @xrplf/rpc-reviewers
src/xrpld/app/misc/ @xrplf/rpc-reviewers

View File

@@ -11,18 +11,16 @@ runs:
steps: steps:
# When a tag is pushed, the version is used as-is. # When a tag is pushed, the version is used as-is.
- name: Generate version for tag event - name: Generate version for tag event
if: ${{ startsWith(github.ref, 'refs/tags/') }} if: ${{ github.event_name == 'tag' }}
shell: bash shell: bash
env: env:
VERSION: ${{ github.ref_name }} VERSION: ${{ github.ref_name }}
run: echo "VERSION=${VERSION}" >> "${GITHUB_ENV}" run: echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"
# When a tag is not pushed, then the version (e.g. 1.2.3-b0) is extracted # When a tag is not pushed, then the version is extracted from the
# from the BuildInfo.cpp file and the shortened commit hash appended to it. # BuildInfo.cpp file and the shortened commit hash appended to it.
# We use a plus sign instead of a hyphen because Conan recipe versions do
# not support two hyphens.
- name: Generate version for non-tag event - name: Generate version for non-tag event
if: ${{ !startsWith(github.ref, 'refs/tags/') }} if: ${{ github.event_name != 'tag' }}
shell: bash shell: bash
run: | run: |
echo 'Extracting version from BuildInfo.cpp.' echo 'Extracting version from BuildInfo.cpp.'
@@ -34,7 +32,7 @@ runs:
echo 'Appending shortened commit hash to version.' echo 'Appending shortened commit hash to version.'
SHA='${{ github.sha }}' SHA='${{ github.sha }}'
VERSION="${VERSION}+${SHA:0:7}" VERSION="${VERSION}-${SHA:0:7}"
echo "VERSION=${VERSION}" >> "${GITHUB_ENV}" echo "VERSION=${VERSION}" >> "${GITHUB_ENV}"

View File

@@ -31,7 +31,7 @@ runs:
conan config install conan/profiles/ -tf $(conan config home)/profiles/ conan config install conan/profiles/ -tf $(conan config home)/profiles/
echo 'Conan profile:' echo 'Conan profile:'
conan profile show --profile ci conan profile show
- name: Set up Conan remote - name: Set up Conan remote
shell: bash shell: bash

View File

@@ -1,56 +0,0 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/build-deps/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/generate-version/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/print-env/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/setup-conan/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop

View File

@@ -29,6 +29,22 @@ If a refactor, how is this better than the previous implementation?
If there is a spec or design document for this feature, please link it here. If there is a spec or design document for this feature, please link it here.
--> -->
### Type of Change
<!--
Please check [x] relevant options, delete irrelevant ones.
-->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Refactor (non-breaking change that only restructures code)
- [ ] Performance (increase or change in throughput and/or latency)
- [ ] Tests (you added tests for code that already exists, or your new feature included in this PR)
- [ ] Documentation update
- [ ] Chore (no impact to binary, e.g. `.gitignore`, formatting, dropping support for older tooling)
- [ ] Release
### API Impact ### API Impact
<!-- <!--

View File

@@ -70,7 +70,7 @@ that `test` code should _never_ be included in `xrpl` or `xrpld` code.)
## Validation ## Validation
The [levelization](generate.py) script takes no parameters, The [levelization](generate.sh) script takes no parameters,
reads no environment variables, and can be run from any directory, reads no environment variables, and can be run from any directory,
as long as it is in the expected location in the rippled repo. as long as it is in the expected location in the rippled repo.
It can be run at any time from within a checked out repo, and will It can be run at any time from within a checked out repo, and will
@@ -104,7 +104,7 @@ It generates many files of [results](results):
Github Actions workflow to test that levelization loops haven't Github Actions workflow to test that levelization loops haven't
changed. Unfortunately, if changes are detected, it can't tell if changed. Unfortunately, if changes are detected, it can't tell if
they are improvements or not, so if you have resolved any issues or they are improvements or not, so if you have resolved any issues or
done anything else to improve levelization, run `generate.py`, done anything else to improve levelization, run `levelization.sh`,
and commit the updated results. and commit the updated results.
The `loops.txt` and `ordering.txt` files relate the modules The `loops.txt` and `ordering.txt` files relate the modules
@@ -128,7 +128,7 @@ The committed files hide the detailed values intentionally, to
prevent false alarms and merging issues, and because it's easy to prevent false alarms and merging issues, and because it's easy to
get those details locally. get those details locally.
1. Run `generate.py` 1. Run `levelization.sh`
2. Grep the modules in `paths.txt`. 2. Grep the modules in `paths.txt`.
- For example, if a cycle is found `A ~= B`, simply `grep -w - For example, if a cycle is found `A ~= B`, simply `grep -w
A .github/scripts/levelization/results/paths.txt | grep -w B` A .github/scripts/levelization/results/paths.txt | grep -w B`

View File

@@ -1,335 +0,0 @@
#!/usr/bin/env python3
"""
Usage: generate.py
This script takes no parameters, and can be called from any directory in the file system.
"""
import os
import re
import subprocess
import sys
from collections import defaultdict
from pathlib import Path
from typing import Dict, List, Tuple, Set, Optional
# Compile regex patterns once at module level
INCLUDE_PATTERN = re.compile(r"^\s*#include.*/.*\.h")
INCLUDE_PATH_PATTERN = re.compile(r'[<"]([^>"]+)[>"]')
def dictionary_sort_key(s: str) -> str:
"""
Create a sort key that mimics 'sort -d' (dictionary order).
Dictionary order only considers blanks and alphanumeric characters.
This means punctuation like '.' is ignored during sorting.
"""
# Keep only alphanumeric characters and spaces
return "".join(c for c in s if c.isalnum() or c.isspace())
def get_level(file_path: str) -> str:
"""
Extract the level from a file path (second and third directory components).
Equivalent to bash: cut -d/ -f 2,3
Examples:
src/xrpld/app/main.cpp -> xrpld.app
src/libxrpl/protocol/STObject.cpp -> libxrpl.protocol
include/xrpl/basics/base_uint.h -> xrpl.basics
"""
parts = file_path.split("/")
# Get fields 2 and 3 (indices 1 and 2 in 0-based indexing)
if len(parts) >= 3:
level = f"{parts[1]}/{parts[2]}"
elif len(parts) >= 2:
level = f"{parts[1]}/toplevel"
else:
level = file_path
# If the "level" indicates a file, cut off the filename
if "." in level.split("/")[-1]: # Avoid Path object creation
# Use the "toplevel" label as a workaround for `sort`
# inconsistencies between different utility versions
level = level.rsplit("/", 1)[0] + "/toplevel"
return level.replace("/", ".")
def extract_include_level(include_line: str) -> Optional[str]:
"""
Extract the include path from an #include directive.
Gets the first two directory components from the include path.
Equivalent to bash: cut -d/ -f 1,2
Examples:
#include <xrpl/basics/base_uint.h> -> xrpl.basics
#include "xrpld/app/main/Application.h" -> xrpld.app
"""
# Remove everything before the quote or angle bracket
match = INCLUDE_PATH_PATTERN.search(include_line)
if not match:
return None
include_path = match.group(1)
parts = include_path.split("/")
# Get first two fields (indices 0 and 1)
if len(parts) >= 2:
include_level = f"{parts[0]}/{parts[1]}"
else:
include_level = include_path
# If the "includelevel" indicates a file, cut off the filename
if "." in include_level.split("/")[-1]: # Avoid Path object creation
include_level = include_level.rsplit("/", 1)[0] + "/toplevel"
return include_level.replace("/", ".")
def find_repository_directories(
start_path: Path, depth_limit: int = 10
) -> Tuple[Path, List[Path]]:
"""
Find the repository root by looking for src or include folders.
Walks up the directory tree from the start path.
"""
current = start_path.resolve()
# Walk up the directory tree
for _ in range(depth_limit): # Limit search depth to prevent infinite loops
src_path = current / "src"
include_path = current / "include"
# Check if this directory has src or include folders
has_src = src_path.exists()
has_include = include_path.exists()
if has_src or has_include:
return current, [src_path, include_path]
# Move up one level
parent = current.parent
if parent == current: # Reached filesystem root
break
current = parent
# If we couldn't find it, raise an error
raise RuntimeError(
"Could not find repository root. "
"Expected to find a directory containing 'src' and/or 'include' folders."
)
def main():
# Change to the script's directory
script_dir = Path(__file__).parent.resolve()
os.chdir(script_dir)
# Clean up and create results directory.
results_dir = script_dir / "results"
if results_dir.exists():
import shutil
shutil.rmtree(results_dir)
results_dir.mkdir()
# Find the repository root by searching for src and include directories.
try:
repo_root, scan_dirs = find_repository_directories(script_dir)
print(f"Found repository root: {repo_root}")
print(f"Scanning directories:")
for scan_dir in scan_dirs:
print(f" - {scan_dir.relative_to(repo_root)}")
except RuntimeError as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
print("\nScanning for raw includes...")
# Find all #include directives
raw_includes: List[Tuple[str, str]] = []
rawincludes_file = results_dir / "rawincludes.txt"
# Write to file as we go to avoid storing everything in memory.
with open(rawincludes_file, "w", buffering=8192) as raw_f:
for dir_path in scan_dirs:
print(f" Scanning {dir_path.relative_to(repo_root)}...")
for file_path in dir_path.rglob("*"):
if not file_path.is_file():
continue
try:
rel_path_str = str(file_path.relative_to(repo_root))
# Read file with a large buffer for performance.
with open(
file_path,
"r",
encoding="utf-8",
errors="ignore",
buffering=8192,
) as f:
for line in f:
# Quick check before regex
if "#include" not in line or "boost" in line:
continue
if INCLUDE_PATTERN.match(line):
line_stripped = line.strip()
entry = f"{rel_path_str}:{line_stripped}\n"
print(entry, end="")
raw_f.write(entry)
raw_includes.append((rel_path_str, line_stripped))
except Exception as e:
print(f"Error reading {file_path}: {e}", file=sys.stderr)
# Build levelization paths and count directly (no need to sort first).
print("Build levelization paths")
path_counts: Dict[Tuple[str, str], int] = defaultdict(int)
for file_path, include_line in raw_includes:
include_level = extract_include_level(include_line)
if not include_level:
continue
level = get_level(file_path)
if level != include_level:
path_counts[(level, include_level)] += 1
# Sort and deduplicate paths (using dictionary order like bash 'sort -d').
print("Sort and deduplicate paths")
paths_file = results_dir / "paths.txt"
with open(paths_file, "w") as f:
# Sort using dictionary order: only alphanumeric and spaces matter
sorted_items = sorted(
path_counts.items(),
key=lambda x: (dictionary_sort_key(x[0][0]), dictionary_sort_key(x[0][1])),
)
for (level, include_level), count in sorted_items:
line = f"{count:7} {level} {include_level}\n"
print(line.rstrip())
f.write(line)
# Split into flat-file database
print("Split into flat-file database")
includes_dir = results_dir / "includes"
included_by_dir = results_dir / "included_by"
includes_dir.mkdir()
included_by_dir.mkdir()
# Batch writes by grouping data first to avoid repeated file opens.
includes_data: Dict[str, List[Tuple[str, int]]] = defaultdict(list)
included_by_data: Dict[str, List[Tuple[str, int]]] = defaultdict(list)
# Process in sorted order to match bash script behaviour (dictionary order).
sorted_items = sorted(
path_counts.items(),
key=lambda x: (dictionary_sort_key(x[0][0]), dictionary_sort_key(x[0][1])),
)
for (level, include_level), count in sorted_items:
includes_data[level].append((include_level, count))
included_by_data[include_level].append((level, count))
# Write all includes files in sorted order (dictionary order).
for level in sorted(includes_data.keys(), key=dictionary_sort_key):
entries = includes_data[level]
with open(includes_dir / level, "w") as f:
for include_level, count in entries:
line = f"{include_level} {count}\n"
print(line.rstrip())
f.write(line)
# Write all included_by files in sorted order (dictionary order).
for include_level in sorted(included_by_data.keys(), key=dictionary_sort_key):
entries = included_by_data[include_level]
with open(included_by_dir / include_level, "w") as f:
for level, count in entries:
line = f"{level} {count}\n"
print(line.rstrip())
f.write(line)
# Search for loops
print("Search for loops")
loops_file = results_dir / "loops.txt"
ordering_file = results_dir / "ordering.txt"
loops_found: Set[Tuple[str, str]] = set()
# Pre-load all include files into memory to avoid repeated I/O.
# This is the biggest optimisation - we were reading files repeatedly in nested loops.
# Use list of tuples to preserve file order.
includes_cache: Dict[str, List[Tuple[str, int]]] = {}
includes_lookup: Dict[str, Dict[str, int]] = {} # For fast lookup
# Note: bash script uses 'for source in *' which uses standard glob sorting,
# NOT dictionary order. So we use standard sorted() here, not dictionary_sort_key.
for include_file in sorted(includes_dir.iterdir(), key=lambda p: p.name):
if not include_file.is_file():
continue
includes_cache[include_file.name] = []
includes_lookup[include_file.name] = {}
with open(include_file, "r") as f:
for line in f:
parts = line.strip().split()
if len(parts) >= 2:
include_name = parts[0]
include_count = int(parts[1])
includes_cache[include_file.name].append(
(include_name, include_count)
)
includes_lookup[include_file.name][include_name] = include_count
with open(loops_file, "w", buffering=8192) as loops_f, open(
ordering_file, "w", buffering=8192
) as ordering_f:
# Use standard sorting to match bash glob expansion 'for source in *'.
for source in sorted(includes_cache.keys()):
source_includes = includes_cache[source]
for include, include_freq in source_includes:
# Check if include file exists and references source
if include not in includes_lookup:
continue
source_freq = includes_lookup[include].get(source)
if source_freq is not None:
# Found a loop
loop_key = tuple(sorted([source, include]))
if loop_key in loops_found:
continue
loops_found.add(loop_key)
loops_f.write(f"Loop: {source} {include}\n")
# If the counts are close, indicate that the two modules are
# on the same level, though they shouldn't be.
diff = include_freq - source_freq
if diff > 3:
loops_f.write(f" {source} > {include}\n\n")
elif diff < -3:
loops_f.write(f" {include} > {source}\n\n")
elif source_freq == include_freq:
loops_f.write(f" {include} == {source}\n\n")
else:
loops_f.write(f" {include} ~= {source}\n\n")
else:
ordering_f.write(f"{source} > {include}\n")
# Print results
print("\nOrdering:")
with open(ordering_file, "r") as f:
print(f.read(), end="")
print("\nLoops:")
with open(loops_file, "r") as f:
print(f.read(), end="")
if __name__ == "__main__":
main()

130
.github/scripts/levelization/generate.sh vendored Executable file
View File

@@ -0,0 +1,130 @@
#!/bin/bash
# Usage: generate.sh
# This script takes no parameters, reads no environment variables,
# and can be run from any directory, as long as it is in the expected
# location in the repo.
pushd $( dirname $0 )
if [ -v PS1 ]
then
# if the shell is interactive, clean up any flotsam before analyzing
git clean -ix
fi
# Ensure all sorting is ASCII-order consistently across platforms.
export LANG=C
rm -rfv results
mkdir results
includes="$( pwd )/results/rawincludes.txt"
pushd ../../..
echo Raw includes:
grep -r '^[ ]*#include.*/.*\.h' include src | \
grep -v boost | tee ${includes}
popd
pushd results
oldifs=${IFS}
IFS=:
mkdir includes
mkdir included_by
echo Build levelization paths
exec 3< ${includes} # open rawincludes.txt for input
while read -r -u 3 file include
do
level=$( echo ${file} | cut -d/ -f 2,3 )
# If the "level" indicates a file, cut off the filename
if [[ "${level##*.}" != "${level}" ]]
then
# Use the "toplevel" label as a workaround for `sort`
# inconsistencies between different utility versions
level="$( dirname ${level} )/toplevel"
fi
level=$( echo ${level} | tr '/' '.' )
includelevel=$( echo ${include} | sed 's/.*["<]//; s/[">].*//' | \
cut -d/ -f 1,2 )
if [[ "${includelevel##*.}" != "${includelevel}" ]]
then
# Use the "toplevel" label as a workaround for `sort`
# inconsistencies between different utility versions
includelevel="$( dirname ${includelevel} )/toplevel"
fi
includelevel=$( echo ${includelevel} | tr '/' '.' )
if [[ "$level" != "$includelevel" ]]
then
echo $level $includelevel | tee -a paths.txt
fi
done
echo Sort and deduplicate paths
sort -ds paths.txt | uniq -c | tee sortedpaths.txt
mv sortedpaths.txt paths.txt
exec 3>&- #close fd 3
IFS=${oldifs}
unset oldifs
echo Split into flat-file database
exec 4<paths.txt # open paths.txt for input
while read -r -u 4 count level include
do
echo ${include} ${count} | tee -a includes/${level}
echo ${level} ${count} | tee -a included_by/${include}
done
exec 4>&- #close fd 4
loops="$( pwd )/loops.txt"
ordering="$( pwd )/ordering.txt"
pushd includes
echo Search for loops
# Redirect stdout to a file
exec 4>&1
exec 1>"${loops}"
for source in *
do
if [[ -f "$source" ]]
then
exec 5<"${source}" # open for input
while read -r -u 5 include includefreq
do
if [[ -f $include ]]
then
if grep -q -w $source $include
then
if grep -q -w "Loop: $include $source" "${loops}"
then
continue
fi
sourcefreq=$( grep -w $source $include | cut -d\ -f2 )
echo "Loop: $source $include"
# If the counts are close, indicate that the two modules are
# on the same level, though they shouldn't be
if [[ $(( $includefreq - $sourcefreq )) -gt 3 ]]
then
echo -e " $source > $include\n"
elif [[ $(( $sourcefreq - $includefreq )) -gt 3 ]]
then
echo -e " $include > $source\n"
elif [[ $sourcefreq -eq $includefreq ]]
then
echo -e " $include == $source\n"
else
echo -e " $include ~= $source\n"
fi
else
echo "$source > $include" >> "${ordering}"
fi
fi
done
exec 5>&- #close fd 5
fi
done
exec 1>&4 #close fd 1
exec 4>&- #close fd 4
cat "${ordering}"
cat "${loops}"
popd
popd
popd

View File

@@ -4,11 +4,14 @@ Loop: test.jtx test.toplevel
Loop: test.jtx test.unit_test Loop: test.jtx test.unit_test
test.unit_test == test.jtx test.unit_test == test.jtx
Loop: xrpld.app xrpld.core
xrpld.app > xrpld.core
Loop: xrpld.app xrpld.overlay Loop: xrpld.app xrpld.overlay
xrpld.overlay ~= xrpld.app xrpld.overlay > xrpld.app
Loop: xrpld.app xrpld.peerfinder Loop: xrpld.app xrpld.peerfinder
xrpld.peerfinder == xrpld.app xrpld.peerfinder ~= xrpld.app
Loop: xrpld.app xrpld.rpc Loop: xrpld.app xrpld.rpc
xrpld.rpc > xrpld.app xrpld.rpc > xrpld.app

View File

@@ -1,6 +1,4 @@
libxrpl.basics > xrpl.basics libxrpl.basics > xrpl.basics
libxrpl.conditions > xrpl.basics
libxrpl.conditions > xrpl.conditions
libxrpl.core > xrpl.basics libxrpl.core > xrpl.basics
libxrpl.core > xrpl.core libxrpl.core > xrpl.core
libxrpl.crypto > xrpl.basics libxrpl.crypto > xrpl.basics
@@ -19,29 +17,17 @@ libxrpl.nodestore > xrpl.protocol
libxrpl.protocol > xrpl.basics libxrpl.protocol > xrpl.basics
libxrpl.protocol > xrpl.json libxrpl.protocol > xrpl.json
libxrpl.protocol > xrpl.protocol libxrpl.protocol > xrpl.protocol
libxrpl.protocol_autogen > xrpl.protocol_autogen
libxrpl.rdb > xrpl.basics
libxrpl.rdb > xrpl.core
libxrpl.rdb > xrpl.rdb
libxrpl.resource > xrpl.basics libxrpl.resource > xrpl.basics
libxrpl.resource > xrpl.json libxrpl.resource > xrpl.json
libxrpl.resource > xrpl.protocol
libxrpl.resource > xrpl.resource libxrpl.resource > xrpl.resource
libxrpl.server > xrpl.basics libxrpl.server > xrpl.basics
libxrpl.server > xrpl.json libxrpl.server > xrpl.json
libxrpl.server > xrpl.protocol libxrpl.server > xrpl.protocol
libxrpl.server > xrpl.rdb
libxrpl.server > xrpl.server libxrpl.server > xrpl.server
libxrpl.shamap > xrpl.basics libxrpl.shamap > xrpl.basics
libxrpl.shamap > xrpl.protocol libxrpl.shamap > xrpl.protocol
libxrpl.shamap > xrpl.shamap libxrpl.shamap > xrpl.shamap
libxrpl.tx > xrpl.basics
libxrpl.tx > xrpl.conditions
libxrpl.tx > xrpl.core
libxrpl.tx > xrpl.json
libxrpl.tx > xrpl.ledger
libxrpl.tx > xrpl.protocol
libxrpl.tx > xrpl.server
libxrpl.tx > xrpl.tx
test.app > test.jtx test.app > test.jtx
test.app > test.rpc test.app > test.rpc
test.app > test.toplevel test.app > test.toplevel
@@ -56,10 +42,7 @@ test.app > xrpl.json
test.app > xrpl.ledger test.app > xrpl.ledger
test.app > xrpl.nodestore test.app > xrpl.nodestore
test.app > xrpl.protocol test.app > xrpl.protocol
test.app > xrpl.rdb
test.app > xrpl.resource test.app > xrpl.resource
test.app > xrpl.server
test.app > xrpl.tx
test.basics > test.jtx test.basics > test.jtx
test.basics > test.unit_test test.basics > test.unit_test
test.basics > xrpl.basics test.basics > xrpl.basics
@@ -69,7 +52,7 @@ test.basics > xrpl.json
test.basics > xrpl.protocol test.basics > xrpl.protocol
test.beast > xrpl.basics test.beast > xrpl.basics
test.conditions > xrpl.basics test.conditions > xrpl.basics
test.conditions > xrpl.conditions test.conditions > xrpld.conditions
test.consensus > test.csf test.consensus > test.csf
test.consensus > test.toplevel test.consensus > test.toplevel
test.consensus > test.unit_test test.consensus > test.unit_test
@@ -78,7 +61,6 @@ test.consensus > xrpld.app
test.consensus > xrpld.consensus test.consensus > xrpld.consensus
test.consensus > xrpl.json test.consensus > xrpl.json
test.consensus > xrpl.ledger test.consensus > xrpl.ledger
test.consensus > xrpl.tx
test.core > test.jtx test.core > test.jtx
test.core > test.toplevel test.core > test.toplevel
test.core > test.unit_test test.core > test.unit_test
@@ -86,17 +68,14 @@ test.core > xrpl.basics
test.core > xrpl.core test.core > xrpl.core
test.core > xrpld.core test.core > xrpld.core
test.core > xrpl.json test.core > xrpl.json
test.core > xrpl.rdb
test.core > xrpl.server test.core > xrpl.server
test.csf > xrpl.basics test.csf > xrpl.basics
test.csf > xrpld.consensus test.csf > xrpld.consensus
test.csf > xrpl.json test.csf > xrpl.json
test.csf > xrpl.ledger
test.csf > xrpl.protocol test.csf > xrpl.protocol
test.json > test.jtx test.json > test.jtx
test.json > xrpl.json test.json > xrpl.json
test.jtx > xrpl.basics test.jtx > xrpl.basics
test.jtx > xrpl.core
test.jtx > xrpld.app test.jtx > xrpld.app
test.jtx > xrpld.core test.jtx > xrpld.core
test.jtx > xrpld.rpc test.jtx > xrpld.rpc
@@ -106,10 +85,10 @@ test.jtx > xrpl.net
test.jtx > xrpl.protocol test.jtx > xrpl.protocol
test.jtx > xrpl.resource test.jtx > xrpl.resource
test.jtx > xrpl.server test.jtx > xrpl.server
test.jtx > xrpl.tx
test.ledger > test.jtx test.ledger > test.jtx
test.ledger > test.toplevel test.ledger > test.toplevel
test.ledger > xrpl.basics test.ledger > xrpl.basics
test.ledger > xrpld.app
test.ledger > xrpld.core test.ledger > xrpld.core
test.ledger > xrpl.ledger test.ledger > xrpl.ledger
test.ledger > xrpl.protocol test.ledger > xrpl.protocol
@@ -117,8 +96,8 @@ test.nodestore > test.jtx
test.nodestore > test.toplevel test.nodestore > test.toplevel
test.nodestore > test.unit_test test.nodestore > test.unit_test
test.nodestore > xrpl.basics test.nodestore > xrpl.basics
test.nodestore > xrpld.core
test.nodestore > xrpl.nodestore test.nodestore > xrpl.nodestore
test.nodestore > xrpl.rdb
test.overlay > test.jtx test.overlay > test.jtx
test.overlay > test.toplevel test.overlay > test.toplevel
test.overlay > test.unit_test test.overlay > test.unit_test
@@ -126,7 +105,6 @@ test.overlay > xrpl.basics
test.overlay > xrpld.app test.overlay > xrpld.app
test.overlay > xrpld.overlay test.overlay > xrpld.overlay
test.overlay > xrpld.peerfinder test.overlay > xrpld.peerfinder
test.overlay > xrpl.ledger
test.overlay > xrpl.nodestore test.overlay > xrpl.nodestore
test.overlay > xrpl.protocol test.overlay > xrpl.protocol
test.overlay > xrpl.shamap test.overlay > xrpl.shamap
@@ -137,7 +115,6 @@ test.peerfinder > xrpld.core
test.peerfinder > xrpld.peerfinder test.peerfinder > xrpld.peerfinder
test.peerfinder > xrpl.protocol test.peerfinder > xrpl.protocol
test.protocol > test.toplevel test.protocol > test.toplevel
test.protocol > test.unit_test
test.protocol > xrpl.basics test.protocol > xrpl.basics
test.protocol > xrpl.json test.protocol > xrpl.json
test.protocol > xrpl.protocol test.protocol > xrpl.protocol
@@ -153,11 +130,8 @@ test.rpc > xrpld.core
test.rpc > xrpld.overlay test.rpc > xrpld.overlay
test.rpc > xrpld.rpc test.rpc > xrpld.rpc
test.rpc > xrpl.json test.rpc > xrpl.json
test.rpc > xrpl.ledger
test.rpc > xrpl.protocol test.rpc > xrpl.protocol
test.rpc > xrpl.resource test.rpc > xrpl.resource
test.rpc > xrpl.server
test.rpc > xrpl.tx
test.server > test.jtx test.server > test.jtx
test.server > test.toplevel test.server > test.toplevel
test.server > test.unit_test test.server > test.unit_test
@@ -175,88 +149,61 @@ test.shamap > xrpl.shamap
test.toplevel > test.csf test.toplevel > test.csf
test.toplevel > xrpl.json test.toplevel > xrpl.json
test.unit_test > xrpl.basics test.unit_test > xrpl.basics
test.unit_test > xrpl.protocol
tests.libxrpl > xrpl.basics tests.libxrpl > xrpl.basics
tests.libxrpl > xrpl.json tests.libxrpl > xrpl.json
tests.libxrpl > xrpl.net tests.libxrpl > xrpl.net
tests.libxrpl > xrpl.protocol
tests.libxrpl > xrpl.protocol_autogen
xrpl.conditions > xrpl.basics
xrpl.conditions > xrpl.protocol
xrpl.core > xrpl.basics xrpl.core > xrpl.basics
xrpl.core > xrpl.json xrpl.core > xrpl.json
xrpl.core > xrpl.protocol
xrpl.json > xrpl.basics xrpl.json > xrpl.basics
xrpl.ledger > xrpl.basics xrpl.ledger > xrpl.basics
xrpl.ledger > xrpl.protocol xrpl.ledger > xrpl.protocol
xrpl.ledger > xrpl.server
xrpl.ledger > xrpl.shamap
xrpl.net > xrpl.basics xrpl.net > xrpl.basics
xrpl.nodestore > xrpl.basics xrpl.nodestore > xrpl.basics
xrpl.nodestore > xrpl.protocol xrpl.nodestore > xrpl.protocol
xrpl.protocol > xrpl.basics xrpl.protocol > xrpl.basics
xrpl.protocol > xrpl.json xrpl.protocol > xrpl.json
xrpl.protocol_autogen > xrpl.json
xrpl.protocol_autogen > xrpl.protocol
xrpl.rdb > xrpl.basics
xrpl.rdb > xrpl.core
xrpl.rdb > xrpl.protocol
xrpl.resource > xrpl.basics xrpl.resource > xrpl.basics
xrpl.resource > xrpl.json xrpl.resource > xrpl.json
xrpl.resource > xrpl.protocol xrpl.resource > xrpl.protocol
xrpl.server > xrpl.basics xrpl.server > xrpl.basics
xrpl.server > xrpl.core
xrpl.server > xrpl.json xrpl.server > xrpl.json
xrpl.server > xrpl.protocol xrpl.server > xrpl.protocol
xrpl.server > xrpl.rdb
xrpl.server > xrpl.resource
xrpl.server > xrpl.shamap
xrpl.shamap > xrpl.basics xrpl.shamap > xrpl.basics
xrpl.shamap > xrpl.nodestore xrpl.shamap > xrpl.nodestore
xrpl.shamap > xrpl.protocol xrpl.shamap > xrpl.protocol
xrpl.tx > xrpl.basics
xrpl.tx > xrpl.core
xrpl.tx > xrpl.ledger
xrpl.tx > xrpl.protocol
xrpld.app > test.unit_test xrpld.app > test.unit_test
xrpld.app > xrpl.basics xrpld.app > xrpl.basics
xrpld.app > xrpl.core xrpld.app > xrpl.core
xrpld.app > xrpld.conditions
xrpld.app > xrpld.consensus xrpld.app > xrpld.consensus
xrpld.app > xrpld.core
xrpld.app > xrpl.json xrpld.app > xrpl.json
xrpld.app > xrpl.ledger xrpld.app > xrpl.ledger
xrpld.app > xrpl.net xrpld.app > xrpl.net
xrpld.app > xrpl.nodestore xrpld.app > xrpl.nodestore
xrpld.app > xrpl.protocol xrpld.app > xrpl.protocol
xrpld.app > xrpl.rdb
xrpld.app > xrpl.resource xrpld.app > xrpl.resource
xrpld.app > xrpl.server
xrpld.app > xrpl.shamap xrpld.app > xrpl.shamap
xrpld.app > xrpl.tx xrpld.conditions > xrpl.basics
xrpld.conditions > xrpl.protocol
xrpld.consensus > xrpl.basics xrpld.consensus > xrpl.basics
xrpld.consensus > xrpl.json xrpld.consensus > xrpl.json
xrpld.consensus > xrpl.ledger
xrpld.consensus > xrpl.protocol xrpld.consensus > xrpl.protocol
xrpld.core > xrpl.basics xrpld.core > xrpl.basics
xrpld.core > xrpl.core xrpld.core > xrpl.core
xrpld.core > xrpl.json xrpld.core > xrpl.json
xrpld.core > xrpl.net xrpld.core > xrpl.net
xrpld.core > xrpl.protocol xrpld.core > xrpl.protocol
xrpld.core > xrpl.rdb
xrpld.overlay > xrpl.basics xrpld.overlay > xrpl.basics
xrpld.overlay > xrpl.core xrpld.overlay > xrpl.core
xrpld.overlay > xrpld.core xrpld.overlay > xrpld.core
xrpld.overlay > xrpld.peerfinder xrpld.overlay > xrpld.peerfinder
xrpld.overlay > xrpl.json xrpld.overlay > xrpl.json
xrpld.overlay > xrpl.protocol xrpld.overlay > xrpl.protocol
xrpld.overlay > xrpl.rdb
xrpld.overlay > xrpl.resource xrpld.overlay > xrpl.resource
xrpld.overlay > xrpl.server xrpld.overlay > xrpl.server
xrpld.overlay > xrpl.tx
xrpld.peerfinder > xrpl.basics xrpld.peerfinder > xrpl.basics
xrpld.peerfinder > xrpld.core xrpld.peerfinder > xrpld.core
xrpld.peerfinder > xrpl.protocol xrpld.peerfinder > xrpl.protocol
xrpld.peerfinder > xrpl.rdb
xrpld.perflog > xrpl.basics xrpld.perflog > xrpl.basics
xrpld.perflog > xrpl.core xrpld.perflog > xrpl.core
xrpld.perflog > xrpld.rpc xrpld.perflog > xrpld.rpc
@@ -269,8 +216,6 @@ xrpld.rpc > xrpl.ledger
xrpld.rpc > xrpl.net xrpld.rpc > xrpl.net
xrpld.rpc > xrpl.nodestore xrpld.rpc > xrpl.nodestore
xrpld.rpc > xrpl.protocol xrpld.rpc > xrpl.protocol
xrpld.rpc > xrpl.rdb
xrpld.rpc > xrpl.resource xrpld.rpc > xrpl.resource
xrpld.rpc > xrpl.server xrpld.rpc > xrpl.server
xrpld.rpc > xrpl.tx
xrpld.shamap > xrpl.shamap xrpld.shamap > xrpl.shamap

View File

@@ -1,30 +0,0 @@
#!/bin/bash
# Exit the script as soon as an error occurs.
set -e
# This script checks whether there are no new include guards introduced by a new
# PR, as header files should use "#pragma once" instead. The script assumes any
# include guards will use "XRPL_" as prefix.
# Usage: .github/scripts/rename/include.sh <repository directory>
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <repository directory>"
exit 1
fi
DIRECTORY=$1
echo "Processing directory: ${DIRECTORY}"
if [ ! -d "${DIRECTORY}" ]; then
echo "Error: Directory '${DIRECTORY}' does not exist."
exit 1
fi
find "${DIRECTORY}" -type f \( -name "*.h" -o -name "*.hpp" -o -name "*.ipp" \) | while read -r FILE; do
echo "Processing file: ${FILE}"
if grep -q "#ifndef XRPL_" "${FILE}"; then
echo "Please replace all include guards by #pragma once."
exit 1
fi
done
echo "Checking complete."

View File

@@ -44,27 +44,29 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# We build and test all configurations by default, except for Windows in # We build and test all configurations by default, except for Windows in
# Debug, because it is too slow, as well as when code coverage is # Debug, because it is too slow, as well as when code coverage is
# enabled as that mode already runs the tests. # enabled as that mode already runs the tests.
build_only = False build_only = True
if os["distro_name"] == "windows" and build_type == "Debug": if os["distro_name"] == "windows" and build_type == "Debug":
build_only = True build_only = True
# Only generate a subset of configurations in PRs. # Only generate a subset of configurations in PRs.
if not all: if not all:
# Debian: # Debian:
# - Bookworm using GCC 13: Release on linux/amd64, set the reference # - Bookworm using GCC 13: Release and Unity on linux/amd64, set
# fee to 500. # the reference fee to 500.
# - Bookworm using GCC 15: Debug on linux/amd64, enable code # - Bookworm using GCC 15: Debug and no Unity on linux/amd64, enable
# coverage (which will be done below). # code coverage (which will be done below).
# - Bookworm using Clang 16: Debug on linux/amd64, enable voidstar. # - Bookworm using Clang 16: Debug and no Unity on linux/arm64,
# - Bookworm using Clang 17: Release on linux/amd64, set the # enable voidstar.
# reference fee to 1000. # - Bookworm using Clang 17: Release and no Unity on linux/amd64,
# - Bookworm using Clang 20: Debug on linux/amd64. # set the reference fee to 1000.
# - Bookworm using Clang 20: Debug and Unity on linux/amd64.
if os["distro_name"] == "debian": if os["distro_name"] == "debian":
skip = True skip = True
if os["distro_version"] == "bookworm": if os["distro_version"] == "bookworm":
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13" f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
and build_type == "Release" and build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}" cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}"
@@ -72,19 +74,22 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15" f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and build_type == "Debug" and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
skip = False skip = False
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-16" f"{os['compiler_name']}-{os['compiler_version']}" == "clang-16"
and build_type == "Debug" and build_type == "Debug"
and architecture["platform"] == "linux/amd64" and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/arm64"
): ):
cmake_args = f"-Dvoidstar=ON {cmake_args}" cmake_args = f"-Dvoidstar=ON {cmake_args}"
skip = False skip = False
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-17" f"{os['compiler_name']}-{os['compiler_version']}" == "clang-17"
and build_type == "Release" and build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}" cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=1000 {cmake_args}"
@@ -92,6 +97,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20" f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
and build_type == "Debug" and build_type == "Debug"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
skip = False skip = False
@@ -99,14 +105,15 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue continue
# RHEL: # RHEL:
# - 9 using GCC 12: Debug on linux/amd64. # - 9 using GCC 12: Debug and Unity on linux/amd64.
# - 10 using Clang: Release on linux/amd64. # - 10 using Clang: Release and no Unity on linux/amd64.
if os["distro_name"] == "rhel": if os["distro_name"] == "rhel":
skip = True skip = True
if os["distro_version"] == "9": if os["distro_version"] == "9":
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12" f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Debug" and build_type == "Debug"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
skip = False skip = False
@@ -114,6 +121,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-any" f"{os['compiler_name']}-{os['compiler_version']}" == "clang-any"
and build_type == "Release" and build_type == "Release"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
skip = False skip = False
@@ -121,16 +129,17 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue continue
# Ubuntu: # Ubuntu:
# - Jammy using GCC 12: Debug on linux/arm64. # - Jammy using GCC 12: Debug and no Unity on linux/arm64.
# - Noble using GCC 14: Release on linux/amd64. # - Noble using GCC 14: Release and Unity on linux/amd64.
# - Noble using Clang 18: Debug on linux/amd64. # - Noble using Clang 18: Debug and no Unity on linux/amd64.
# - Noble using Clang 19: Release on linux/arm64. # - Noble using Clang 19: Release and Unity on linux/arm64.
if os["distro_name"] == "ubuntu": if os["distro_name"] == "ubuntu":
skip = True skip = True
if os["distro_version"] == "jammy": if os["distro_version"] == "jammy":
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12" f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Debug" and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/arm64" and architecture["platform"] == "linux/arm64"
): ):
skip = False skip = False
@@ -138,18 +147,21 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14" f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-14"
and build_type == "Release" and build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
skip = False skip = False
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-18" f"{os['compiler_name']}-{os['compiler_version']}" == "clang-18"
and build_type == "Debug" and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
skip = False skip = False
if ( if (
f"{os['compiler_name']}-{os['compiler_version']}" == "clang-19" f"{os['compiler_name']}-{os['compiler_version']}" == "clang-19"
and build_type == "Release" and build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "linux/arm64" and architecture["platform"] == "linux/arm64"
): ):
skip = False skip = False
@@ -157,16 +169,20 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
continue continue
# MacOS: # MacOS:
# - Debug on macos/arm64. # - Debug and no Unity on macos/arm64.
if os["distro_name"] == "macos" and not ( if os["distro_name"] == "macos" and not (
build_type == "Debug" and architecture["platform"] == "macos/arm64" build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "macos/arm64"
): ):
continue continue
# Windows: # Windows:
# - Release on windows/amd64. # - Release and Unity on windows/amd64.
if os["distro_name"] == "windows" and not ( if os["distro_name"] == "windows" and not (
build_type == "Release" and architecture["platform"] == "windows/amd64" build_type == "Release"
and "-Dunity=ON" in cmake_args
and architecture["platform"] == "windows/amd64"
): ):
continue continue
@@ -193,28 +209,18 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
): ):
continue continue
# Enable code coverage for Debian Bookworm using GCC 15 in Debug on # Enable code coverage for Debian Bookworm using GCC 15 in Debug and no
# linux/amd64 # Unity on linux/amd64
if ( if (
f"{os['distro_name']}-{os['distro_version']}" == "debian-bookworm" f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and build_type == "Debug" and build_type == "Debug"
and "-Dunity=OFF" in cmake_args
and architecture["platform"] == "linux/amd64" and architecture["platform"] == "linux/amd64"
): ):
cmake_args = f"{cmake_args} -Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0" cmake_args = f"-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}"
# Enable unity build for Ubuntu Jammy using GCC 12 in Debug on
# linux/amd64.
if (
f"{os['distro_name']}-{os['distro_version']}" == "ubuntu-jammy"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-12"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"{cmake_args} -Dunity=ON"
# Generate a unique name for the configuration, e.g. macos-arm64-debug # Generate a unique name for the configuration, e.g. macos-arm64-debug
# or debian-bookworm-gcc-12-amd64-release. # or debian-bookworm-gcc-12-amd64-release-unity.
config_name = os["distro_name"] config_name = os["distro_name"]
if (n := os["distro_version"]) != "": if (n := os["distro_version"]) != "":
config_name += f"-{n}" config_name += f"-{n}"

View File

@@ -208,5 +208,5 @@
} }
], ],
"build_type": ["Debug", "Release"], "build_type": ["Debug", "Release"],
"cmake_args": [""] "cmake_args": ["-Dunity=OFF", "-Dunity=ON"]
} }

View File

@@ -15,5 +15,8 @@
} }
], ],
"build_type": ["Debug", "Release"], "build_type": ["Debug", "Release"],
"cmake_args": ["-DCMAKE_POLICY_VERSION_MINIMUM=3.5"] "cmake_args": [
"-Dunity=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"-Dunity=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5"
]
} }

View File

@@ -15,5 +15,5 @@
} }
], ],
"build_type": ["Debug", "Release"], "build_type": ["Debug", "Release"],
"cmake_args": [""] "cmake_args": ["-Dunity=OFF", "-Dunity=ON"]
} }

View File

@@ -1,13 +0,0 @@
name: Check PR commits
on:
pull_request_target:
# The action needs to have write permissions to post comments on the PR.
permissions:
contents: read
pull-requests: write
jobs:
check_commits:
uses: XRPLF/actions/.github/workflows/check-pr-commits.yml@481048b78b94ac3343d1292b4ef125a813879f2b

View File

@@ -1,14 +0,0 @@
name: Check PR title
on:
merge_group:
types:
- checks_requested
pull_request:
types: [opened, edited, reopened, synchronize, ready_for_review]
branches: [develop]
jobs:
check_title:
if: ${{ github.event.pull_request.draft != true }}
uses: XRPLF/actions/.github/workflows/check-pr-title.yml@e2c7f400d1e85ae65dad552fd425169fbacca4a3

View File

@@ -1,25 +0,0 @@
name: Label PRs with merge conflicts
on:
# So that PRs touching the same files as the push are updated.
push:
# So that the `dirtyLabel` is removed if conflicts are resolved.
# We recommend `pull_request_target` so that github secrets are available.
# In `pull_request` we wouldn't be able to change labels of fork PRs.
pull_request_target:
types: [synchronize]
permissions:
pull-requests: write
jobs:
main:
runs-on: ubuntu-latest
steps:
- name: Check if PRs are dirty
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 # v3.0.3
with:
dirtyLabel: "PR: has conflicts"
repoToken: "${{ secrets.GITHUB_TOKEN }}"
commentOnDirty: "This PR has conflicts, please resolve them in order for the PR to be reviewed."
commentOnClean: "All conflicts have been resolved. Assigned reviewers can now start or resume their review."

View File

@@ -33,7 +33,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Determine changed files - name: Determine changed files
# This step checks whether any files have changed that should # This step checks whether any files have changed that should
# cause the next jobs to run. We do it this way rather than # cause the next jobs to run. We do it this way rather than
@@ -46,7 +46,7 @@ jobs:
# that Github considers any skipped jobs to have passed, and in # that Github considers any skipped jobs to have passed, and in
# turn the required checks as well. # turn the required checks as well.
id: changes id: changes
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5 uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with: with:
files: | files: |
# These paths are unique to `on-pr.yml`. # These paths are unique to `on-pr.yml`.
@@ -59,18 +59,14 @@ jobs:
# Keep the paths below in sync with those in `on-trigger.yml`. # Keep the paths below in sync with those in `on-trigger.yml`.
.github/actions/build-deps/** .github/actions/build-deps/**
.github/actions/build-test/** .github/actions/build-test/**
.github/actions/generate-version/**
.github/actions/setup-conan/** .github/actions/setup-conan/**
.github/scripts/strategy-matrix/** .github/scripts/strategy-matrix/**
.github/workflows/reusable-build.yml .github/workflows/reusable-build.yml
.github/workflows/reusable-build-test-config.yml .github/workflows/reusable-build-test-config.yml
.github/workflows/reusable-build-test.yml .github/workflows/reusable-build-test.yml
.github/workflows/reusable-clang-tidy.yml
.github/workflows/reusable-clang-tidy-files.yml
.github/workflows/reusable-strategy-matrix.yml .github/workflows/reusable-strategy-matrix.yml
.github/workflows/reusable-test.yml .github/workflows/reusable-test.yml
.github/workflows/reusable-upload-recipe.yml .github/workflows/reusable-upload-recipe.yml
.clang-tidy
.codecov.yml .codecov.yml
cmake/** cmake/**
conan/** conan/**
@@ -110,17 +106,6 @@ jobs:
if: ${{ needs.should-run.outputs.go == 'true' }} if: ${{ needs.should-run.outputs.go == 'true' }}
uses: ./.github/workflows/reusable-check-rename.yml uses: ./.github/workflows/reusable-check-rename.yml
clang-tidy:
needs: should-run
if: ${{ needs.should-run.outputs.go == 'true' }}
uses: ./.github/workflows/reusable-clang-tidy.yml
permissions:
issues: write
contents: read
with:
check_only_changed: true
create_issue_on_failure: false
build-test: build-test:
needs: should-run needs: should-run
if: ${{ needs.should-run.outputs.go == 'true' }} if: ${{ needs.should-run.outputs.go == 'true' }}
@@ -141,8 +126,9 @@ jobs:
needs: needs:
- should-run - should-run
- build-test - build-test
# Only run when committing to a PR that targets a release branch. # Only run when committing to a PR that targets a release branch in the
if: ${{ github.repository == 'XRPLF/rippled' && needs.should-run.outputs.go == 'true' && github.event_name == 'pull_request' && startsWith(github.event.pull_request.base.ref, 'release') }} # XRPLF repository.
if: ${{ github.repository_owner == 'XRPLF' && needs.should-run.outputs.go == 'true' && startsWith(github.ref, 'refs/heads/release') }}
uses: ./.github/workflows/reusable-upload-recipe.yml uses: ./.github/workflows/reusable-upload-recipe.yml
secrets: secrets:
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}
@@ -169,7 +155,6 @@ jobs:
needs: needs:
- check-levelization - check-levelization
- check-rename - check-rename
- clang-tidy
- build-test - build-test
- upload-recipe - upload-recipe
- notify-clio - notify-clio

View File

@@ -5,7 +5,7 @@ name: Tag
on: on:
push: push:
tags: tags:
- "[0-9]+.[0-9]+.[0-9]*" - "v*"
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
@@ -17,7 +17,8 @@ defaults:
jobs: jobs:
upload-recipe: upload-recipe:
if: ${{ github.repository == 'XRPLF/rippled' }} # Only run when a tag is pushed to the XRPLF repository.
if: ${{ github.repository_owner == 'XRPLF' }}
uses: ./.github/workflows/reusable-upload-recipe.yml uses: ./.github/workflows/reusable-upload-recipe.yml
secrets: secrets:
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}

View File

@@ -16,18 +16,14 @@ on:
# Keep the paths below in sync with those in `on-pr.yml`. # Keep the paths below in sync with those in `on-pr.yml`.
- ".github/actions/build-deps/**" - ".github/actions/build-deps/**"
- ".github/actions/build-test/**" - ".github/actions/build-test/**"
- ".github/actions/generate-version/**"
- ".github/actions/setup-conan/**" - ".github/actions/setup-conan/**"
- ".github/scripts/strategy-matrix/**" - ".github/scripts/strategy-matrix/**"
- ".github/workflows/reusable-build.yml" - ".github/workflows/reusable-build.yml"
- ".github/workflows/reusable-build-test-config.yml" - ".github/workflows/reusable-build-test-config.yml"
- ".github/workflows/reusable-build-test.yml" - ".github/workflows/reusable-build-test.yml"
- ".github/workflows/reusable-clang-tidy.yml"
- ".github/workflows/reusable-clang-tidy-files.yml"
- ".github/workflows/reusable-strategy-matrix.yml" - ".github/workflows/reusable-strategy-matrix.yml"
- ".github/workflows/reusable-test.yml" - ".github/workflows/reusable-test.yml"
- ".github/workflows/reusable-upload-recipe.yml" - ".github/workflows/reusable-upload-recipe.yml"
- ".clang-tidy"
- ".codecov.yml" - ".codecov.yml"
- "cmake/**" - "cmake/**"
- "conan/**" - "conan/**"
@@ -63,15 +59,6 @@ defaults:
shell: bash shell: bash
jobs: jobs:
clang-tidy:
uses: ./.github/workflows/reusable-clang-tidy.yml
permissions:
issues: write
contents: read
with:
check_only_changed: false
create_issue_on_failure: ${{ github.event_name == 'schedule' }}
build-test: build-test:
uses: ./.github/workflows/reusable-build-test.yml uses: ./.github/workflows/reusable-build-test.yml
strategy: strategy:
@@ -92,8 +79,8 @@ jobs:
upload-recipe: upload-recipe:
needs: build-test needs: build-test
# Only run when pushing to the develop branch. # Only run when pushing to the develop branch in the XRPLF repository.
if: ${{ github.repository == 'XRPLF/rippled' && github.event_name == 'push' && github.ref == 'refs/heads/develop' }} if: ${{ github.repository_owner == 'XRPLF' && github.event_name == 'push' && github.ref == 'refs/heads/develop' }}
uses: ./.github/workflows/reusable-upload-recipe.yml uses: ./.github/workflows/reusable-upload-recipe.yml
secrets: secrets:
remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }} remote_username: ${{ secrets.CONAN_REMOTE_USERNAME }}

View File

@@ -1,9 +1,6 @@
name: Run pre-commit hooks name: Run pre-commit hooks
on: on:
merge_group:
types:
- checks_requested
pull_request: pull_request:
push: push:
branches: branches:
@@ -14,7 +11,7 @@ on:
jobs: jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks. # Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks: run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@e7896f15cc60d0da1a272c77ee5c4026b424f9c7 uses: XRPLF/actions/.github/workflows/pre-commit.yml@282890f46d6921249d5659dd38babcb0bd8aef48
with: with:
runs_on: ubuntu-latest runs_on: ubuntu-latest
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-41ec7c1" }' container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-ab4d1f0" }'

View File

@@ -4,17 +4,6 @@ name: Build and publish documentation
on: on:
push: push:
branches:
- "develop"
paths:
- ".github/workflows/publish-docs.yml"
- "*.md"
- "**/*.md"
- "docs/**"
- "include/**"
- "src/libxrpl/**"
- "src/xrpld/**"
pull_request:
paths: paths:
- ".github/workflows/publish-docs.yml" - ".github/workflows/publish-docs.yml"
- "*.md" - "*.md"
@@ -34,25 +23,20 @@ defaults:
env: env:
BUILD_DIR: build BUILD_DIR: build
# ubuntu-latest has only 2 CPUs for private repositories NPROC_SUBTRACT: 2
# https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for--private-repositories
NPROC_SUBTRACT: ${{ github.event.repository.visibility == 'public' && '2' || '1' }}
jobs: jobs:
build: publish:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: ghcr.io/xrplf/ci/tools-rippled-documentation:sha-a8c7be1 container: ghcr.io/xrplf/ci/tools-rippled-documentation:sha-a8c7be1
permissions:
contents: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e
with:
enable_ccache: false
- name: Get number of processors - name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf uses: XRPLF/actions/get-nproc@2ece4ec6ab7de266859a6f053571425b2bd684b6
id: nproc id: nproc
with: with:
subtract: ${{ env.NPROC_SUBTRACT }} subtract: ${{ env.NPROC_SUBTRACT }}
@@ -80,23 +64,9 @@ jobs:
cmake -Donly_docs=ON .. cmake -Donly_docs=ON ..
cmake --build . --target docs --parallel ${BUILD_NPROC} cmake --build . --target docs --parallel ${BUILD_NPROC}
- name: Create documentation artifact - name: Publish documentation
if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && github.event_name == 'push' }} if: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }}
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0 uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
with: with:
path: ${{ env.BUILD_DIR }}/docs/html github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ${{ env.BUILD_DIR }}/docs/html
deploy:
if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && github.event_name == 'push' }}
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deploy
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0

View File

@@ -76,7 +76,7 @@ jobs:
name: ${{ inputs.config_name }} name: ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }} runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }} container: ${{ inputs.image != '' && inputs.image || null }}
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 60 }} timeout-minutes: 60
env: env:
# Use a namespace to keep the objects separate for each configuration. # Use a namespace to keep the objects separate for each configuration.
CCACHE_NAMESPACE: ${{ inputs.config_name }} CCACHE_NAMESPACE: ${{ inputs.config_name }}
@@ -101,13 +101,13 @@ jobs:
steps: steps:
- name: Cleanup workspace (macOS and Windows) - name: Cleanup workspace (macOS and Windows)
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }} if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4 uses: XRPLF/actions/cleanup-workspace@2ece4ec6ab7de266859a6f053571425b2bd684b6
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e uses: XRPLF/actions/prepare-runner@f05cab7b8541eee6473aa42beb9d2fe35608a190
with: with:
enable_ccache: ${{ inputs.ccache_enabled }} enable_ccache: ${{ inputs.ccache_enabled }}
@@ -119,14 +119,12 @@ jobs:
uses: ./.github/actions/print-env uses: ./.github/actions/print-env
- name: Get number of processors - name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf uses: XRPLF/actions/get-nproc@2ece4ec6ab7de266859a6f053571425b2bd684b6
id: nproc id: nproc
with: with:
subtract: ${{ inputs.nproc_subtract }} subtract: ${{ inputs.nproc_subtract }}
- name: Setup Conan - name: Setup Conan
env:
SANITIZERS: ${{ inputs.sanitizers }}
uses: ./.github/actions/setup-conan uses: ./.github/actions/setup-conan
- name: Build dependencies - name: Build dependencies
@@ -166,29 +164,6 @@ jobs:
--parallel "${BUILD_NPROC}" \ --parallel "${BUILD_NPROC}" \
--target "${CMAKE_TARGET}" --target "${CMAKE_TARGET}"
- name: Check protocol autogen files are up-to-date
env:
MESSAGE: |
The generated protocol wrapper classes are out of date.
This typically happens when your branch is behind develop and
the macro files or generator scripts have changed.
To fix this:
1. Update your branch from develop (merge or rebase)
2. Build with code generation enabled (XRPL_NO_CODEGEN=OFF)
3. Commit and push the regenerated files
run: |
set -e
DIFF=$(git status --porcelain -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen)
if [ -n "${DIFF}" ]; then
echo "::error::Generated protocol files are out of date"
git diff -- include/xrpl/protocol_autogen src/tests/libxrpl/protocol_autogen
echo "${MESSAGE}"
exit 1
fi
- name: Show ccache statistics - name: Show ccache statistics
if: ${{ inputs.ccache_enabled }} if: ${{ inputs.ccache_enabled }}
run: | run: |
@@ -199,8 +174,8 @@ jobs:
fi fi
- name: Upload the binary (Linux) - name: Upload the binary (Linux)
if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && runner.os == 'Linux' }} if: ${{ github.repository_owner == 'XRPLF' && runner.os == 'Linux' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with: with:
name: xrpld-${{ inputs.config_name }} name: xrpld-${{ inputs.config_name }}
path: ${{ env.BUILD_DIR }}/xrpld path: ${{ env.BUILD_DIR }}/xrpld
@@ -227,17 +202,11 @@ jobs:
- name: Set sanitizer options - name: Set sanitizer options
if: ${{ !inputs.build_only && env.SANITIZERS_ENABLED == 'true' }} if: ${{ !inputs.build_only && env.SANITIZERS_ENABLED == 'true' }}
env:
CONFIG_NAME: ${{ inputs.config_name }}
run: | run: |
ASAN_OPTS="include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-asan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp" echo "ASAN_OPTIONS=print_stacktrace=1:detect_container_overflow=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp" >> ${GITHUB_ENV}
if [[ "${CONFIG_NAME}" == *gcc* ]]; then echo "TSAN_OPTIONS=second_deadlock_stack=1:halt_on_error=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
ASAN_OPTS="${ASAN_OPTS}:alloc_dealloc_mismatch=0" echo "UBSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
fi echo "LSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
echo "ASAN_OPTIONS=${ASAN_OPTS}" >> ${GITHUB_ENV}
echo "TSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-tsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV}
echo "UBSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV}
echo "LSAN_OPTIONS=include=${GITHUB_WORKSPACE}/sanitizers/suppressions/runtime-lsan-options.txt:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV}
- name: Run the separate tests - name: Run the separate tests
if: ${{ !inputs.build_only }} if: ${{ !inputs.build_only }}
@@ -258,23 +227,8 @@ jobs:
env: env:
BUILD_NPROC: ${{ steps.nproc.outputs.nproc }} BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
run: | run: |
set -o pipefail ./xrpld --unittest --unittest-jobs "${BUILD_NPROC}"
# Coverage builds are slower due to instrumentation; use fewer parallel jobs to avoid flakiness
[ "$COVERAGE_ENABLED" = "true" ] && BUILD_NPROC=$(( BUILD_NPROC - 2 ))
./xrpld --unittest --unittest-jobs "${BUILD_NPROC}" 2>&1 | tee unittest.log
- name: Show test failure summary
if: ${{ failure() && !inputs.build_only }}
working-directory: ${{ runner.os == 'Windows' && format('{0}/{1}', env.BUILD_DIR, inputs.build_type) || env.BUILD_DIR }}
run: |
if [ ! -f unittest.log ]; then
echo "unittest.log not found; embedded tests may not have run."
exit 0
fi
if ! grep -E "failed" unittest.log; then
echo "Log present but no failure lines found in unittest.log."
fi
- name: Debug failure (Linux) - name: Debug failure (Linux)
if: ${{ failure() && runner.os == 'Linux' && !inputs.build_only }} if: ${{ failure() && runner.os == 'Linux' && !inputs.build_only }}
run: | run: |
@@ -297,8 +251,8 @@ jobs:
--target coverage --target coverage
- name: Upload coverage report - name: Upload coverage report
if: ${{ github.repository == 'XRPLF/rippled' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }} if: ${{ github.repository_owner == 'XRPLF' && !inputs.build_only && env.COVERAGE_ENABLED == 'true' }}
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
with: with:
disable_search: true disable_search: true
disable_telem: true disable_telem: true

View File

@@ -18,9 +18,9 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Check levelization - name: Check levelization
run: python .github/scripts/levelization/generate.py run: .github/scripts/levelization/generate.sh
- name: Check for differences - name: Check for differences
env: env:
MESSAGE: | MESSAGE: |
@@ -32,7 +32,7 @@ jobs:
removed from loops.txt, it's probably an improvement, while if removed from loops.txt, it's probably an improvement, while if
something was added, it's probably a regression. something was added, it's probably a regression.
Run '.github/scripts/levelization/generate.py' in your repo, commit Run '.github/scripts/levelization/generate.sh' in your repo, commit
and push the changes. See .github/scripts/levelization/README.md for and push the changes. See .github/scripts/levelization/README.md for
more info. more info.
run: | run: |

View File

@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Check definitions - name: Check definitions
run: .github/scripts/rename/definitions.sh . run: .github/scripts/rename/definitions.sh .
- name: Check copyright notices - name: Check copyright notices
@@ -31,8 +31,6 @@ jobs:
run: .github/scripts/rename/namespace.sh . run: .github/scripts/rename/namespace.sh .
- name: Check config name - name: Check config name
run: .github/scripts/rename/config.sh . run: .github/scripts/rename/config.sh .
- name: Check include guards
run: .github/scripts/rename/include.sh .
- name: Check for differences - name: Check for differences
env: env:
MESSAGE: | MESSAGE: |

View File

@@ -1,162 +0,0 @@
name: Run clang-tidy on files
on:
workflow_call:
inputs:
files:
description: "List of files to check (empty means check all files)"
type: string
default: ""
create_issue_on_failure:
description: "Whether to create an issue if the check failed"
type: boolean
default: false
defaults:
run:
shell: bash
env:
# Conan installs the generators in the build/generators directory, see the
# layout() method in conanfile.py. We then run CMake from the build directory.
BUILD_DIR: build
BUILD_TYPE: Release
jobs:
run-clang-tidy:
name: Run clang tidy
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: "ghcr.io/xrplf/ci/debian-trixie:clang-21-sha-53033a2"
permissions:
issues: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e
with:
enable_ccache: false
- name: Print build environment
uses: ./.github/actions/print-env
- name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf
id: nproc
- name: Setup Conan
uses: ./.github/actions/setup-conan
- name: Build dependencies
uses: ./.github/actions/build-deps
with:
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ env.BUILD_TYPE }}
log_verbosity: verbose
- name: Configure CMake
working-directory: ${{ env.BUILD_DIR }}
run: |
cmake \
-G 'Ninja' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
-Dtests=ON \
-Dwerr=ON \
-Dxrpld=ON \
..
# clang-tidy needs headers generated from proto files
- name: Build libxrpl.libpb
working-directory: ${{ env.BUILD_DIR }}
run: |
ninja -j ${{ steps.nproc.outputs.nproc }} xrpl.libpb
- name: Run clang tidy
id: run_clang_tidy
continue-on-error: true
env:
TARGETS: ${{ inputs.files != '' && inputs.files || 'src tests' }}
run: |
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -allow-no-checks ${TARGETS} 2>&1 | tee clang-tidy-output.txt
- name: Upload clang-tidy output
if: ${{ (github.repository_owner == 'XRPLF' || github.event.repository.visibility == 'public') && steps.run_clang_tidy.outcome != 'success' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: clang-tidy-results
path: clang-tidy-output.txt
retention-days: 30
- name: Create an issue
if: steps.run_clang_tidy.outcome != 'success' && inputs.create_issue_on_failure
id: create_issue
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
# Prepare issue body with clang-tidy output
cat > issue.md <<EOF
## Clang-tidy Check Failed
**Workflow:** ${{ github.workflow }}
**Run ID:** ${{ github.run_id }}
**Commit:** ${{ github.sha }}
**Branch/Ref:** ${{ github.ref }}
**Triggered by:** ${{ github.actor }}
### Clang-tidy Output:
\`\`\`
EOF
# Append clang-tidy output (filter for errors and warnings)
if [ -f clang-tidy-output.txt ]; then
# Extract lines containing 'error:', 'warning:', or 'note:'
grep -E '(error:|warning:|note:)' clang-tidy-output.txt > filtered-output.txt || true
# If filtered output is empty, use original (might be a different error format)
if [ ! -s filtered-output.txt ]; then
cp clang-tidy-output.txt filtered-output.txt
fi
# Truncate if too large
head -c 60000 filtered-output.txt >> issue.md
if [ "$(wc -c < filtered-output.txt)" -gt 60000 ]; then
echo "" >> issue.md
echo "... (output truncated, see artifacts for full output)" >> issue.md
fi
rm filtered-output.txt
else
echo "No output file found" >> issue.md
fi
cat >> issue.md <<EOF
\`\`\`
**Workflow run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
---
*This issue was automatically created by the clang-tidy workflow.*
EOF
# Create the issue
gh issue create \
--label "Bug,Clang-tidy" \
--title "Clang-tidy check failed" \
--body-file ./issue.md \
> create_issue.log
created_issue="$(sed 's|.*/||' create_issue.log)"
echo "created_issue=$created_issue" >> $GITHUB_OUTPUT
echo "Created issue #$created_issue"
rm -f create_issue.log issue.md clang-tidy-output.txt
- name: Fail the workflow if clang-tidy failed
if: steps.run_clang_tidy.outcome != 'success'
run: |
echo "Clang-tidy check failed!"
exit 1

View File

@@ -1,55 +0,0 @@
name: Clang-tidy check
on:
workflow_call:
inputs:
check_only_changed:
description: "Check only changed files in PR. If false, checks all files in the repository."
type: boolean
default: false
create_issue_on_failure:
description: "Whether to create an issue if the check failed"
type: boolean
default: false
defaults:
run:
shell: bash
jobs:
determine-files:
name: Determine files to check
if: ${{ inputs.check_only_changed }}
runs-on: ubuntu-latest
outputs:
clang_tidy_config_changed: ${{ steps.changed_clang_tidy.outputs.any_changed }}
any_cpp_changed: ${{ steps.changed_files.outputs.any_changed }}
all_changed_files: ${{ steps.changed_files.outputs.all_changed_files }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get changed C++ files
id: changed_files
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5
with:
files: |
**/*.cpp
**/*.h
**/*.ipp
separator: " "
- name: Get changed clang-tidy configuration
id: changed_clang_tidy
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5
with:
files: |
.clang-tidy
run-clang-tidy:
needs: [determine-files]
if: ${{ always() && !cancelled() && (!inputs.check_only_changed || needs.determine-files.outputs.any_cpp_changed == 'true' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
uses: ./.github/workflows/reusable-clang-tidy-files.yml
with:
files: ${{ (needs.determine-files.outputs.clang_tidy_config_changed != 'true' && inputs.check_only_changed) && needs.determine-files.outputs.all_changed_files || '' }}
create_issue_on_failure: ${{ inputs.create_issue_on_failure }}

View File

@@ -29,10 +29,10 @@ jobs:
matrix: ${{ steps.generate.outputs.matrix }} matrix: ${{ steps.generate.outputs.matrix }}
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Set up Python - name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with: with:
python-version: 3.13 python-version: 3.13

View File

@@ -43,12 +43,16 @@ jobs:
container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13-sha-5dd7158 container: ghcr.io/xrplf/ci/ubuntu-noble:gcc-13-sha-5dd7158
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Generate build version number - name: Generate build version number
id: version id: version
uses: ./.github/actions/generate-version uses: ./.github/actions/generate-version
- name: Determine recipe reference
id: ref
run: echo "ref=xrpl/${{ steps.version.outputs.version }}" >> "${GITHUB_OUTPUT}"
- name: Set up Conan - name: Set up Conan
uses: ./.github/actions/setup-conan uses: ./.github/actions/setup-conan
with: with:
@@ -58,46 +62,17 @@ jobs:
- name: Log into Conan remote - name: Log into Conan remote
env: env:
REMOTE_NAME: ${{ inputs.remote_name }} REMOTE_NAME: ${{ inputs.remote_name }}
REMOTE_USERNAME: ${{ secrets.remote_username }} REMOTE_USERNAME: ${{ inputs.remote_username }}
REMOTE_PASSWORD: ${{ secrets.remote_password }} REMOTE_PASSWORD: ${{ inputs.remote_password }}
run: conan remote login "${REMOTE_NAME}" "${REMOTE_USERNAME}" --password "${REMOTE_PASSWORD}" run: conan remote login "${REMOTE_NAME}" "${REMOTE_USERNAME}" --password "${REMOTE_PASSWORD}"
- name: Upload Conan recipe (version) - name: Upload Conan recipe
env: env:
RECIPE_REF: ${{ steps.ref.outputs.ref }}
REMOTE_NAME: ${{ inputs.remote_name }} REMOTE_NAME: ${{ inputs.remote_name }}
run: | run: |
conan export . --version=${{ steps.version.outputs.version }} conan export .
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/${{ steps.version.outputs.version }} conan upload --confirm --check --remote="${REMOTE_NAME}" ${RECIPE_REF}
# When this workflow is triggered by a push event, it will always be when merging into the
# 'develop' branch, see on-trigger.yml.
- name: Upload Conan recipe (develop)
if: ${{ github.event_name == 'push' }}
env:
REMOTE_NAME: ${{ inputs.remote_name }}
run: |
conan export . --version=develop
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/develop
# When this workflow is triggered by a pull request event, it will always be when merging into
# one of the 'release' branches, see on-pr.yml.
- name: Upload Conan recipe (rc)
if: ${{ github.event_name == 'pull_request' }}
env:
REMOTE_NAME: ${{ inputs.remote_name }}
run: |
conan export . --version=rc
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/rc
# When this workflow is triggered by a push event, it will always be when tagging a final
# release, see on-tag.yml.
- name: Upload Conan recipe (release)
if: ${{ startsWith(github.ref, 'refs/tags/') }}
env:
REMOTE_NAME: ${{ inputs.remote_name }}
run: |
conan export . --version=release
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/release
outputs: outputs:
ref: xrpl/${{ steps.version.outputs.version }} ref: ${{ steps.ref.outputs.ref }}

View File

@@ -64,13 +64,13 @@ jobs:
steps: steps:
- name: Cleanup workspace (macOS and Windows) - name: Cleanup workspace (macOS and Windows)
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }} if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
uses: XRPLF/actions/cleanup-workspace@c7d9ce5ebb03c752a354889ecd870cadfc2b1cd4 uses: XRPLF/actions/cleanup-workspace@2ece4ec6ab7de266859a6f053571425b2bd684b6
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
- name: Prepare runner - name: Prepare runner
uses: XRPLF/actions/prepare-runner@2bbc2dc1abeec7bfaa886804ab86871ac201764e uses: XRPLF/actions/prepare-runner@f05cab7b8541eee6473aa42beb9d2fe35608a190
with: with:
enable_ccache: false enable_ccache: false
@@ -78,14 +78,12 @@ jobs:
uses: ./.github/actions/print-env uses: ./.github/actions/print-env
- name: Get number of processors - name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf uses: XRPLF/actions/get-nproc@2ece4ec6ab7de266859a6f053571425b2bd684b6
id: nproc id: nproc
with: with:
subtract: ${{ env.NPROC_SUBTRACT }} subtract: ${{ env.NPROC_SUBTRACT }}
- name: Setup Conan - name: Setup Conan
env:
SANITIZERS: ${{ matrix.sanitizers }}
uses: ./.github/actions/setup-conan uses: ./.github/actions/setup-conan
with: with:
remote_name: ${{ env.CONAN_REMOTE_NAME }} remote_name: ${{ env.CONAN_REMOTE_NAME }}
@@ -100,14 +98,13 @@ jobs:
# Set the verbosity to "quiet" for Windows to avoid an excessive # Set the verbosity to "quiet" for Windows to avoid an excessive
# amount of logs. For other OSes, the "verbose" logs are more useful. # amount of logs. For other OSes, the "verbose" logs are more useful.
log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }} log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
sanitizers: ${{ matrix.sanitizers }}
- name: Log into Conan remote - name: Log into Conan remote
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }} if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}" run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
- name: Upload Conan packages - name: Upload Conan packages
if: ${{ github.repository == 'XRPLF/rippled' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }} if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
env: env:
FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }} FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
run: conan upload "*" --remote="${CONAN_REMOTE_NAME}" --confirm ${FORCE_OPTION} run: conan upload "*" --remote="${CONAN_REMOTE_NAME}" --confirm ${FORCE_OPTION}

17
.gitignore vendored
View File

@@ -42,9 +42,6 @@ gmon.out
# Locally patched Conan recipes # Locally patched Conan recipes
external/conan-center-index/ external/conan-center-index/
# Local conan directory
.conan
# XCode IDE. # XCode IDE.
*.pbxuser *.pbxuser
!default.pbxuser !default.pbxuser
@@ -67,21 +64,7 @@ DerivedData
/.vs/ /.vs/
/.vscode/ /.vscode/
# zed IDE.
/.zed/
# AI tools. # AI tools.
/.agent
/.agents
/.augment /.augment
/.claude /.claude
/CLAUDE.md /CLAUDE.md
# Python
__pycache__
# Direnv's directory
/.direnv
# clangd cache
/.cache

View File

@@ -13,8 +13,6 @@ repos:
- 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: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # frozen: v6.0.0
hooks: hooks:
- id: check-added-large-files
args: [--maxkb=400, --enforce-all]
- id: trailing-whitespace - id: trailing-whitespace
- id: end-of-file-fixer - id: end-of-file-fixer
- id: mixed-line-ending - id: mixed-line-ending
@@ -22,33 +20,27 @@ repos:
args: [--assume-in-merge] args: [--assume-in-merge]
- 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: 7d85583be209cb547946c82fbe51f4bc5dd1d017 # frozen: v18.1.8
hooks: hooks:
- id: clang-format - id: clang-format
args: [--style=file] args: [--style=file]
"types_or": [c++, c, proto] "types_or": [c++, c, proto]
exclude: ^include/xrpl/protocol_autogen/(transactions|ledger_entries)/
- repo: https://github.com/BlankSpruce/gersemi
rev: 0.26.0
hooks:
- id: gersemi
- repo: https://github.com/rbubley/mirrors-prettier - repo: https://github.com/rbubley/mirrors-prettier
rev: c2bc67fe8f8f549cc489e00ba8b45aa18ee713b1 # frozen: v3.8.1 rev: 5ba47274f9b181bce26a5150a725577f3c336011 # frozen: v3.6.2
hooks: hooks:
- id: prettier - id: prettier
- repo: https://github.com/psf/black-pre-commit-mirror - repo: https://github.com/psf/black-pre-commit-mirror
rev: ea488cebbfd88a5f50b8bd95d5c829d0bb76feb8 # frozen: 26.1.0 rev: 831207fd435b47aeffdf6af853097e64322b4d44 # frozen: v25.12.0
hooks: hooks:
- id: black - id: black
- repo: https://github.com/streetsidesoftware/cspell-cli - repo: https://github.com/streetsidesoftware/cspell-cli
rev: a42085ade523f591dca134379a595e7859986445 # frozen: v9.7.0 rev: 1cfa010f078c354f3ffb8413616280cc28f5ba21 # frozen: v9.4.0
hooks: hooks:
- id: cspell # Spell check changed files - id: cspell # Spell check changed files
exclude: (.config/cspell.config.yaml|^include/xrpl/protocol_autogen/(transactions|ledger_entries)/) exclude: .config/cspell.config.yaml
- id: cspell # Spell check the commit message - id: cspell # Spell check the commit message
name: check commit message spelling name: check commit message spelling
args: args:
@@ -59,27 +51,8 @@ repos:
- .git/COMMIT_EDITMSG - .git/COMMIT_EDITMSG
stages: [commit-msg] stages: [commit-msg]
- repo: local
hooks:
- id: nix-fmt
name: Format Nix files
entry: |
bash -c '
if command -v nix &> /dev/null || [ "$GITHUB_ACTIONS" = "true" ]; then
nix --extra-experimental-features "nix-command flakes" fmt "$@"
else
echo "Skipping nix-fmt: nix not installed and not in GitHub Actions"
exit 0
fi
' --
language: system
types:
- nix
pass_filenames: true
exclude: | exclude: |
(?x)^( (?x)^(
external/.*| external/.*|
.github/scripts/levelization/results/.*\.txt| .github/scripts/levelization/results/.*\.txt
src/tests/libxrpl/protocol_autogen/(transactions|ledger_entries)/.*
)$ )$

View File

@@ -6,102 +6,90 @@ For info about how [API versioning](https://xrpl.org/request-formatting.html#api
The API version controls the API behavior you see. This includes what properties you see in responses, what parameters you're permitted to send in requests, and so on. You specify the API version in each of your requests. When a breaking change is introduced to the `rippled` API, a new version is released. To avoid breaking your code, you should set (or increase) your version when you're ready to upgrade. The API version controls the API behavior you see. This includes what properties you see in responses, what parameters you're permitted to send in requests, and so on. You specify the API version in each of your requests. When a breaking change is introduced to the `rippled` API, a new version is released. To avoid breaking your code, you should set (or increase) your version when you're ready to upgrade.
The [commandline](https://xrpl.org/docs/references/http-websocket-apis/api-conventions/request-formatting/#commandline-format) always uses the latest API version. The command line is intended for ad-hoc usage by humans, not programs or automated scripts. The command line is not meant for use in production code.
For a log of breaking changes, see the **API Version [number]** headings. In general, breaking changes are associated with a particular API Version number. For non-breaking changes, scroll to the **XRP Ledger version [x.y.z]** headings. Non-breaking changes are associated with a particular XRP Ledger (`rippled`) release. For a log of breaking changes, see the **API Version [number]** headings. In general, breaking changes are associated with a particular API Version number. For non-breaking changes, scroll to the **XRP Ledger version [x.y.z]** headings. Non-breaking changes are associated with a particular XRP Ledger (`rippled`) release.
## API Version 3 (Beta)
API version 3 is currently a beta API. It requires enabling `[beta_rpc_api]` in the rippled configuration to use. See [API-VERSION-3.md](API-VERSION-3.md) for the full list of changes in API version 3.
## API Version 2 ## API Version 2
API version 2 is available in `rippled` version 2.0.0 and later. See [API-VERSION-2.md](API-VERSION-2.md) for the full list of changes in API version 2. API version 2 is available in `rippled` version 2.0.0 and later. To use this API, clients specify `"api_version" : 2` in each request.
#### Removed methods
In API version 2, the following deprecated methods are no longer available: (https://github.com/XRPLF/rippled/pull/4759)
- `tx_history` - Instead, use other methods such as `account_tx` or `ledger` with the `transactions` field set to `true`.
- `ledger_header` - Instead, use the `ledger` method.
#### Modifications to JSON transaction element in V2
In API version 2, JSON elements for transaction output have been changed and made consistent for all methods which output transactions. (https://github.com/XRPLF/rippled/pull/4775)
This helps to unify the JSON serialization format of transactions. (https://github.com/XRPLF/clio/issues/722, https://github.com/XRPLF/rippled/issues/4727)
- JSON transaction element is named `tx_json`
- Binary transaction element is named `tx_blob`
- JSON transaction metadata element is named `meta`
- Binary transaction metadata element is named `meta_blob`
Additionally, these elements are now consistently available next to `tx_json` (i.e. sibling elements), where possible:
- `hash` - Transaction ID. This data was stored inside transaction output in API version 1, but in API version 2 is a sibling element.
- `ledger_index` - Ledger index (only set on validated ledgers)
- `ledger_hash` - Ledger hash (only set on closed or validated ledgers)
- `close_time_iso` - Ledger close time expressed in ISO 8601 time format (only set on validated ledgers)
- `validated` - Bool element set to `true` if the transaction is in a validated ledger, otherwise `false`
This change affects the following methods:
- `tx` - Transaction data moved into element `tx_json` (was inline inside `result`) or, if binary output was requested, moved from `tx` to `tx_blob`. Renamed binary transaction metadata element (if it was requested) from `meta` to `meta_blob`. Changed location of `hash` and added new elements
- `account_tx` - Renamed transaction element from `tx` to `tx_json`. Renamed binary transaction metadata element (if it was requested) from `meta` to `meta_blob`. Changed location of `hash` and added new elements
- `transaction_entry` - Renamed transaction metadata element from `metadata` to `meta`. Changed location of `hash` and added new elements
- `subscribe` - Renamed transaction element from `transaction` to `tx_json`. Changed location of `hash` and added new elements
- `sign`, `sign_for`, `submit` and `submit_multisigned` - Changed location of `hash` element.
#### Modification to `Payment` transaction JSON schema
When reading Payments, the `Amount` field should generally **not** be used. Instead, use [delivered_amount](https://xrpl.org/partial-payments.html#the-delivered_amount-field) to see the amount that the Payment delivered. To clarify its meaning, the `Amount` field is being renamed to `DeliverMax`. (https://github.com/XRPLF/rippled/pull/4733)
- In `Payment` transaction type, JSON RPC field `Amount` is renamed to `DeliverMax`. To enable smooth client transition, `Amount` is still handled, as described below: (https://github.com/XRPLF/rippled/pull/4733)
- On JSON RPC input (e.g. `submit_multisigned` etc. methods), `Amount` is recognized as an alias to `DeliverMax` for both API version 1 and version 2 clients.
- On JSON RPC input, submitting both `Amount` and `DeliverMax` fields is allowed _only_ if they are identical; otherwise such input is rejected with `rpcINVALID_PARAMS` error.
- On JSON RPC output (e.g. `subscribe`, `account_tx` etc. methods), `DeliverMax` is present in both API version 1 and version 2.
- On JSON RPC output, `Amount` is only present in API version 1 and _not_ in version 2.
#### Modifications to account_info response
- `signer_lists` is returned in the root of the response. (In API version 1, it was nested under `account_data`.) (https://github.com/XRPLF/rippled/pull/3770)
- When using an invalid `signer_lists` value, the API now returns an "invalidParams" error. (https://github.com/XRPLF/rippled/pull/4585)
- (`signer_lists` must be a boolean. In API version 1, strings were accepted and may return a normal response - i.e. as if `signer_lists` were `true`.)
#### Modifications to [account_tx](https://xrpl.org/account_tx.html#account_tx) response
- Using `ledger_index_min`, `ledger_index_max`, and `ledger_index` returns `invalidParams` because if you use `ledger_index_min` or `ledger_index_max`, then it does not make sense to also specify `ledger_index`. In API version 1, no error was returned. (https://github.com/XRPLF/rippled/pull/4571)
- The same applies for `ledger_index_min`, `ledger_index_max`, and `ledger_hash`. (https://github.com/XRPLF/rippled/issues/4545#issuecomment-1565065579)
- Using a `ledger_index_min` or `ledger_index_max` beyond the range of ledgers that the server has:
- returns `lgrIdxMalformed` in API version 2. Previously, in API version 1, no error was returned. (https://github.com/XRPLF/rippled/issues/4288)
- Attempting to use a non-boolean value (such as a string) for the `binary` or `forward` parameters returns `invalidParams` (`rpcINVALID_PARAMS`). Previously, in API version 1, no error was returned. (https://github.com/XRPLF/rippled/pull/4620)
#### Modifications to [noripple_check](https://xrpl.org/noripple_check.html#noripple_check) response
- Attempting to use a non-boolean value (such as a string) for the `transactions` parameter returns `invalidParams` (`rpcINVALID_PARAMS`). Previously, in API version 1, no error was returned. (https://github.com/XRPLF/rippled/pull/4620)
## API Version 1 ## API Version 1
This version is supported by all `rippled` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified. This version is supported by all `rippled` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
## Unreleased The [commandline](https://xrpl.org/docs/references/http-websocket-apis/api-conventions/request-formatting/#commandline-format) always uses the latest API version. The command line is intended for ad-hoc usage by humans, not programs or automated scripts. The command line is not meant for use in production code.
This section contains changes targeting a future version. ### Inconsistency: server_info - network_id
### Additions The `network_id` field was added in the `server_info` response in version 1.5.0 (2019), but it is not returned in [reporting mode](https://xrpl.org/rippled-server-modes.html#reporting-mode). However, use of reporting mode is now discouraged, in favor of using [Clio](https://github.com/XRPLF/clio) instead.
- `server_definitions`: Added the following new sections to the response ([#6321](https://github.com/XRPLF/rippled/pull/6321)):
- `TRANSACTION_FORMATS`: Describes the fields and their optionality for each transaction type, including common fields shared across all transactions.
- `LEDGER_ENTRY_FORMATS`: Describes the fields and their optionality for each ledger entry type, including common fields shared across all ledger entries.
- `TRANSACTION_FLAGS`: Maps transaction type names to their supported flags and flag values.
- `LEDGER_ENTRY_FLAGS`: Maps ledger entry type names to their flags and flag values.
- `ACCOUNT_SET_FLAGS`: Maps AccountSet flag names (asf flags) to their numeric values.
### Bugfixes
- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers. [#6318](https://github.com/XRPLF/rippled/pull/6318)
## XRP Ledger server version 3.1.0
[Version 3.1.0](https://github.com/XRPLF/rippled/releases/tag/3.1.0) was released on Jan 27, 2026.
### Additions in 3.1.0
- `vault_info`: New RPC method to retrieve information about a specific vault (part of XLS-66 Lending Protocol). ([#6156](https://github.com/XRPLF/rippled/pull/6156))
## XRP Ledger server version 3.0.0
[Version 3.0.0](https://github.com/XRPLF/rippled/releases/tag/3.0.0) was released on Dec 9, 2025.
### Additions in 3.0.0
- `ledger_entry`: Supports all ledger entry types with dedicated parsers. ([#5237](https://github.com/XRPLF/rippled/pull/5237))
- `ledger_entry`: New error codes `entryNotFound` and `unexpectedLedgerType` for more specific error handling. ([#5237](https://github.com/XRPLF/rippled/pull/5237))
- `ledger_entry`: Improved error messages with more context (e.g., specifying which field is invalid or missing). ([#5237](https://github.com/XRPLF/rippled/pull/5237))
- `ledger_entry`: Assorted bug fixes in RPC processing. ([#5237](https://github.com/XRPLF/rippled/pull/5237))
- `simulate`: Supports additional metadata in the response. ([#5754](https://github.com/XRPLF/rippled/pull/5754))
## XRP Ledger server version 2.6.2
[Version 2.6.2](https://github.com/XRPLF/rippled/releases/tag/2.6.2) was released on Nov 19, 2025.
This release contains bug fixes only and no API changes.
## XRP Ledger server version 2.6.1
[Version 2.6.1](https://github.com/XRPLF/rippled/releases/tag/2.6.1) was released on Sep 30, 2025.
This release contains bug fixes only and no API changes.
## XRP Ledger server version 2.6.0
[Version 2.6.0](https://github.com/XRPLF/rippled/releases/tag/2.6.0) was released on Aug 27, 2025.
### Additions in 2.6.0
- `account_info`: Added `allowTrustLineLocking` flag in response. ([#5525](https://github.com/XRPLF/rippled/pull/5525))
- `ledger`: Removed the type filter from the RPC command. ([#4934](https://github.com/XRPLF/rippled/pull/4934))
- `subscribe` (`validations` stream): `network_id` is now included. ([#5579](https://github.com/XRPLF/rippled/pull/5579))
- `subscribe` (`transactions` stream): `nftoken_id`, `nftoken_ids`, and `offer_id` are now included in transaction metadata. ([#5230](https://github.com/XRPLF/rippled/pull/5230))
## XRP Ledger server version 2.5.1
[Version 2.5.1](https://github.com/XRPLF/rippled/releases/tag/2.5.1) was released on Sep 17, 2025.
This release contains bug fixes only and no API changes.
## XRP Ledger server version 2.5.0 ## XRP Ledger server version 2.5.0
[Version 2.5.0](https://github.com/XRPLF/rippled/releases/tag/2.5.0) was released on Jun 24, 2025. As of 2025-04-04, version 2.5.0 is in development. You can use a pre-release version by building from source or [using the `nightly` package](https://xrpl.org/docs/infrastructure/installation/install-rippled-on-ubuntu).
### Additions and bugfixes in 2.5.0 ### Additions and bugfixes in 2.5.0
- `tx`: Added `ctid` field to the response and improved error handling. ([#4738](https://github.com/XRPLF/rippled/pull/4738)) - `channel_authorize`: If `signing_support` is not enabled in the config, the RPC is disabled.
- `ledger_entry`: Improved error messages in `permissioned_domain`. ([#5344](https://github.com/XRPLF/rippled/pull/5344))
- `simulate`: Improved multi-sign usage. ([#5479](https://github.com/XRPLF/rippled/pull/5479))
- `channel_authorize`: If `signing_support` is not enabled in the config, the RPC is disabled. ([#5385](https://github.com/XRPLF/rippled/pull/5385))
- `subscribe` (admin): Removed webhook queue limit to prevent dropping notifications; reduced HTTP timeout from 10 minutes to 30 seconds. ([#5163](https://github.com/XRPLF/rippled/pull/5163))
- `ledger_data` (gRPC): Fixed crashing issue with some invalid markers. ([#5137](https://github.com/XRPLF/rippled/pull/5137))
- `account_lines`: Fixed error with `no_ripple` and `no_ripple_peer` sometimes showing up incorrectly. ([#5345](https://github.com/XRPLF/rippled/pull/5345))
- `account_tx`: Fixed issue with incorrect CTIDs. ([#5408](https://github.com/XRPLF/rippled/pull/5408))
## XRP Ledger server version 2.4.0 ## XRP Ledger server version 2.4.0
@@ -109,19 +97,11 @@ This release contains bug fixes only and no API changes.
### Additions and bugfixes in 2.4.0 ### Additions and bugfixes in 2.4.0
- `simulate`: A new RPC that executes a [dry run of a transaction submission](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0069d-simulate#2-rpc-simulate). ([#5069](https://github.com/XRPLF/rippled/pull/5069)) - `ledger_entry`: `state` is added an alias for `ripple_state`.
- Signing methods (`sign`, `sign_for`, `submit`): Autofill fees better, properly handle transactions without a base fee, and autofill the `NetworkID` field. ([#5069](https://github.com/XRPLF/rippled/pull/5069)) - `ledger_entry`: Enables case-insensitive filtering by canonical name in addition to case-sensitive filtering by RPC name.
- `ledger_entry`: `state` is added as an alias for `ripple_state`. ([#5199](https://github.com/XRPLF/rippled/pull/5199)) - `validators`: Added new field `validator_list_threshold` in response.
- `ledger`, `ledger_data`, `account_objects`: Support filtering ledger entry types by their canonical names (case-insensitive). ([#5271](https://github.com/XRPLF/rippled/pull/5271)) - `simulate`: A new RPC that executes a [dry run of a transaction submission](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0069d-simulate#2-rpc-simulate)
- `validators`: Added new field `validator_list_threshold` in response. ([#5112](https://github.com/XRPLF/rippled/pull/5112)) - Signing methods autofill fees better and properly handle transactions that don't have a base fee, and will also autofill the `NetworkID` field.
- `server_info`: Added git commit hash info on admin connection. ([#5225](https://github.com/XRPLF/rippled/pull/5225))
- `server_definitions`: Changed larger `UInt` serialized types to `Hash`. ([#5231](https://github.com/XRPLF/rippled/pull/5231))
## XRP Ledger server version 2.3.1
[Version 2.3.1](https://github.com/XRPLF/rippled/releases/tag/2.3.1) was released on Jan 29, 2025.
This release contains bug fixes only and no API changes.
## XRP Ledger server version 2.3.0 ## XRP Ledger server version 2.3.0
@@ -129,30 +109,19 @@ This release contains bug fixes only and no API changes.
### Breaking changes in 2.3.0 ### Breaking changes in 2.3.0
- `book_changes`: If the requested ledger version is not available on this node, a `ledgerNotFound` error is returned and the node does not attempt to acquire the ledger from the p2p network (as with other non-admin RPCs). Admins can still attempt to retrieve old ledgers with the `ledger_request` RPC. - `book_changes`: If the requested ledger version is not available on this node, a `ledgerNotFound` error is returned and the node does not attempt to acquire the ledger from the p2p network (as with other non-admin RPCs).
Admins can still attempt to retrieve old ledgers with the `ledger_request` RPC.
### Additions and bugfixes in 2.3.0 ### Additions and bugfixes in 2.3.0
- `book_changes`: Returns a `validated` field in its response. ([#5096](https://github.com/XRPLF/rippled/pull/5096)) - `book_changes`: Returns a `validated` field in its response, which was missing in prior versions.
- `book_changes`: Accepts shortcut strings (`current`, `closed`, `validated`) for the `ledger_index` parameter. ([#5096](https://github.com/XRPLF/rippled/pull/5096))
- `server_definitions`: Include `index` in response. ([#5190](https://github.com/XRPLF/rippled/pull/5190))
- `account_nfts`: Fix issue where unassociated marker would return incorrect results. ([#5045](https://github.com/XRPLF/rippled/pull/5045))
- `account_objects`: Fix issue where invalid marker would not return an error. ([#5046](https://github.com/XRPLF/rippled/pull/5046))
- `account_objects`: Disallow filtering by ledger entry types that an account cannot hold. ([#5056](https://github.com/XRPLF/rippled/pull/5056))
- `tx`: Allow lowercase CTID. ([#5049](https://github.com/XRPLF/rippled/pull/5049))
- `feature`: Better error handling for invalid values of `feature`. ([#5063](https://github.com/XRPLF/rippled/pull/5063))
## XRP Ledger server version 2.2.0 ## XRP Ledger server version 2.2.0
[Version 2.2.0](https://github.com/XRPLF/rippled/releases/tag/2.2.0) was released on Jun 5, 2024. The following additions are non-breaking (because they are purely additive): [Version 2.2.0](https://github.com/XRPLF/rippled/releases/tag/2.2.0) was released on Jun 5, 2024. The following additions are non-breaking (because they are purely additive):
- `feature`: Add a non-admin mode for users. (It was previously only available to admin connections.) The method returns an updated list of amendments, including their names and other information. ([#4781](https://github.com/XRPLF/rippled/pull/4781)) - The `feature` method now has a non-admin mode for users. (It was previously only available to admin connections.) The method returns an updated list of amendments, including their names and other information. ([#4781](https://github.com/XRPLF/rippled/pull/4781))
## XRP Ledger server version 2.0.1
[Version 2.0.1](https://github.com/XRPLF/rippled/releases/tag/2.0.1) was released on Jan 29, 2024. The following additions are non-breaking:
- `path_find`: Fixes unbounded memory growth. ([#4822](https://github.com/XRPLF/rippled/pull/4822))
## XRP Ledger server version 2.0.0 ## XRP Ledger server version 2.0.0
@@ -160,18 +129,24 @@ This release contains bug fixes only and no API changes.
- `server_definitions`: A new RPC that generates a `definitions.json`-like output that can be used in XRPL libraries. - `server_definitions`: A new RPC that generates a `definitions.json`-like output that can be used in XRPL libraries.
- In `Payment` transactions, `DeliverMax` has been added. This is a replacement for the `Amount` field, which should not be used. Typically, the `delivered_amount` (in transaction metadata) should be used. To ease the transition, `DeliverMax` is present regardless of API version, since adding a field is non-breaking. - In `Payment` transactions, `DeliverMax` has been added. This is a replacement for the `Amount` field, which should not be used. Typically, the `delivered_amount` (in transaction metadata) should be used. To ease the transition, `DeliverMax` is present regardless of API version, since adding a field is non-breaking.
- API version 2 has been moved from beta to supported, meaning that it is generally available (regardless of the `beta_rpc_api` setting). The full list of changes is in [API-VERSION-2.md](API-VERSION-2.md). - API version 2 has been moved from beta to supported, meaning that it is generally available (regardless of the `beta_rpc_api` setting).
## XRP Ledger server version 2.2.0
The following is a non-breaking addition to the API.
- The `feature` method now has a non-admin mode for users. (It was previously only available to admin connections.) The method returns an updated list of amendments, including their names and other information. ([#4781](https://github.com/XRPLF/rippled/pull/4781))
## XRP Ledger server version 1.12.0 ## XRP Ledger server version 1.12.0
[Version 1.12.0](https://github.com/XRPLF/rippled/releases/tag/1.12.0) was released on Sep 6, 2023. The following additions are non-breaking (because they are purely additive): [Version 1.12.0](https://github.com/XRPLF/rippled/releases/tag/1.12.0) was released on Sep 6, 2023. The following additions are non-breaking (because they are purely additive).
- `server_info`: Added `ports`, an array which advertises the RPC and WebSocket ports. This information is also included in the `/crawl` endpoint (which calls `server_info` internally). `grpc` and `peer` ports are also included. ([#4427](https://github.com/XRPLF/rippled/pull/4427)) - `server_info`: Added `ports`, an array which advertises the RPC and WebSocket ports. This information is also included in the `/crawl` endpoint (which calls `server_info` internally). `grpc` and `peer` ports are also included. (https://github.com/XRPLF/rippled/pull/4427)
- `ports` contains objects, each containing a `port` for the listening port (a number string), and a `protocol` array listing the supported protocols on that port. - `ports` contains objects, each containing a `port` for the listening port (a number string), and a `protocol` array listing the supported protocols on that port.
- This allows crawlers to build a more detailed topology without needing to port-scan nodes. - This allows crawlers to build a more detailed topology without needing to port-scan nodes.
- (For peers and other non-admin clients, the info about admin ports is excluded.) - (For peers and other non-admin clients, the info about admin ports is excluded.)
- Clawback: The following additions are gated by the Clawback amendment (`featureClawback`). ([#4553](https://github.com/XRPLF/rippled/pull/4553)) - Clawback: The following additions are gated by the Clawback amendment (`featureClawback`). (https://github.com/XRPLF/rippled/pull/4553)
- Adds an [AccountRoot flag](https://xrpl.org/accountroot.html#accountroot-flags) called `lsfAllowTrustLineClawback`. ([#4617](https://github.com/XRPLF/rippled/pull/4617)) - Adds an [AccountRoot flag](https://xrpl.org/accountroot.html#accountroot-flags) called `lsfAllowTrustLineClawback` (https://github.com/XRPLF/rippled/pull/4617)
- Adds the corresponding `asfAllowTrustLineClawback` [AccountSet Flag](https://xrpl.org/accountset.html#accountset-flags) as well. - Adds the corresponding `asfAllowTrustLineClawback` [AccountSet Flag](https://xrpl.org/accountset.html#accountset-flags) as well.
- Clawback is disabled by default, so if an issuer desires the ability to claw back funds, they must use an `AccountSet` transaction to set the AllowTrustLineClawback flag. They must do this before creating any trust lines, offers, escrows, payment channels, or checks. - Clawback is disabled by default, so if an issuer desires the ability to claw back funds, they must use an `AccountSet` transaction to set the AllowTrustLineClawback flag. They must do this before creating any trust lines, offers, escrows, payment channels, or checks.
- Adds the [Clawback transaction type](https://github.com/XRPLF/XRPL-Standards/blob/master/XLS-39d-clawback/README.md#331-clawback-transaction), containing these fields: - Adds the [Clawback transaction type](https://github.com/XRPLF/XRPL-Standards/blob/master/XLS-39d-clawback/README.md#331-clawback-transaction), containing these fields:
@@ -206,16 +181,16 @@ This release contains bug fixes only and no API changes.
### Breaking changes in 1.11 ### Breaking changes in 1.11
- Added the ability to mark amendments as obsolete. For the `feature` admin API, there is a new possible value for the `vetoed` field. ([#4291](https://github.com/XRPLF/rippled/pull/4291)) - Added the ability to mark amendments as obsolete. For the `feature` admin API, there is a new possible value for the `vetoed` field. (https://github.com/XRPLF/rippled/pull/4291)
- The value of `vetoed` can now be `true`, `false`, or `"Obsolete"`. - The value of `vetoed` can now be `true`, `false`, or `"Obsolete"`.
- Removed the acceptance of seeds or public keys in place of account addresses. ([#4404](https://github.com/XRPLF/rippled/pull/4404)) - Removed the acceptance of seeds or public keys in place of account addresses. (https://github.com/XRPLF/rippled/pull/4404)
- This simplifies the API and encourages better security practices (i.e. seeds should never be sent over the network). - This simplifies the API and encourages better security practices (i.e. seeds should never be sent over the network).
- For the `ledger_data` method, when all entries are filtered out, the `state` field of the response is now an empty list (in other words, an empty array, `[]`). (Previously, it would return `null`.) While this is technically a breaking change, the new behavior is consistent with the documentation, so this is considered only a bug fix. ([#4398](https://github.com/XRPLF/rippled/pull/4398)) - For the `ledger_data` method, when all entries are filtered out, the `state` field of the response is now an empty list (in other words, an empty array, `[]`). (Previously, it would return `null`.) While this is technically a breaking change, the new behavior is consistent with the documentation, so this is considered only a bug fix. (https://github.com/XRPLF/rippled/pull/4398)
- If and when the `fixNFTokenRemint` amendment activates, there will be a new AccountRoot field, `FirstNFTSequence`. This field is set to the current account sequence when the account issues their first NFT. If an account has not issued any NFTs, then the field is not set. ([#4406](https://github.com/XRPLF/rippled/pull/4406)) - If and when the `fixNFTokenRemint` amendment activates, there will be a new AccountRoot field, `FirstNFTSequence`. This field is set to the current account sequence when the account issues their first NFT. If an account has not issued any NFTs, then the field is not set. ([#4406](https://github.com/XRPLF/rippled/pull/4406))
- There is a new account deletion restriction: an account can only be deleted if `FirstNFTSequence` + `MintedNFTokens` + `256` is less than the current ledger sequence. - There is a new account deletion restriction: an account can only be deleted if `FirstNFTSequence` + `MintedNFTokens` + `256` is less than the current ledger sequence.
- This is potentially a breaking change if clients have logic for determining whether an account can be deleted. - This is potentially a breaking change if clients have logic for determining whether an account can be deleted.
- NetworkID - NetworkID
- For sidechains and networks with a network ID greater than 1024, there is a new [transaction common field](https://xrpl.org/transaction-common-fields.html), `NetworkID`. ([#4370](https://github.com/XRPLF/rippled/pull/4370)) - For sidechains and networks with a network ID greater than 1024, there is a new [transaction common field](https://xrpl.org/transaction-common-fields.html), `NetworkID`. (https://github.com/XRPLF/rippled/pull/4370)
- This field helps to prevent replay attacks and is now required for chains whose network ID is 1025 or higher. - This field helps to prevent replay attacks and is now required for chains whose network ID is 1025 or higher.
- The field must be omitted for Mainnet, so there is no change for Mainnet users. - The field must be omitted for Mainnet, so there is no change for Mainnet users.
- There are three new local error codes: - There are three new local error codes:
@@ -225,10 +200,10 @@ This release contains bug fixes only and no API changes.
### Additions and bug fixes in 1.11 ### Additions and bug fixes in 1.11
- Added `nftoken_id`, `nftoken_ids` and `offer_id` meta fields into NFT `tx` and `account_tx` responses. ([#4447](https://github.com/XRPLF/rippled/pull/4447)) - Added `nftoken_id`, `nftoken_ids` and `offer_id` meta fields into NFT `tx` and `account_tx` responses. (https://github.com/XRPLF/rippled/pull/4447)
- Added an `account_flags` object to the `account_info` method response. ([#4459](https://github.com/XRPLF/rippled/pull/4459)) - Added an `account_flags` object to the `account_info` method response. (https://github.com/XRPLF/rippled/pull/4459)
- Added `NFTokenPages` to the `account_objects` RPC. ([#4352](https://github.com/XRPLF/rippled/pull/4352)) - Added `NFTokenPages` to the `account_objects` RPC. (https://github.com/XRPLF/rippled/pull/4352)
- Fixed: `marker` returned from the `account_lines` command would not work on subsequent commands. ([#4361](https://github.com/XRPLF/rippled/pull/4361)) - Fixed: `marker` returned from the `account_lines` command would not work on subsequent commands. (https://github.com/XRPLF/rippled/pull/4361)
## XRP Ledger server version 1.10.0 ## XRP Ledger server version 1.10.0

View File

@@ -1,66 +0,0 @@
# API Version 2
API version 2 is available in `rippled` version 2.0.0 and later. To use this API, clients specify `"api_version" : 2` in each request.
For info about how [API versioning](https://xrpl.org/request-formatting.html#api-versioning) works, including examples, please view the [XLS-22d spec](https://github.com/XRPLF/XRPL-Standards/discussions/54). For details about the implementation of API versioning, view the [implementation PR](https://github.com/XRPLF/rippled/pull/3155). API versioning ensures existing integrations and users continue to receive existing behavior, while those that request a higher API version will experience new behavior.
## Removed methods
In API version 2, the following deprecated methods are no longer available: ([#4759](https://github.com/XRPLF/rippled/pull/4759))
- `tx_history` - Instead, use other methods such as `account_tx` or `ledger` with the `transactions` field set to `true`.
- `ledger_header` - Instead, use the `ledger` method.
## Modifications to JSON transaction element in API version 2
In API version 2, JSON elements for transaction output have been changed and made consistent for all methods which output transactions. ([#4775](https://github.com/XRPLF/rippled/pull/4775))
This helps to unify the JSON serialization format of transactions. ([clio#722](https://github.com/XRPLF/clio/issues/722), [#4727](https://github.com/XRPLF/rippled/issues/4727))
- JSON transaction element is named `tx_json`
- Binary transaction element is named `tx_blob`
- JSON transaction metadata element is named `meta`
- Binary transaction metadata element is named `meta_blob`
Additionally, these elements are now consistently available next to `tx_json` (i.e. sibling elements), where possible:
- `hash` - Transaction ID. This data was stored inside transaction output in API version 1, but in API version 2 is a sibling element.
- `ledger_index` - Ledger index (only set on validated ledgers)
- `ledger_hash` - Ledger hash (only set on closed or validated ledgers)
- `close_time_iso` - Ledger close time expressed in ISO 8601 time format (only set on validated ledgers)
- `validated` - Bool element set to `true` if the transaction is in a validated ledger, otherwise `false`
This change affects the following methods:
- `tx` - Transaction data moved into element `tx_json` (was inline inside `result`) or, if binary output was requested, moved from `tx` to `tx_blob`. Renamed binary transaction metadata element (if it was requested) from `meta` to `meta_blob`. Changed location of `hash` and added new elements
- `account_tx` - Renamed transaction element from `tx` to `tx_json`. Renamed binary transaction metadata element (if it was requested) from `meta` to `meta_blob`. Changed location of `hash` and added new elements
- `transaction_entry` - Renamed transaction metadata element from `metadata` to `meta`. Changed location of `hash` and added new elements
- `subscribe` - Renamed transaction element from `transaction` to `tx_json`. Changed location of `hash` and added new elements
- `sign`, `sign_for`, `submit` and `submit_multisigned` - Changed location of `hash` element.
## Modifications to `Payment` transaction JSON schema
When reading Payments, the `Amount` field should generally **not** be used. Instead, use [delivered_amount](https://xrpl.org/partial-payments.html#the-delivered_amount-field) to see the amount that the Payment delivered. To clarify its meaning, the `Amount` field is being renamed to `DeliverMax`. ([#4733](https://github.com/XRPLF/rippled/pull/4733))
- In `Payment` transaction type, JSON RPC field `Amount` is renamed to `DeliverMax`. To enable smooth client transition, `Amount` is still handled, as described below: ([#4733](https://github.com/XRPLF/rippled/pull/4733))
- On JSON RPC input (e.g. `submit_multisigned` etc. methods), `Amount` is recognized as an alias to `DeliverMax` for both API version 1 and version 2 clients.
- On JSON RPC input, submitting both `Amount` and `DeliverMax` fields is allowed _only_ if they are identical; otherwise such input is rejected with `rpcINVALID_PARAMS` error.
- On JSON RPC output (e.g. `subscribe`, `account_tx` etc. methods), `DeliverMax` is present in both API version 1 and version 2.
- On JSON RPC output, `Amount` is only present in API version 1 and _not_ in version 2.
## Modifications to account_info response
- `signer_lists` is returned in the root of the response. (In API version 1, it was nested under `account_data`.) ([#3770](https://github.com/XRPLF/rippled/pull/3770))
- When using an invalid `signer_lists` value, the API now returns an "invalidParams" error. ([#4585](https://github.com/XRPLF/rippled/pull/4585))
- (`signer_lists` must be a boolean. In API version 1, strings were accepted and may return a normal response - i.e. as if `signer_lists` were `true`.)
## Modifications to [account_tx](https://xrpl.org/account_tx.html#account_tx) response
- Using `ledger_index_min`, `ledger_index_max`, and `ledger_index` returns `invalidParams` because if you use `ledger_index_min` or `ledger_index_max`, then it does not make sense to also specify `ledger_index`. In API version 1, no error was returned. ([#4571](https://github.com/XRPLF/rippled/pull/4571))
- The same applies for `ledger_index_min`, `ledger_index_max`, and `ledger_hash`. ([#4545](https://github.com/XRPLF/rippled/issues/4545#issuecomment-1565065579))
- Using a `ledger_index_min` or `ledger_index_max` beyond the range of ledgers that the server has:
- returns `lgrIdxMalformed` in API version 2. Previously, in API version 1, no error was returned. ([#4288](https://github.com/XRPLF/rippled/issues/4288))
- Attempting to use a non-boolean value (such as a string) for the `binary` or `forward` parameters returns `invalidParams` (`rpcINVALID_PARAMS`). Previously, in API version 1, no error was returned. ([#4620](https://github.com/XRPLF/rippled/pull/4620))
## Modifications to [noripple_check](https://xrpl.org/noripple_check.html#noripple_check) response
- Attempting to use a non-boolean value (such as a string) for the `transactions` parameter returns `invalidParams` (`rpcINVALID_PARAMS`). Previously, in API version 1, no error was returned. ([#4620](https://github.com/XRPLF/rippled/pull/4620))

View File

@@ -1,27 +0,0 @@
# API Version 3
API version 3 is currently a **beta API**. It requires enabling `[beta_rpc_api]` in the rippled configuration to use. To use this API, clients specify `"api_version" : 3` in each request.
For info about how [API versioning](https://xrpl.org/request-formatting.html#api-versioning) works, including examples, please view the [XLS-22d spec](https://github.com/XRPLF/XRPL-Standards/discussions/54). For details about the implementation of API versioning, view the [implementation PR](https://github.com/XRPLF/rippled/pull/3155). API versioning ensures existing integrations and users continue to receive existing behavior, while those that request a higher API version will experience new behavior.
## Breaking Changes
### Modifications to `amm_info`
The order of error checks has been changed to provide more specific error messages. ([#4924](https://github.com/XRPLF/rippled/pull/4924))
- **Before (API v2)**: When sending an invalid account or asset to `amm_info` while other parameters are not set as expected, the method returns a generic `rpcINVALID_PARAMS` error.
- **After (API v3)**: The same scenario returns a more specific error: `rpcISSUE_MALFORMED` for malformed assets or `rpcACT_MALFORMED` for malformed accounts.
### Modifications to `ledger_entry`
Added support for string shortcuts to look up fixed-location ledger entries using the `"index"` parameter. ([#5644](https://github.com/XRPLF/rippled/pull/5644))
In API version 3, the following string values can be used with the `"index"` parameter:
- `"index": "amendments"` - Returns the `Amendments` ledger entry
- `"index": "fee"` - Returns the `FeeSettings` ledger entry
- `"index": "nunl"` - Returns the `NegativeUNL` ledger entry
- `"index": "hashes"` - Returns the "short" `LedgerHashes` ledger entry (recent ledger hashes)
These shortcuts are only available in API version 3 and later. In API versions 1 and 2, these string values would result in an error.

115
BUILD.md
View File

@@ -125,9 +125,9 @@ default profile.
### Patched recipes ### Patched recipes
Occasionally, we need patched recipes or recipes not present in Conan Center. The recipes in Conan Center occasionally need to be patched for compatibility
We maintain a fork of the Conan Center Index with the latest version of `xrpld`. We maintain a fork of the Conan Center
[here](https://github.com/XRPLF/conan-center-index/) containing the modified and newly added recipes. [here](https://github.com/XRPLF/conan-center-index/) containing the patches.
To ensure our patched recipes are used, you must add our Conan remote at a To ensure our patched recipes are used, you must add our Conan remote at a
higher index than the default Conan Center remote, so it is consulted first. You higher index than the default Conan Center remote, so it is consulted first. You
@@ -137,11 +137,19 @@ can do this by running:
conan remote add --index 0 xrplf https://conan.ripplex.io conan remote add --index 0 xrplf https://conan.ripplex.io
``` ```
Alternatively, you can pull our recipes from the repository and export them locally: Alternatively, you can pull the patched recipes into the repository and use them
locally:
```bash ```bash
# Extract the version number from the lockfile.
function extract_version {
version=$(cat conan.lock | sed -nE "s@.+${1}/(.+)#.+@\1@p" | head -n1)
echo ${version}
}
# Define which recipes to export. # Define which recipes to export.
recipes=('abseil' 'ed25519' 'grpc' 'm4' 'mpt-crypto' 'openssl' 'secp256k1' 'snappy' 'soci' 'wasm-xrplf' 'wasmi') recipes=('ed25519' 'grpc' 'openssl' 'secp256k1' 'snappy' 'soci')
folders=('all' 'all' '3.x.x' 'all' 'all' 'all')
# Selectively check out the recipes from our CCI fork. # Selectively check out the recipes from our CCI fork.
cd external cd external
@@ -150,19 +158,29 @@ cd conan-center-index
git init git init
git remote add origin git@github.com:XRPLF/conan-center-index.git git remote add origin git@github.com:XRPLF/conan-center-index.git
git sparse-checkout init git sparse-checkout init
for recipe in "${recipes[@]}"; do for ((index = 1; index <= ${#recipes[@]}; index++)); do
echo "Checking out recipe '${recipe}'..." recipe=${recipes[index]}
git sparse-checkout add recipes/${recipe} folder=${folders[index]}
echo "Checking out recipe '${recipe}' from folder '${folder}'..."
git sparse-checkout add recipes/${recipe}/${folder}
done done
git fetch origin master git fetch origin master
git checkout master git checkout master
cd ../..
./export_all.sh # Export the recipes into the local cache.
cd ../../ for ((index = 1; index <= ${#recipes[@]}; index++)); do
recipe=${recipes[index]}
folder=${folders[index]}
version=$(extract_version ${recipe})
echo "Exporting '${recipe}/${version}' from '${recipe}/${folder}'..."
conan export --version $(extract_version ${recipe}) \
external/conan-center-index/recipes/${recipe}/${folder}
done
``` ```
In the case we switch to a newer version of a dependency that still requires a In the case we switch to a newer version of a dependency that still requires a
patch or add a new dependency, it will be necessary for you to pull in the changes and re-export the patch, it will be necessary for you to pull in the changes and re-export the
updated dependencies with the newer version. However, if we switch to a newer updated dependencies with the newer version. However, if we switch to a newer
version that no longer requires a patch, no action is required on your part, as version that no longer requires a patch, no action is required on your part, as
the new recipe will be automatically pulled from the official Conan Center. the new recipe will be automatically pulled from the official Conan Center.
@@ -171,8 +189,6 @@ the new recipe will be automatically pulled from the official Conan Center.
> You might need to add `--lockfile=""` to your `conan install` command > You might need to add `--lockfile=""` to your `conan install` command
> to avoid automatic use of the existing `conan.lock` file when you run > to avoid automatic use of the existing `conan.lock` file when you run
> `conan export` manually on your machine > `conan export` manually on your machine
>
> This is not recommended though, as you might end up using different revisions of recipes.
### Conan profile tweaks ### Conan profile tweaks
@@ -188,14 +204,39 @@ Possible values are ['5.0', '5.1', '6.0', '6.1', '7.0', '7.3', '8.0', '8.1',
Read "http://docs.conan.io/2/knowledge/faq.html#error-invalid-setting" Read "http://docs.conan.io/2/knowledge/faq.html#error-invalid-setting"
``` ```
you need to add your compiler to the list of compiler versions in you need to amend the list of compiler versions in
`$(conan config home)/settings_user.yml`, by adding the required version number(s) `$(conan config home)/settings.yml`, by appending the required version number(s)
to the `version` array specific for your compiler. For example: to the `version` array specific for your compiler. For example:
```yaml ```yaml
compiler: apple-clang:
apple-clang: version:
version: ["17.0"] [
"5.0",
"5.1",
"6.0",
"6.1",
"7.0",
"7.3",
"8.0",
"8.1",
"9.0",
"9.1",
"10.0",
"11.0",
"12.0",
"13",
"13.0",
"13.1",
"14",
"14.0",
"15",
"15.0",
"16",
"16.0",
"17",
"17.0",
]
``` ```
#### Multiple compilers #### Multiple compilers
@@ -327,36 +368,6 @@ The workaround for this error is to add two lines to your profile:
tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS'] tools.build:cxxflags=['-DBOOST_ASIO_DISABLE_CONCEPTS']
``` ```
### Set Up Ccache
To speed up repeated compilations, we recommend that you install
[ccache](https://ccache.dev), a tool that wraps your compiler so that it can
cache build objects locally.
#### Linux
You can install it using the package manager, e.g. `sudo apt install ccache`
(Ubuntu) or `sudo dnf install ccache` (RHEL).
#### macOS
You can install it using Homebrew, i.e. `brew install ccache`.
#### Windows
You can install it using Chocolatey, i.e. `choco install ccache`. If you already
have Ccache installed, then `choco upgrade ccache` will update it to the latest
version. However, if you see an error such as:
```
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(617,5): error MSB6006: "cl.exe" exited with code 3.
```
then please install a specific version of Ccache that we know works, via: `choco
install ccache --version 4.11.3 --allow-downgrade`.
### Build and Test ### Build and Test
1. Create a build directory and move into it. 1. Create a build directory and move into it.
@@ -539,10 +550,10 @@ See [Sanitizers docs](./docs/build/sanitizers.md) for more details.
| `werr` | OFF | Treat compilation warnings as errors | | `werr` | OFF | Treat compilation warnings as errors |
| `wextra` | OFF | Enable additional compilation warnings | | `wextra` | OFF | Enable additional compilation warnings |
[Unity builds][5] may be faster for the first build (at the cost of much more [Unity builds][5] may be faster for the first build
memory) since they concatenate sources into fewer translation units. Non-unity (at the cost of much more memory) since they concatenate sources into fewer
builds may be faster for incremental builds, and can be helpful for detecting translation units. Non-unity builds may be faster for incremental builds,
`#include` omissions. and can be helpful for detecting `#include` omissions.
## Troubleshooting ## Troubleshooting

View File

@@ -1,23 +1,20 @@
cmake_minimum_required(VERSION 3.16) cmake_minimum_required(VERSION 3.16)
if(POLICY CMP0074) if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW) cmake_policy(SET CMP0074 NEW)
endif() endif()
if(POLICY CMP0077) if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW) cmake_policy(SET CMP0077 NEW)
endif() endif()
# Fix "unrecognized escape" issues when passing CMAKE_MODULE_PATH on Windows. # Fix "unrecognized escape" issues when passing CMAKE_MODULE_PATH on Windows.
if(DEFINED CMAKE_MODULE_PATH) file(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH)
file(TO_CMAKE_PATH "${CMAKE_MODULE_PATH}" CMAKE_MODULE_PATH)
endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
project(xrpl) project(xrpl)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CompilationEnv) include(CompilationEnv)
@@ -36,40 +33,51 @@ endif()
# Enable ccache to speed up builds. # Enable ccache to speed up builds.
include(Ccache) include(Ccache)
# make GIT_COMMIT_HASH define available to all sources
find_package(Git)
if(Git_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse HEAD
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gch)
if(gch)
set(GIT_COMMIT_HASH "${gch}")
message(STATUS gch: ${GIT_COMMIT_HASH})
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
endif()
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse --abbrev-ref HEAD
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gb)
if(gb)
set(GIT_BRANCH "${gb}")
message(STATUS gb: ${GIT_BRANCH})
add_definitions(-DGIT_BRANCH="${GIT_BRANCH}")
endif()
endif() #git
if(thread_safety_analysis) if(thread_safety_analysis)
add_compile_options( add_compile_options(-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -DXRPL_ENABLE_THREAD_SAFETY_ANNOTATIONS)
-Wthread-safety add_compile_options("-stdlib=libc++")
-D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS add_link_options("-stdlib=libc++")
-DXRPL_ENABLE_THREAD_SAFETY_ANNOTATIONS
)
add_compile_options("-stdlib=libc++")
add_link_options("-stdlib=libc++")
endif() endif()
include(CheckCXXCompilerFlag) include (CheckCXXCompilerFlag)
include(FetchContent) include (FetchContent)
include(ExternalProject) include (ExternalProject)
include(CMakeFuncs) # must come *after* ExternalProject b/c it overrides one function in EP include (CMakeFuncs) # must come *after* ExternalProject b/c it overrides one function in EP
if(target) if (target)
message( message (FATAL_ERROR "The target option has been removed - use native cmake options to control build")
FATAL_ERROR endif ()
"The target option has been removed - use native cmake options to control build"
)
endif()
include(XrplSanity) include(XrplSanity)
include(XrplVersion) include(XrplVersion)
include(XrplSettings) include(XrplSettings)
# this check has to remain in the top-level cmake because of the early return statement # this check has to remain in the top-level cmake
if(packages_only) # because of the early return statement
if(NOT TARGET rpm) if (packages_only)
message( if (NOT TARGET rpm)
FATAL_ERROR message (FATAL_ERROR "packages_only requested, but targets were not created - is docker installed?")
"packages_only requested, but targets were not created - is docker installed?" endif()
) return ()
endif() endif ()
return()
endif()
include(XrplCompiler) include(XrplCompiler)
include(XrplSanitizers) include(XrplSanitizers)
include(XrplInterface) include(XrplInterface)
@@ -77,9 +85,11 @@ include(XrplInterface)
option(only_docs "Include only the docs target?" FALSE) option(only_docs "Include only the docs target?" FALSE)
include(XrplDocs) include(XrplDocs)
if(only_docs) if(only_docs)
return() return()
endif() endif()
###
include(deps/Boost) include(deps/Boost)
add_subdirectory(external/antithesis-sdk) add_subdirectory(external/antithesis-sdk)
@@ -95,47 +105,45 @@ find_package(SOCI REQUIRED)
find_package(SQLite3 REQUIRED) find_package(SQLite3 REQUIRED)
find_package(xxHash REQUIRED) find_package(xxHash REQUIRED)
target_link_libraries( target_link_libraries(xrpl_libs INTERFACE
xrpl_libs ed25519::ed25519
INTERFACE lz4::lz4
ed25519::ed25519 OpenSSL::Crypto
lz4::lz4 OpenSSL::SSL
OpenSSL::Crypto secp256k1::secp256k1
OpenSSL::SSL soci::soci
secp256k1::secp256k1 SQLite::SQLite3
soci::soci
SQLite::SQLite3
) )
option(rocksdb "Enable RocksDB" ON) option(rocksdb "Enable RocksDB" ON)
if(rocksdb) if(rocksdb)
find_package(RocksDB REQUIRED) find_package(RocksDB REQUIRED)
set_target_properties( set_target_properties(RocksDB::rocksdb PROPERTIES
RocksDB::rocksdb INTERFACE_COMPILE_DEFINITIONS XRPL_ROCKSDB_AVAILABLE=1
PROPERTIES INTERFACE_COMPILE_DEFINITIONS XRPL_ROCKSDB_AVAILABLE=1
) )
target_link_libraries(xrpl_libs INTERFACE RocksDB::rocksdb) target_link_libraries(xrpl_libs INTERFACE RocksDB::rocksdb)
endif() endif()
# Work around changes to Conan recipe for now. # Work around changes to Conan recipe for now.
if(TARGET nudb::core) if(TARGET nudb::core)
set(nudb nudb::core) set(nudb nudb::core)
elseif(TARGET NuDB::nudb) elseif(TARGET NuDB::nudb)
set(nudb NuDB::nudb) set(nudb NuDB::nudb)
else() else()
message(FATAL_ERROR "unknown nudb target") message(FATAL_ERROR "unknown nudb target")
endif() endif()
target_link_libraries(xrpl_libs INTERFACE ${nudb}) target_link_libraries(xrpl_libs INTERFACE ${nudb})
if(coverage) if(coverage)
include(XrplCov) include(XrplCov)
endif() endif()
set(PROJECT_EXPORT_SET XrplExports)
include(XrplCore) include(XrplCore)
include(XrplInstall) include(XrplInstall)
include(XrplValidatorKeys) include(XrplValidatorKeys)
if(tests) if(tests)
include(CTest) include(CTest)
add_subdirectory(src/tests/libxrpl) add_subdirectory(src/tests/libxrpl)
endif() endif()

View File

@@ -127,6 +127,26 @@ tl;dr
> 6. Wrap the body at 72 characters. > 6. Wrap the body at 72 characters.
> 7. Use the body to explain what and why vs. how. > 7. Use the body to explain what and why vs. how.
In addition to those guidelines, please add one of the following
prefixes to the subject line if appropriate.
- `fix:` - The primary purpose is to fix an existing bug.
- `perf:` - The primary purpose is performance improvements.
- `refactor:` - The changes refactor code without affecting
functionality.
- `test:` - The changes _only_ affect unit tests.
- `docs:` - The changes _only_ affect documentation. This can
include code comments in addition to `.md` files like this one.
- `build:` - The changes _only_ affect the build process,
including CMake and/or Conan settings.
- `chore:` - Other tasks that don't affect the binary, but don't fit
any of the other cases. e.g. formatting, git settings, updating
Github Actions jobs.
Whenever possible, when updating commits after the PR is open, please
add the PR number to the end of the subject line. e.g. `test: Add
unit tests for Feature X (#1234)`.
## Pull requests ## Pull requests
In general, pull requests use `develop` as the base branch. In general, pull requests use `develop` as the base branch.
@@ -160,23 +180,6 @@ credibility of the existing approvals is insufficient.
Pull requests must be merged by [squash-and-merge][squash] Pull requests must be merged by [squash-and-merge][squash]
to preserve a linear history for the `develop` branch. to preserve a linear history for the `develop` branch.
### Type of Change
In addition to those guidelines, please start your PR title with one of the following:
- `build:` - The changes _only_ affect the build process, including CMake and/or Conan settings.
- `feat`: New feature (change which adds functionality).
- `fix:` - The primary purpose is to fix an existing bug.
- `docs:` - The changes _only_ affect documentation.
- `test:` - The changes _only_ affect unit tests.
- `ci`: Continuous Integration (changes to our CI configuration files and scripts).
- `style`: Code style (formatting).
- `refactor:` - The changes refactor code without affecting functionality.
- `perf:` - The primary purpose is performance improvements.
- `chore:` - Other tasks that don't affect the binary, but don't fit any of the other cases. e.g. `git` settings, `clang-tidy`, removing dead code, dropping support for older tooling.
First letter after the type prefix should be capitalized, and the type prefix should be followed by a colon and a space. e.g. `feat: Add support for Borrowing Protocol`.
### "Ready to merge" ### "Ready to merge"
A pull request should only have the "Ready to merge" label added when it A pull request should only have the "Ready to merge" label added when it
@@ -216,7 +219,7 @@ coherent rather than a set of _thou shalt not_ commandments.
## Formatting ## Formatting
All code must conform to `clang-format` version 21, All code must conform to `clang-format` version 18,
according to the settings in [`.clang-format`](./.clang-format), according to the settings in [`.clang-format`](./.clang-format),
unless the result would be unreasonably difficult to read or maintain. unless the result would be unreasonably difficult to read or maintain.
To demarcate lines that should be left as-is, surround them with comments like To demarcate lines that should be left as-is, surround them with comments like
@@ -248,38 +251,6 @@ pip3 install pre-commit
pre-commit install pre-commit install
``` ```
## Clang-tidy
All code must pass `clang-tidy` checks according to the settings in [`.clang-tidy`](./.clang-tidy).
There is a Continuous Integration job that runs clang-tidy on pull requests. The CI will check:
- All changed C++ files (`.cpp`, `.h`, `.ipp`) when only code files are modified
- **All files in the repository** when the `.clang-tidy` configuration file is changed
This ensures that configuration changes don't introduce new warnings across the codebase.
### Installing clang-tidy
See the [environment setup guide](./docs/build/environment.md#clang-tidy) for platform-specific installation instructions.
### Running clang-tidy locally
Before running clang-tidy, you must build the project to generate required files (particularly protobuf headers). Refer to [`BUILD.md`](./BUILD.md) for build instructions.
Then run clang-tidy on your local changes:
```
run-clang-tidy -p build -allow-no-checks src tests
```
This will check all source files in the `src`, `include` and `tests` directories using the compile commands from your `build` directory.
If you wish to automatically fix whatever clang-tidy finds _and_ is capable of fixing, add `-fix` to the above command:
```
run-clang-tidy -p build -quiet -fix -allow-no-checks src tests
```
## Contracts and instrumentation ## Contracts and instrumentation
We are using [Antithesis](https://antithesis.com/) for continuous fuzzing, We are using [Antithesis](https://antithesis.com/) for continuous fuzzing,
@@ -901,8 +872,7 @@ git push --delete upstream-push master-next
11. [Create a new release on 11. [Create a new release on
Github](https://github.com/XRPLF/rippled/releases). Be sure that Github](https://github.com/XRPLF/rippled/releases). Be sure that
"Set as the latest release" is checked. "Set as the latest release" is checked.
12. Open a PR to update the [API-CHANGELOG](API-CHANGELOG.md) and `API-VERSION-[n].md` with the changes for this release (if any are missing). 12. Finally [reverse merge the release into `develop`](#follow-up-reverse-merge).
13. Finally, [reverse merge the release into `develop`](#follow-up-reverse-merge).
#### Special cases: point releases, hotfixes, etc. #### Special cases: point releases, hotfixes, etc.

View File

@@ -1,7 +1,7 @@
ISC License ISC License
Copyright (c) 2011, Arthur Britto, David Schwartz, Jed McCaleb, Vinnie Falco, Bob Way, Eric Lombrozo, Nikolaos D. Bougalis, Howard Hinnant. Copyright (c) 2011, Arthur Britto, David Schwartz, Jed McCaleb, Vinnie Falco, Bob Way, Eric Lombrozo, Nikolaos D. Bougalis, Howard Hinnant.
Copyright (c) 2012-present, the XRP Ledger developers. Copyright (c) 2012-2025, the XRP Ledger 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

View File

@@ -940,7 +940,23 @@
# #
# path Location to store the database # path Location to store the database
# #
# Optional keys for NuDB and RocksDB: # Optional keys
#
# cache_size Size of cache for database records. Default is 16384.
# Setting this value to 0 will use the default value.
#
# cache_age Length of time in minutes to keep database records
# cached. Default is 5 minutes. Setting this value to
# 0 will use the default value.
#
# Note: if neither cache_size nor cache_age is
# specified, the cache for database records will not
# be created. If only one of cache_size or cache_age
# is specified, the cache will be created using the
# default value for the unspecified parameter.
#
# Note: the cache will not be created if online_delete
# is specified.
# #
# fast_load Boolean. If set, load the last persisted ledger # fast_load Boolean. If set, load the last persisted ledger
# from disk upon process start before syncing to # from disk upon process start before syncing to
@@ -948,6 +964,8 @@
# if sufficient IOPS capacity is available. # if sufficient IOPS capacity is available.
# Default 0. # Default 0.
# #
# Optional keys for NuDB or RocksDB:
#
# earliest_seq The default is 32570 to match the XRP ledger # earliest_seq The default is 32570 to match the XRP ledger
# network's earliest allowed sequence. Alternate # network's earliest allowed sequence. Alternate
# networks may set this value. Minimum value of 1. # networks may set this value. Minimum value of 1.

View File

@@ -1,32 +1,30 @@
macro(exclude_from_default target_) macro (exclude_from_default target_)
set_target_properties(${target_} PROPERTIES EXCLUDE_FROM_ALL ON) set_target_properties (${target_} PROPERTIES EXCLUDE_FROM_ALL ON)
set_target_properties(${target_} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON) set_target_properties (${target_} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD ON)
endmacro() endmacro ()
macro(exclude_if_included target_) macro (exclude_if_included target_)
get_directory_property(has_parent PARENT_DIRECTORY) get_directory_property(has_parent PARENT_DIRECTORY)
if(has_parent) if (has_parent)
exclude_from_default(${target_}) exclude_from_default (${target_})
endif() endif ()
endmacro() endmacro ()
find_package(Git) find_package(Git)
function(git_branch branch_val) function (git_branch branch_val)
if(NOT GIT_FOUND) if (NOT GIT_FOUND)
return() return ()
endif() endif ()
set(_branch "") set (_branch "")
execute_process( execute_process (COMMAND ${GIT_EXECUTABLE} "rev-parse" "--abbrev-ref" "HEAD"
COMMAND ${GIT_EXECUTABLE} "rev-parse" "--abbrev-ref" "HEAD" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} RESULT_VARIABLE _git_exit_code
RESULT_VARIABLE _git_exit_code OUTPUT_VARIABLE _temp_branch
OUTPUT_VARIABLE _temp_branch OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
ERROR_QUIET if (_git_exit_code EQUAL 0)
) set (_branch ${_temp_branch})
if(_git_exit_code EQUAL 0) endif ()
set(_branch ${_temp_branch}) set (${branch_val} "${_branch}" PARENT_SCOPE)
endif() endfunction ()
set(${branch_val} "${_branch}" PARENT_SCOPE)
endfunction()

View File

@@ -1,62 +1,57 @@
find_program(CCACHE_PATH "ccache") find_program(CCACHE_PATH "ccache")
if(NOT CCACHE_PATH) if (NOT CCACHE_PATH)
return() return()
endif() endif ()
# For Linux and macOS we can use the ccache binary directly. # For Linux and macOS we can use the ccache binary directly.
if(NOT MSVC) if (NOT MSVC)
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PATH}") set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PATH}")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}") set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PATH}")
message(STATUS "Found ccache: ${CCACHE_PATH}") message(STATUS "Found ccache: ${CCACHE_PATH}")
return() return()
endif() endif ()
# For Windows more effort is required. The code below is a modified version of # For Windows more effort is required. The code below is a modified version of
# https://github.com/ccache/ccache/wiki/MS-Visual-Studio#usage-with-cmake. # https://github.com/ccache/ccache/wiki/MS-Visual-Studio#usage-with-cmake.
if("${CCACHE_PATH}" MATCHES "chocolatey") if ("${CCACHE_PATH}" MATCHES "chocolatey")
message(DEBUG "Ccache path: ${CCACHE_PATH}") message(DEBUG "Ccache path: ${CCACHE_PATH}")
# Chocolatey uses a shim executable that we cannot use directly, in which case we have to find the executable it # Chocolatey uses a shim executable that we cannot use directly, in which
# points to. If we cannot find the target executable then we cannot use ccache. # case we have to find the executable it points to. If we cannot find the
# target executable then we cannot use ccache.
find_program(BASH_PATH "bash") find_program(BASH_PATH "bash")
if(NOT BASH_PATH) if (NOT BASH_PATH)
message(WARNING "Could not find bash.") message(WARNING "Could not find bash.")
return() return()
endif() endif ()
execute_process( execute_process(
COMMAND COMMAND bash -c "export LC_ALL='en_US.UTF-8'; ${CCACHE_PATH} --shimgen-noop | grep -oP 'path to executable: \\K.+' | head -c -1"
bash -c OUTPUT_VARIABLE CCACHE_PATH)
"export LC_ALL='en_US.UTF-8'; ${CCACHE_PATH} --shimgen-noop | grep -oP 'path to executable: \\K.+' | head -c -1"
OUTPUT_VARIABLE CCACHE_PATH
)
if(NOT CCACHE_PATH) if (NOT CCACHE_PATH)
message(WARNING "Could not find ccache target.") message(WARNING "Could not find ccache target.")
return() return()
endif() endif ()
file(TO_CMAKE_PATH "${CCACHE_PATH}" CCACHE_PATH) file(TO_CMAKE_PATH "${CCACHE_PATH}" CCACHE_PATH)
endif() endif ()
message(STATUS "Found ccache: ${CCACHE_PATH}") message(STATUS "Found ccache: ${CCACHE_PATH}")
# Tell cmake to use ccache for compiling with Visual Studio. # Tell cmake to use ccache for compiling with Visual Studio.
file(COPY_FILE ${CCACHE_PATH} ${CMAKE_BINARY_DIR}/cl.exe ONLY_IF_DIFFERENT) file(COPY_FILE
${CCACHE_PATH} ${CMAKE_BINARY_DIR}/cl.exe
ONLY_IF_DIFFERENT)
set(CMAKE_VS_GLOBALS set(CMAKE_VS_GLOBALS
"CLToolExe=cl.exe" "CLToolExe=cl.exe"
"CLToolPath=${CMAKE_BINARY_DIR}" "CLToolPath=${CMAKE_BINARY_DIR}"
"TrackFileAccess=false" "TrackFileAccess=false"
"UseMultiToolTask=true" "UseMultiToolTask=true")
)
# By default Visual Studio generators will use /Zi to capture debug information, which is not compatible with ccache, so # By default Visual Studio generators will use /Zi to capture debug information,
# tell it to use /Z7 instead. # which is not compatible with ccache, so tell it to use /Z7 instead.
if(MSVC) if (MSVC)
foreach( foreach (var_
var_ CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE)
CMAKE_C_FLAGS_RELEASE string (REPLACE "/Zi" "/Z7" ${var_} "${${var_}}")
CMAKE_CXX_FLAGS_DEBUG endforeach ()
CMAKE_CXX_FLAGS_RELEASE endif ()
)
string(REPLACE "/Zi" "/Z7" ${var_} "${${var_}}")
endforeach()
endif()

View File

@@ -172,49 +172,44 @@ include(CMakeParseArguments)
option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE) 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
COMMAND xcrun -f llvm-cov OUTPUT_VARIABLE LLVMCOV_PATH
OUTPUT_VARIABLE LLVMCOV_PATH OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_STRIP_TRAILING_WHITESPACE )
) else()
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
"Clang version must be 3.0.0 or greater! Aborting..."
)
endif()
elseif(
NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU"
AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(LLVM)?[Ff]lang"
)
message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...")
endif() endif()
elseif(NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU"
AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(LLVM)?[Ff]lang")
message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...")
endif()
endforeach() endforeach()
set(COVERAGE_COMPILER_FLAGS "-g --coverage" CACHE INTERNAL "") set(COVERAGE_COMPILER_FLAGS "-g --coverage"
CACHE INTERNAL "")
set(COVERAGE_CXX_COMPILER_FLAGS "") set(COVERAGE_CXX_COMPILER_FLAGS "")
set(COVERAGE_C_COMPILER_FLAGS "") set(COVERAGE_C_COMPILER_FLAGS "")
@@ -233,75 +228,49 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
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_CXX_COMPILER_FLAGS} -fprofile-abs-path")
"${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-abs-path"
)
endif() endif()
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_C_COMPILER_FLAGS} -fprofile-abs-path")
"${COVERAGE_C_COMPILER_FLAGS} -fprofile-abs-path"
)
endif() endif()
check_linker_flag(CXX -fprofile-abs-path HAVE_cxx_linker_fprofile_abs_path) check_linker_flag(CXX -fprofile-abs-path HAVE_cxx_linker_fprofile_abs_path)
if(HAVE_cxx_linker_fprofile_abs_path) if(HAVE_cxx_linker_fprofile_abs_path)
set(COVERAGE_CXX_LINKER_FLAGS set(COVERAGE_CXX_LINKER_FLAGS "${COVERAGE_CXX_LINKER_FLAGS} -fprofile-abs-path")
"${COVERAGE_CXX_LINKER_FLAGS} -fprofile-abs-path"
)
endif() endif()
check_linker_flag(C -fprofile-abs-path HAVE_c_linker_fprofile_abs_path) check_linker_flag(C -fprofile-abs-path HAVE_c_linker_fprofile_abs_path)
if(HAVE_c_linker_fprofile_abs_path) if(HAVE_c_linker_fprofile_abs_path)
set(COVERAGE_C_LINKER_FLAGS set(COVERAGE_C_LINKER_FLAGS "${COVERAGE_C_LINKER_FLAGS} -fprofile-abs-path")
"${COVERAGE_C_LINKER_FLAGS} -fprofile-abs-path"
)
endif() endif()
check_cxx_compiler_flag(-fprofile-update=atomic HAVE_cxx_fprofile_update) check_cxx_compiler_flag(-fprofile-update=atomic HAVE_cxx_fprofile_update)
if(HAVE_cxx_fprofile_update) if(HAVE_cxx_fprofile_update)
set(COVERAGE_CXX_COMPILER_FLAGS set(COVERAGE_CXX_COMPILER_FLAGS "${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-update=atomic")
"${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-update=atomic"
)
endif() endif()
check_c_compiler_flag(-fprofile-update=atomic HAVE_c_fprofile_update) check_c_compiler_flag(-fprofile-update=atomic HAVE_c_fprofile_update)
if(HAVE_c_fprofile_update) if(HAVE_c_fprofile_update)
set(COVERAGE_C_COMPILER_FLAGS set(COVERAGE_C_COMPILER_FLAGS "${COVERAGE_C_COMPILER_FLAGS} -fprofile-update=atomic")
"${COVERAGE_C_COMPILER_FLAGS} -fprofile-update=atomic"
)
endif() endif()
check_linker_flag( check_linker_flag(CXX -fprofile-update=atomic HAVE_cxx_linker_fprofile_update)
CXX
-fprofile-update=atomic
HAVE_cxx_linker_fprofile_update
)
if(HAVE_cxx_linker_fprofile_update) if(HAVE_cxx_linker_fprofile_update)
set(COVERAGE_CXX_LINKER_FLAGS set(COVERAGE_CXX_LINKER_FLAGS "${COVERAGE_CXX_LINKER_FLAGS} -fprofile-update=atomic")
"${COVERAGE_CXX_LINKER_FLAGS} -fprofile-update=atomic"
)
endif() endif()
check_linker_flag(C -fprofile-update=atomic HAVE_c_linker_fprofile_update) check_linker_flag(C -fprofile-update=atomic HAVE_c_linker_fprofile_update)
if(HAVE_c_linker_fprofile_update) if(HAVE_c_linker_fprofile_update)
set(COVERAGE_C_LINKER_FLAGS set(COVERAGE_C_LINKER_FLAGS "${COVERAGE_C_LINKER_FLAGS} -fprofile-update=atomic")
"${COVERAGE_C_LINKER_FLAGS} -fprofile-update=atomic"
)
endif() endif()
endif() endif()
get_property( get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
GENERATOR_IS_MULTI_CONFIG
GLOBAL
PROPERTY GENERATOR_IS_MULTI_CONFIG
)
if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)) if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG))
message( message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
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) endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)
# Defines a target for running and collection code coverage information # Defines a target for running and collection code coverage information
@@ -330,13 +299,7 @@ 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...")
@@ -358,33 +321,21 @@ function(setup_target_for_coverage_gcovr)
endif() endif()
if(NOT DEFINED Coverage_EXECUTABLE AND DEFINED Coverage_EXECUTABLE_ARGS) if(NOT DEFINED Coverage_EXECUTABLE AND DEFINED Coverage_EXECUTABLE_ARGS)
message( message(FATAL_ERROR "EXECUTABLE_ARGS must not be set if EXECUTABLE is not set")
FATAL_ERROR
"EXECUTABLE_ARGS must not be set if EXECUTABLE is not set"
)
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
"Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting..."
)
else() else()
if( if((Coverage_FORMAT STREQUAL "html-details")
(Coverage_FORMAT STREQUAL "html-details") OR (Coverage_FORMAT STREQUAL "html-nested"))
OR (Coverage_FORMAT STREQUAL "html-nested") set(GCOVR_OUTPUT_FILE ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html)
)
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")
(Coverage_FORMAT STREQUAL "json-summary")
OR (Coverage_FORMAT STREQUAL "json-details") 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)
@@ -397,65 +348,50 @@ function(setup_target_for_coverage_gcovr)
endif() endif()
endif() endif()
if( if((Coverage_FORMAT STREQUAL "cobertura")
(Coverage_FORMAT STREQUAL "cobertura") OR (Coverage_FORMAT STREQUAL "xml"))
OR (Coverage_FORMAT STREQUAL "xml") list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}" )
) list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura-pretty )
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}")
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 "jacoco") elseif(Coverage_FORMAT STREQUAL "jacoco")
list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco "${GCOVR_OUTPUT_FILE}" )
list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco-pretty) list(APPEND GCOVR_ADDITIONAL_ARGS --jacoco-pretty )
elseif(Coverage_FORMAT STREQUAL "clover") elseif(Coverage_FORMAT STREQUAL "clover")
list(APPEND GCOVR_ADDITIONAL_ARGS --clover "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --clover "${GCOVR_OUTPUT_FILE}" )
list(APPEND GCOVR_ADDITIONAL_ARGS --clover-pretty) list(APPEND GCOVR_ADDITIONAL_ARGS --clover-pretty )
elseif(Coverage_FORMAT STREQUAL "lcov") elseif(Coverage_FORMAT STREQUAL "lcov")
list(APPEND GCOVR_ADDITIONAL_ARGS --lcov "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --lcov "${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
"Unsupported output style ${Coverage_FORMAT}! Aborting..."
)
endif() 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
${Coverage_EXCLUDE}
${COVERAGE_EXCLUDES}
${COVERAGE_GCOVR_EXCLUDES}
)
if(CMAKE_VERSION VERSION_GREATER 3.4) if(CMAKE_VERSION VERSION_GREATER 3.4)
get_filename_component( get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR})
EXCLUDE
${EXCLUDE}
ABSOLUTE
BASE_DIR ${BASEDIR}
)
endif() endif()
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
endforeach() endforeach()
@@ -473,29 +409,22 @@ function(setup_target_for_coverage_gcovr)
# before running the coverage target NAME # before running the coverage target NAME
if(DEFINED Coverage_EXECUTABLE) if(DEFINED Coverage_EXECUTABLE)
set(GCOVR_EXEC_TESTS_CMD set(GCOVR_EXEC_TESTS_CMD
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
${Coverage_EXECUTABLE_ARGS}
) )
endif() endif()
# Create folder # Create folder
if(DEFINED GCOVR_CREATE_FOLDER) if(DEFINED GCOVR_CREATE_FOLDER)
set(GCOVR_FOLDER_CMD set(GCOVR_FOLDER_CMD
${CMAKE_COMMAND} ${CMAKE_COMMAND} -E make_directory ${GCOVR_CREATE_FOLDER})
-E
make_directory
${GCOVR_CREATE_FOLDER}
)
endif() endif()
# Running gcovr # Running gcovr
set(GCOVR_CMD set(GCOVR_CMD
${GCOVR_PATH} ${GCOVR_PATH}
--gcov-executable --gcov-executable ${GCOV_TOOL}
${GCOV_TOOL}
--gcov-ignore-parse-errors=negative_hits.warn_once_per_file --gcov-ignore-parse-errors=negative_hits.warn_once_per_file
-r -r ${BASEDIR}
${BASEDIR}
${GCOVR_ADDITIONAL_ARGS} ${GCOVR_ADDITIONAL_ARGS}
${GCOVR_EXCLUDE_ARGS} ${GCOVR_EXCLUDE_ARGS}
--object-directory=${PROJECT_BINARY_DIR} --object-directory=${PROJECT_BINARY_DIR}
@@ -506,23 +435,13 @@ function(setup_target_for_coverage_gcovr)
if(NOT "${GCOVR_EXEC_TESTS_CMD}" STREQUAL "") if(NOT "${GCOVR_EXEC_TESTS_CMD}" STREQUAL "")
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}")
endif() endif()
if(NOT "${GCOVR_FOLDER_CMD}" STREQUAL "") if(NOT "${GCOVR_FOLDER_CMD}" STREQUAL "")
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()
@@ -531,11 +450,11 @@ function(setup_target_for_coverage_gcovr)
message(STATUS "${GCOVR_CMD_SPACED}") message(STATUS "${GCOVR_CMD_SPACED}")
endif() endif()
add_custom_target( add_custom_target(${Coverage_NAME}
${Coverage_NAME}
COMMAND ${GCOVR_EXEC_TESTS_CMD} COMMAND ${GCOVR_EXEC_TESTS_CMD}
COMMAND ${GCOVR_FOLDER_CMD} COMMAND ${GCOVR_FOLDER_CMD}
COMMAND ${GCOVR_CMD} COMMAND ${GCOVR_CMD}
BYPRODUCTS ${GCOVR_OUTPUT_FILE} BYPRODUCTS ${GCOVR_OUTPUT_FILE}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR} WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES} DEPENDS ${Coverage_DEPENDENCIES}
@@ -544,49 +463,25 @@ 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} POST_BUILD
TARGET ${Coverage_NAME}
POST_BUILD
COMMAND echo COMMAND echo
COMMENT COMMENT "Code coverage report saved in ${GCOVR_OUTPUT_FILE} formatted as ${Coverage_FORMAT}"
"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(add_code_coverage_to_target name scope) function(add_code_coverage_to_target name scope)
separate_arguments( separate_arguments(COVERAGE_CXX_COMPILER_FLAGS NATIVE_COMMAND "${COVERAGE_CXX_COMPILER_FLAGS}")
COVERAGE_CXX_COMPILER_FLAGS separate_arguments(COVERAGE_C_COMPILER_FLAGS NATIVE_COMMAND "${COVERAGE_C_COMPILER_FLAGS}")
NATIVE_COMMAND separate_arguments(COVERAGE_CXX_LINKER_FLAGS NATIVE_COMMAND "${COVERAGE_CXX_LINKER_FLAGS}")
"${COVERAGE_CXX_COMPILER_FLAGS}" separate_arguments(COVERAGE_C_LINKER_FLAGS NATIVE_COMMAND "${COVERAGE_C_LINKER_FLAGS}")
)
separate_arguments(
COVERAGE_C_COMPILER_FLAGS
NATIVE_COMMAND
"${COVERAGE_C_COMPILER_FLAGS}"
)
separate_arguments(
COVERAGE_CXX_LINKER_FLAGS
NATIVE_COMMAND
"${COVERAGE_CXX_LINKER_FLAGS}"
)
separate_arguments(
COVERAGE_C_LINKER_FLAGS
NATIVE_COMMAND
"${COVERAGE_C_LINKER_FLAGS}"
)
# Add compiler options to the target # Add compiler options to the target
target_compile_options( target_compile_options(${name} ${scope}
${name} $<$<COMPILE_LANGUAGE:CXX>:${COVERAGE_CXX_COMPILER_FLAGS}>
${scope} $<$<COMPILE_LANGUAGE:C>:${COVERAGE_C_COMPILER_FLAGS}>)
$<$<COMPILE_LANGUAGE:CXX>:${COVERAGE_CXX_COMPILER_FLAGS}>
$<$<COMPILE_LANGUAGE:C>:${COVERAGE_C_COMPILER_FLAGS}>
)
target_link_libraries( target_link_libraries (${name} ${scope}
${name} $<$<LINK_LANGUAGE:CXX>:${COVERAGE_CXX_LINKER_FLAGS} gcov>
${scope} $<$<LINK_LANGUAGE:C>:${COVERAGE_C_LINKER_FLAGS} gcov>
$<$<LINK_LANGUAGE:CXX>:${COVERAGE_CXX_LINKER_FLAGS}>
$<$<LINK_LANGUAGE:C>:${COVERAGE_C_LINKER_FLAGS}>
) )
endfunction() # add_code_coverage_to_target endfunction() # add_code_coverage_to_target

View File

@@ -1,7 +1,8 @@
# Shared detection of compiler, operating system, and architecture. # Shared detection of compiler, operating system, and architecture.
# #
# This module centralizes environment detection so that other CMake modules can use the same variables instead of # This module centralizes environment detection so that other
# repeating checks on CMAKE_* and built-in platform variables. # CMake modules can use the same variables instead of repeating
# checks on CMAKE_* and built-in platform variables.
# Only run once per configure step. # Only run once per configure step.
include_guard(GLOBAL) include_guard(GLOBAL)
@@ -12,22 +13,17 @@ include_guard(GLOBAL)
set(is_clang FALSE) set(is_clang FALSE)
set(is_gcc FALSE) set(is_gcc FALSE)
set(is_msvc FALSE) set(is_msvc FALSE)
set(is_xcode FALSE)
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") # Clang or AppleClang if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") # Clang or AppleClang
set(is_clang TRUE) set(is_clang TRUE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(is_gcc TRUE) set(is_gcc TRUE)
elseif(MSVC) elseif(MSVC)
set(is_msvc TRUE) set(is_msvc TRUE)
else() else()
message(FATAL_ERROR "Unsupported C++ compiler: ${CMAKE_CXX_COMPILER_ID}") message(FATAL_ERROR "Unsupported C++ compiler: ${CMAKE_CXX_COMPILER_ID}")
endif() endif()
# Xcode generator detection
if(CMAKE_GENERATOR STREQUAL "Xcode")
set(is_xcode TRUE)
endif()
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Operating system detection # Operating system detection
@@ -37,11 +33,11 @@ set(is_windows FALSE)
set(is_macos FALSE) set(is_macos FALSE)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux") if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(is_linux TRUE) set(is_linux TRUE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows") elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(is_windows TRUE) set(is_windows TRUE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(is_macos TRUE) set(is_macos TRUE)
endif() endif()
# -------------------------------------------------------------------- # --------------------------------------------------------------------
@@ -50,9 +46,9 @@ endif()
set(is_amd64 FALSE) set(is_amd64 FALSE)
set(is_arm64 FALSE) set(is_arm64 FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
set(is_amd64 TRUE) set(is_amd64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64|ARM64") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64")
set(is_arm64 TRUE) set(is_arm64 TRUE)
else() else()
message(FATAL_ERROR "Unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}") message(FATAL_ERROR "Unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}")
endif() endif()

View File

@@ -1,28 +0,0 @@
include_guard()
set(GIT_BUILD_BRANCH "")
set(GIT_COMMIT_HASH "")
find_package(Git)
if(NOT Git_FOUND)
message(WARNING "Git not found. Git branch and commit hash will be empty.")
return()
endif()
set(GIT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.git)
execute_process(
COMMAND
${GIT_EXECUTABLE} --git-dir=${GIT_DIRECTORY} rev-parse --abbrev-ref HEAD
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE GIT_BUILD_BRANCH
)
execute_process(
COMMAND ${GIT_EXECUTABLE} --git-dir=${GIT_DIRECTORY} rev-parse HEAD
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE GIT_COMMIT_HASH
)
message(STATUS "Git branch: ${GIT_BUILD_BRANCH}")
message(STATUS "Git commit hash: ${GIT_COMMIT_HASH}")

View File

@@ -1,22 +1,25 @@
include(isolate_headers) include(isolate_headers)
function(xrpl_add_test name) function(xrpl_add_test name)
set(target ${PROJECT_NAME}.test.${name}) set(target ${PROJECT_NAME}.test.${name})
file( file(GLOB_RECURSE sources CONFIGURE_DEPENDS
GLOB_RECURSE sources "${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp" )
"${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp" add_executable(${target} ${ARGN} ${sources})
)
add_executable(${target} ${ARGN} ${sources})
isolate_headers( isolate_headers(
${target} ${target}
"${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}"
"${CMAKE_SOURCE_DIR}/tests/${name}" "${CMAKE_SOURCE_DIR}/tests/${name}"
PRIVATE PRIVATE
) )
add_test(NAME ${target} COMMAND ${target}) # Make sure the test isn't optimized away in unity builds
set_target_properties(${target} PROPERTIES
UNITY_BUILD_MODE GROUP
UNITY_BUILD_BATCH_SIZE 0) # Adjust as needed
add_test(NAME ${target} COMMAND ${target})
endfunction() endfunction()

View File

@@ -8,192 +8,153 @@ include(CompilationEnv)
TODO some/most of these common settings belong in a TODO some/most of these common settings belong in a
toolchain file, especially the ABI-impacting ones toolchain file, especially the ABI-impacting ones
#]=========================================================] #]=========================================================]
add_library(common INTERFACE) add_library (common INTERFACE)
add_library(Xrpl::common ALIAS common) add_library (Xrpl::common ALIAS common)
include(XrplSanitizers) include(XrplSanitizers)
# add a single global dependency on this interface lib # add a single global dependency on this interface lib
link_libraries(Xrpl::common) link_libraries (Xrpl::common)
# Respect CMAKE_POSITION_INDEPENDENT_CODE setting (may be set by Conan toolchain) # Respect CMAKE_POSITION_INDEPENDENT_CODE setting (may be set by Conan toolchain)
if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE) if(NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif() endif()
set_target_properties( set_target_properties (common
common PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE})
PROPERTIES
INTERFACE_POSITION_INDEPENDENT_CODE ${CMAKE_POSITION_INDEPENDENT_CODE}
)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
target_compile_definitions( target_compile_definitions (common
common INTERFACE
INTERFACE $<$<CONFIG:Debug>:DEBUG _DEBUG>
$<$<CONFIG:Debug>:DEBUG #[===[
_DEBUG>
#[===[
NOTE: CMAKE release builds already have NDEBUG defined, so no need to add it NOTE: CMAKE release builds already have NDEBUG defined, so no need to add it
explicitly except for the special case of (profile ON) and (assert OFF). explicitly except for the special case of (profile ON) and (assert OFF).
Presumably this is because we don't want profile builds asserting unless Presumably this is because we don't want profile builds asserting unless
asserts were specifically requested. asserts were specifically requested.
]===] ]===]
$<$<AND:$<BOOL:${profile}>,$<NOT:$<BOOL:${assert}>>>:NDEBUG> $<$<AND:$<BOOL:${profile}>,$<NOT:$<BOOL:${assert}>>>:NDEBUG>
# TODO: Remove once we have migrated functions from OpenSSL 1.x to 3.x. # TODO: Remove once we have migrated functions from OpenSSL 1.x to 3.x.
OPENSSL_SUPPRESS_DEPRECATED OPENSSL_SUPPRESS_DEPRECATED
) )
if(MSVC) if (MSVC)
# remove existing exception flag since we set it to -EHa # remove existing exception flag since we set it to -EHa
string(REGEX REPLACE "[-/]EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") string (REGEX REPLACE "[-/]EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
foreach( foreach (var_
var_ CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE)
CMAKE_C_FLAGS_RELEASE
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
)
# also remove dynamic runtime
string(REGEX REPLACE "[-/]MD[d]*" " " ${var_} "${${var_}}")
# /ZI (Edit & Continue debugging information) is incompatible with Gy- # also remove dynamic runtime
string(REPLACE "/ZI" "/Zi" ${var_} "${${var_}}") string (REGEX REPLACE "[-/]MD[d]*" " " ${var_} "${${var_}}")
# omit debug info completely under CI (not needed) # /ZI (Edit & Continue debugging information) is incompatible with Gy-
if(is_ci) string (REPLACE "/ZI" "/Zi" ${var_} "${${var_}}")
string(REPLACE "/Zi" " " ${var_} "${${var_}}")
string(REPLACE "/Z7" " " ${var_} "${${var_}}")
endif()
endforeach()
target_compile_options( # omit debug info completely under CI (not needed)
common if (is_ci)
INTERFACE # Increase object file max size string (REPLACE "/Zi" " " ${var_} "${${var_}}")
-bigobj string (REPLACE "/Z7" " " ${var_} "${${var_}}")
# Floating point behavior endif ()
-fp:precise endforeach ()
# __cdecl calling convention
-Gd target_compile_options (common
# Minimal rebuild: disabled INTERFACE
-Gm- -bigobj # Increase object file max size
# Function level linking: disabled -fp:precise # Floating point behavior
-Gy- -Gd # __cdecl calling convention
# Multiprocessor compilation -Gm- # Minimal rebuild: disabled
-MP -Gy- # Function level linking: disabled
# pragma omp: disabled -MP # Multiprocessor compilation
-openmp- -openmp- # pragma omp: disabled
# No error reporting to Internet -errorReport:none # No error reporting to Internet
-errorReport:none -nologo # Suppress login banner
# Suppress login banner -wd4018 # Disable signed/unsigned comparison warnings
-nologo -wd4244 # Disable float to int possible loss of data warnings
# Disable signed/unsigned comparison warnings -wd4267 # Disable size_t to T possible loss of data warnings
-wd4018 -wd4800 # Disable C4800(int to bool performance)
# Disable float to int possible loss of data warnings -wd4503 # Decorated name length exceeded, name was truncated
-wd4244 $<$<COMPILE_LANGUAGE:CXX>:
# Disable size_t to T possible loss of data warnings -EHa
-wd4267 -GR
# Disable C4800(int to bool performance) >
-wd4800 $<$<CONFIG:Release>:-Ox>
# Decorated name length exceeded, name was truncated $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:
-wd4503 -GS
$<$<COMPILE_LANGUAGE:CXX>: -Zc:forScope
-EHa >
-GR # static runtime
> $<$<CONFIG:Debug>:-MTd>
$<$<CONFIG:Release>:-Ox> $<$<NOT:$<CONFIG:Debug>>:-MT>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>: $<$<BOOL:${werr}>:-WX>
-GS )
-Zc:forScope target_compile_definitions (common
> INTERFACE
# static runtime _WIN32_WINNT=0x6000
$<$<CONFIG:Debug>:-MTd> _SCL_SECURE_NO_WARNINGS
$<$<NOT:$<CONFIG:Debug>>:-MT> _CRT_SECURE_NO_WARNINGS
$<$<BOOL:${werr}>:-WX> WIN32_CONSOLE
) WIN32_LEAN_AND_MEAN
target_compile_definitions( NOMINMAX
common # TODO: Resolve these warnings, don't just silence them
INTERFACE _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
_WIN32_WINNT=0x6000 $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:_CRTDBG_MAP_ALLOC>)
_SCL_SECURE_NO_WARNINGS target_link_libraries (common
_CRT_SECURE_NO_WARNINGS INTERFACE
WIN32_CONSOLE -errorreport:none
WIN32_LEAN_AND_MEAN -machine:X64)
NOMINMAX else ()
# TODO: Resolve these warnings, don't just silence them target_compile_options (common
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS INTERFACE
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>,$<NOT:$<BOOL:${is_ci}>>>:_CRTDBG_MAP_ALLOC> -Wall
) -Wdeprecated
target_link_libraries(common INTERFACE -errorreport:none -machine:X64) $<$<BOOL:${is_clang}>:-Wno-deprecated-declarations>
else() $<$<BOOL:${wextra}>:-Wextra -Wno-unused-parameter>
target_compile_options( $<$<BOOL:${werr}>:-Werror>
common -fstack-protector
INTERFACE -Wno-sign-compare
-Wall -Wno-unused-but-set-variable
-Wdeprecated $<$<NOT:$<CONFIG:Debug>>:-fno-strict-aliasing>
$<$<BOOL:${is_clang}>:-Wno-deprecated-declarations> # tweak gcc optimization for debug
$<$<BOOL:${wextra}>:-Wextra $<$<AND:$<BOOL:${is_gcc}>,$<CONFIG:Debug>>:-O0>
-Wno-unused-parameter> # Add debug symbols to release config
$<$<BOOL:${werr}>:-Werror> $<$<CONFIG:Release>:-g>)
-fstack-protector target_link_libraries (common
-Wno-sign-compare INTERFACE
-Wno-unused-but-set-variable -rdynamic
$<$<NOT:$<CONFIG:Debug>>:-fno-strict-aliasing> $<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now,--build-id>
# tweak gcc optimization for debug # link to static libc/c++ iff:
$<$<AND:$<BOOL:${is_gcc}>,$<CONFIG:Debug>>:-O0> # * static option set and
# Add debug symbols to release config # * NOT APPLE (AppleClang does not support static libc/c++) and
$<$<CONFIG:Release>:-g> # * NOT SANITIZERS (sanitizers typically don't work with static libc/c++)
) $<$<AND:$<BOOL:${static}>,$<NOT:$<BOOL:${APPLE}>>,$<NOT:$<BOOL:${SANITIZERS_ENABLED}>>>:
target_link_libraries( -static-libstdc++
common -static-libgcc
INTERFACE >)
-rdynamic endif ()
$<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now,--build-id>
# link to static libc/c++ iff: * static option set and * NOT APPLE (AppleClang does not support static
# libc/c++) and * NOT SANITIZERS (sanitizers typically don't work with static libc/c++)
$<$<AND:$<BOOL:${static}>,$<NOT:$<BOOL:${APPLE}>>,$<NOT:$<BOOL:${SANITIZERS_ENABLED}>>>:
-static-libstdc++
-static-libgcc
>
)
endif()
# Antithesis instrumentation will only be built and deployed using machines running Linux. # Antithesis instrumentation will only be built and deployed using machines running Linux.
if(voidstar) if (voidstar)
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message( message(FATAL_ERROR "Antithesis instrumentation requires Debug build type, aborting...")
FATAL_ERROR elseif (NOT is_linux)
"Antithesis instrumentation requires Debug build type, aborting..." message(FATAL_ERROR "Antithesis instrumentation requires Linux, aborting...")
) elseif (NOT (is_clang AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0))
elseif(NOT is_linux) message(FATAL_ERROR "Antithesis instrumentation requires Clang version 16 or later, aborting...")
message( endif ()
FATAL_ERROR endif ()
"Antithesis instrumentation requires Linux, aborting..."
)
elseif(
NOT (is_clang AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
)
message(
FATAL_ERROR
"Antithesis instrumentation requires Clang version 16 or later, aborting..."
)
endif()
endif()
if(use_mold) if (use_mold)
# use mold linker if available # use mold linker if available
execute_process( execute_process (
COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=mold -Wl,--version COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=mold -Wl,--version
ERROR_QUIET ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
OUTPUT_VARIABLE LD_VERSION if ("${LD_VERSION}" MATCHES "mold")
) target_link_libraries (common INTERFACE -fuse-ld=mold)
if("${LD_VERSION}" MATCHES "mold") endif ()
target_link_libraries(common INTERFACE -fuse-ld=mold) unset (LD_VERSION)
endif() elseif (use_gold AND is_gcc)
unset(LD_VERSION) # use gold linker if available
elseif(use_gold AND is_gcc) execute_process (
# use gold linker if available COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version
execute_process( ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version
ERROR_QUIET
OUTPUT_VARIABLE LD_VERSION
)
#[=========================================================[ #[=========================================================[
NOTE: THE gold linker inserts -rpath as DT_RUNPATH by NOTE: THE gold linker inserts -rpath as DT_RUNPATH by
default instead of DT_RPATH, so you might have slightly default instead of DT_RPATH, so you might have slightly
@@ -207,37 +168,34 @@ elseif(use_gold AND is_gcc)
disabling would be to figure out all the settings disabling would be to figure out all the settings
required to make gold play nicely with jemalloc. required to make gold play nicely with jemalloc.
#]=========================================================] #]=========================================================]
if(("${LD_VERSION}" MATCHES "GNU gold") AND (NOT jemalloc)) if (("${LD_VERSION}" MATCHES "GNU gold") AND (NOT jemalloc))
target_link_libraries( target_link_libraries (common
common INTERFACE
INTERFACE -fuse-ld=gold
-fuse-ld=gold -Wl,--no-as-needed
-Wl,--no-as-needed #[=========================================================[
#[=========================================================[
see https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1253638/comments/5 see https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1253638/comments/5
DT_RUNPATH does not work great for transitive DT_RUNPATH does not work great for transitive
dependencies (of which boost has a few) - so just dependencies (of which boost has a few) - so just
switch to DT_RPATH if doing dynamic linking with gold switch to DT_RPATH if doing dynamic linking with gold
#]=========================================================] #]=========================================================]
$<$<NOT:$<BOOL:${static}>>:-Wl,--disable-new-dtags> $<$<NOT:$<BOOL:${static}>>:-Wl,--disable-new-dtags>)
) endif ()
endif() unset (LD_VERSION)
unset(LD_VERSION) elseif (use_lld)
elseif(use_lld) # use lld linker if available
# use lld linker if available execute_process (
execute_process( COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=lld -Wl,--version
COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=lld -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
ERROR_QUIET if ("${LD_VERSION}" MATCHES "LLD")
OUTPUT_VARIABLE LD_VERSION target_link_libraries (common INTERFACE -fuse-ld=lld)
) endif ()
if("${LD_VERSION}" MATCHES "LLD") unset (LD_VERSION)
target_link_libraries(common INTERFACE -fuse-ld=lld)
endif()
unset(LD_VERSION)
endif() endif()
if(assert)
foreach(var_ CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE) if (assert)
string(REGEX REPLACE "[-/]DNDEBUG" "" ${var_} "${${var_}}") foreach (var_ CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE)
endforeach() STRING (REGEX REPLACE "[-/]DNDEBUG" "" ${var_} "${${var_}}")
endif() endforeach ()
endif ()

54
cmake/XrplConfig.cmake Normal file
View File

@@ -0,0 +1,54 @@
include (CMakeFindDependencyMacro)
# need to represent system dependencies of the lib here
#[=========================================================[
Boost
#]=========================================================]
if (static OR APPLE OR MSVC)
set (Boost_USE_STATIC_LIBS ON)
endif ()
set (Boost_USE_MULTITHREADED ON)
if (static OR MSVC)
set (Boost_USE_STATIC_RUNTIME ON)
else ()
set (Boost_USE_STATIC_RUNTIME OFF)
endif ()
find_dependency (Boost
COMPONENTS
chrono
container
context
coroutine
date_time
filesystem
program_options
regex
system
thread)
#[=========================================================[
OpenSSL
#]=========================================================]
if (NOT DEFINED OPENSSL_ROOT_DIR)
if (DEFINED ENV{OPENSSL_ROOT})
set (OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT})
elseif (APPLE)
find_program (homebrew brew)
if (homebrew)
execute_process (COMMAND ${homebrew} --prefix openssl
OUTPUT_VARIABLE OPENSSL_ROOT_DIR
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif ()
endif ()
file (TO_CMAKE_PATH "${OPENSSL_ROOT_DIR}" OPENSSL_ROOT_DIR)
endif ()
if (static OR APPLE OR MSVC)
set (OPENSSL_USE_STATIC_LIBS ON)
endif ()
set (OPENSSL_MSVC_STATIC_RT ON)
find_dependency (OpenSSL REQUIRED)
find_dependency (ZLIB)
find_dependency (date)
if (TARGET ZLIB::ZLIB)
set_target_properties(OpenSSL::Crypto PROPERTIES
INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
endif ()

View File

@@ -10,66 +10,62 @@ include(target_protobuf_sources)
# so we just build them as a separate library. # so we just build them as a separate library.
add_library(xrpl.libpb) add_library(xrpl.libpb)
set_target_properties(xrpl.libpb PROPERTIES UNITY_BUILD OFF) set_target_properties(xrpl.libpb PROPERTIES UNITY_BUILD OFF)
target_protobuf_sources( target_protobuf_sources(xrpl.libpb xrpl/proto
xrpl.libpb LANGUAGE cpp
xrpl/proto IMPORT_DIRS include/xrpl/proto
LANGUAGE cpp PROTOS include/xrpl/proto/xrpl.proto
IMPORT_DIRS include/xrpl/proto
PROTOS include/xrpl/proto/xrpl.proto
) )
file(GLOB_RECURSE protos "include/xrpl/proto/org/*.proto") file(GLOB_RECURSE protos "include/xrpl/proto/org/*.proto")
target_protobuf_sources( target_protobuf_sources(xrpl.libpb xrpl/proto
xrpl.libpb LANGUAGE cpp
xrpl/proto IMPORT_DIRS include/xrpl/proto
LANGUAGE cpp PROTOS "${protos}"
IMPORT_DIRS include/xrpl/proto
PROTOS "${protos}"
) )
target_protobuf_sources( target_protobuf_sources(xrpl.libpb xrpl/proto
xrpl.libpb LANGUAGE grpc
xrpl/proto IMPORT_DIRS include/xrpl/proto
LANGUAGE grpc PROTOS "${protos}"
IMPORT_DIRS include/xrpl/proto PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
PROTOS "${protos}" GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
) )
target_compile_options( target_compile_options(xrpl.libpb
xrpl.libpb PUBLIC
PUBLIC $<$<BOOL:${MSVC}>:-wd4996>
$<$<BOOL:${is_msvc}>:-wd4996> $<$<BOOL:${XCODE}>:
$<$<BOOL:${is_xcode}>: --system-header-prefix="google/protobuf"
--system-header-prefix="google/protobuf" -Wno-deprecated-dynamic-exception-spec
-Wno-deprecated-dynamic-exception-spec >
> PRIVATE
PRIVATE $<$<BOOL:${MSVC}>:-wd4065>
$<$<BOOL:${is_msvc}>:-wd4065> $<$<NOT:$<BOOL:${MSVC}>>:-Wno-deprecated-declarations>
$<$<NOT:$<BOOL:${is_msvc}>>:-Wno-deprecated-declarations>
) )
target_link_libraries(xrpl.libpb PUBLIC protobuf::libprotobuf gRPC::grpc++) target_link_libraries(xrpl.libpb
PUBLIC
protobuf::libprotobuf
gRPC::grpc++
)
# TODO: Clean up the number of library targets later. # TODO: Clean up the number of library targets later.
add_library(xrpl.imports.main INTERFACE) add_library(xrpl.imports.main INTERFACE)
target_link_libraries( target_link_libraries(xrpl.imports.main
xrpl.imports.main INTERFACE
INTERFACE absl::random_random
absl::random_random date::date
date::date ed25519::ed25519
ed25519::ed25519 LibArchive::LibArchive
LibArchive::LibArchive OpenSSL::Crypto
OpenSSL::Crypto Xrpl::boost
Xrpl::boost Xrpl::libs
Xrpl::libs Xrpl::opts
Xrpl::opts Xrpl::syslibs
Xrpl::syslibs secp256k1::secp256k1
secp256k1::secp256k1 xrpl.libpb
xrpl.libpb xxHash::xxhash
xxHash::xxhash $<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
) )
include(add_module) include(add_module)
@@ -79,16 +75,6 @@ include(target_link_modules)
add_module(xrpl beast) add_module(xrpl beast)
target_link_libraries(xrpl.libxrpl.beast PUBLIC xrpl.imports.main) target_link_libraries(xrpl.libxrpl.beast PUBLIC xrpl.imports.main)
include(GitInfo)
add_module(xrpl git)
target_compile_definitions(
xrpl.libxrpl.git
PRIVATE
GIT_COMMIT_HASH="${GIT_COMMIT_HASH}"
GIT_BUILD_BRANCH="${GIT_BUILD_BRANCH}"
)
target_link_libraries(xrpl.libxrpl.git PUBLIC xrpl.imports.main)
# Level 02 # Level 02
add_module(xrpl basics) add_module(xrpl basics)
target_link_libraries(xrpl.libxrpl.basics PUBLIC xrpl.libxrpl.beast) target_link_libraries(xrpl.libxrpl.basics PUBLIC xrpl.libxrpl.beast)
@@ -102,140 +88,80 @@ target_link_libraries(xrpl.libxrpl.crypto PUBLIC xrpl.libxrpl.basics)
# Level 04 # Level 04
add_module(xrpl protocol) add_module(xrpl protocol)
target_link_libraries( target_link_libraries(xrpl.libxrpl.protocol PUBLIC
xrpl.libxrpl.protocol xrpl.libxrpl.crypto
PUBLIC xrpl.libxrpl.crypto xrpl.libxrpl.git xrpl.libxrpl.json xrpl.libxrpl.json
) )
# Level 05 # Level 05
## Set up code generation for protocol_autogen module add_module(xrpl core)
include(XrplProtocolAutogen) target_link_libraries(xrpl.libxrpl.core PUBLIC
# Must call setup_protocol_autogen before add_module so that: xrpl.libxrpl.basics
# 1. Stale generated files are cleared before GLOB runs xrpl.libxrpl.json
# 2. Output file list is known for custom commands xrpl.libxrpl.protocol
setup_protocol_autogen()
add_module(xrpl protocol_autogen)
target_link_libraries(
xrpl.libxrpl.protocol_autogen
PUBLIC xrpl.libxrpl.protocol
) )
# Ensure code generation runs before compiling protocol_autogen
if(TARGET protocol_autogen_generate)
add_dependencies(xrpl.libxrpl.protocol_autogen protocol_autogen_generate)
endif()
# Level 06 # Level 06
add_module(xrpl core)
target_link_libraries(
xrpl.libxrpl.core
PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.json
xrpl.libxrpl.protocol
xrpl.libxrpl.protocol_autogen
)
# Level 07
add_module(xrpl resource) add_module(xrpl resource)
target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol) target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
# Level 08 # Level 07
add_module(xrpl net) add_module(xrpl net)
target_link_libraries( target_link_libraries(xrpl.libxrpl.net PUBLIC
xrpl.libxrpl.net xrpl.libxrpl.basics
PUBLIC xrpl.libxrpl.json
xrpl.libxrpl.protocol
xrpl.libxrpl.resource
)
add_module(xrpl server)
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol)
add_module(xrpl nodestore)
target_link_libraries(xrpl.libxrpl.nodestore PUBLIC
xrpl.libxrpl.basics xrpl.libxrpl.basics
xrpl.libxrpl.json xrpl.libxrpl.json
xrpl.libxrpl.protocol xrpl.libxrpl.protocol
xrpl.libxrpl.resource
)
add_module(xrpl nodestore)
target_link_libraries(
xrpl.libxrpl.nodestore
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol
) )
add_module(xrpl shamap) add_module(xrpl shamap)
target_link_libraries( target_link_libraries(xrpl.libxrpl.shamap PUBLIC
xrpl.libxrpl.shamap
PUBLIC
xrpl.libxrpl.basics xrpl.libxrpl.basics
xrpl.libxrpl.crypto xrpl.libxrpl.crypto
xrpl.libxrpl.protocol xrpl.libxrpl.protocol
xrpl.libxrpl.nodestore xrpl.libxrpl.nodestore
) )
add_module(xrpl rdb)
target_link_libraries(
xrpl.libxrpl.rdb
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.core
)
add_module(xrpl server)
target_link_libraries(
xrpl.libxrpl.server
PUBLIC
xrpl.libxrpl.protocol
xrpl.libxrpl.core
xrpl.libxrpl.rdb
xrpl.libxrpl.resource
)
add_module(xrpl conditions)
target_link_libraries(xrpl.libxrpl.conditions PUBLIC xrpl.libxrpl.server)
add_module(xrpl ledger) add_module(xrpl ledger)
target_link_libraries( target_link_libraries(xrpl.libxrpl.ledger PUBLIC
xrpl.libxrpl.ledger xrpl.libxrpl.basics
PUBLIC xrpl.libxrpl.json
xrpl.libxrpl.basics xrpl.libxrpl.protocol
xrpl.libxrpl.json
xrpl.libxrpl.protocol
xrpl.libxrpl.protocol_autogen
xrpl.libxrpl.rdb
xrpl.libxrpl.server
xrpl.libxrpl.shamap
xrpl.libxrpl.conditions
) )
add_module(xrpl tx)
target_link_libraries(xrpl.libxrpl.tx PUBLIC xrpl.libxrpl.ledger)
add_library(xrpl.libxrpl) add_library(xrpl.libxrpl)
set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl) set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
add_library(xrpl::libxrpl ALIAS xrpl.libxrpl) add_library(xrpl::libxrpl ALIAS xrpl.libxrpl)
file( file(GLOB_RECURSE sources CONFIGURE_DEPENDS
GLOB_RECURSE sources "${CMAKE_CURRENT_SOURCE_DIR}/src/libxrpl/*.cpp"
CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/libxrpl/*.cpp"
) )
target_sources(xrpl.libxrpl PRIVATE ${sources}) target_sources(xrpl.libxrpl PRIVATE ${sources})
target_link_modules( target_link_modules(xrpl PUBLIC
xrpl basics
PUBLIC beast
basics core
beast crypto
conditions json
core protocol
crypto resource
git server
json nodestore
ledger shamap
net net
nodestore ledger
protocol
protocol_autogen
rdb
resource
server
shamap
tx
) )
# All headers in libxrpl are in modules. # All headers in libxrpl are in modules.
@@ -248,50 +174,62 @@ target_link_modules(
# $<INSTALL_INTERFACE:include>) # $<INSTALL_INTERFACE:include>)
if(xrpld) if(xrpld)
add_executable(xrpld) add_executable(xrpld)
if(tests) if(tests)
target_compile_definitions(xrpld PUBLIC ENABLE_TESTS) target_compile_definitions(xrpld PUBLIC ENABLE_TESTS)
target_compile_definitions( target_compile_definitions(xrpld PRIVATE
xrpld UNIT_TEST_REFERENCE_FEE=${UNIT_TEST_REFERENCE_FEE}
PRIVATE UNIT_TEST_REFERENCE_FEE=${UNIT_TEST_REFERENCE_FEE}
)
endif()
target_include_directories(
xrpld
PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
) )
endif()
target_include_directories(xrpld
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
)
file( file(GLOB_RECURSE sources CONFIGURE_DEPENDS
GLOB_RECURSE sources "${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld/*.cpp"
CONFIGURE_DEPENDS )
"${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld/*.cpp" target_sources(xrpld PRIVATE ${sources})
if(tests)
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/test/*.cpp"
) )
target_sources(xrpld PRIVATE ${sources}) target_sources(xrpld PRIVATE ${sources})
endif()
if(tests) target_link_libraries(xrpld
file( Xrpl::boost
GLOB_RECURSE sources Xrpl::opts
CONFIGURE_DEPENDS Xrpl::libs
"${CMAKE_CURRENT_SOURCE_DIR}/src/test/*.cpp" xrpl.libxrpl
) )
target_sources(xrpld PRIVATE ${sources}) exclude_if_included(xrpld)
endif() # define a macro for tests that might need to
# be excluded or run differently in CI environment
if(is_ci)
target_compile_definitions(xrpld PRIVATE XRPL_RUNNING_IN_CI)
endif ()
target_link_libraries(xrpld Xrpl::boost Xrpl::opts Xrpl::libs xrpl.libxrpl) if(voidstar)
exclude_if_included(xrpld) target_compile_options(xrpld
# define a macro for tests that might need to PRIVATE
# be excluded or run differently in CI environment -fsanitize-coverage=trace-pc-guard
if(is_ci) )
target_compile_definitions(xrpld PRIVATE XRPL_RUNNING_IN_CI) # xrpld requires access to antithesis-sdk-cpp implementation file
endif() # antithesis_instrumentation.h, which is not exported as INTERFACE
target_include_directories(xrpld
PRIVATE
${CMAKE_SOURCE_DIR}/external/antithesis-sdk
)
endif()
if(voidstar) # any files that don't play well with unity should be added here
target_compile_options(xrpld PRIVATE -fsanitize-coverage=trace-pc-guard) if(tests)
# xrpld requires access to antithesis-sdk-cpp implementation file set_source_files_properties(
# antithesis_instrumentation.h, which is not exported as INTERFACE # these two seem to produce conflicts in beast teardown template methods
target_include_directories( src/test/rpc/ValidatorRPC_test.cpp
xrpld src/test/ledger/Invariants_test.cpp
PRIVATE ${CMAKE_SOURCE_DIR}/external/antithesis-sdk PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
) endif()
endif()
endif() endif()

View File

@@ -3,15 +3,12 @@
#]===================================================================] #]===================================================================]
if(NOT coverage) if(NOT coverage)
message(FATAL_ERROR "Code coverage not enabled! Aborting ...") message(FATAL_ERROR "Code coverage not enabled! Aborting ...")
endif() endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
message( message(WARNING "Code coverage on Windows is not supported, ignoring 'coverage' flag")
WARNING return()
"Code coverage on Windows is not supported, ignoring 'coverage' flag"
)
return()
endif() endif()
include(ProcessorCount) include(ProcessorCount)
@@ -19,35 +16,26 @@ ProcessorCount(PROCESSOR_COUNT)
include(CodeCoverage) include(CodeCoverage)
# The instructions for these commands come from the `CodeCoverage` module, which was copied from # The instructions for these commands come from the `CodeCoverage` module,
# https://github.com/bilke/cmake-modules, commit fb7d2a3, then locally changed (see CHANGES: section in # which was copied from https://github.com/bilke/cmake-modules, commit fb7d2a3,
# `CodeCoverage.cmake`) # then locally changed (see CHANGES: section in `CodeCoverage.cmake`)
set(GCOVR_ADDITIONAL_ARGS ${coverage_extra_args}) set(GCOVR_ADDITIONAL_ARGS ${coverage_extra_args})
if(NOT GCOVR_ADDITIONAL_ARGS STREQUAL "") if(NOT GCOVR_ADDITIONAL_ARGS STREQUAL "")
separate_arguments(GCOVR_ADDITIONAL_ARGS) separate_arguments(GCOVR_ADDITIONAL_ARGS)
endif() endif()
list( list(APPEND GCOVR_ADDITIONAL_ARGS
APPEND GCOVR_ADDITIONAL_ARGS --exclude-throw-branches
--exclude-throw-branches --exclude-noncode-lines
--exclude-noncode-lines --exclude-unreachable-branches -s
--exclude-unreachable-branches -j ${PROCESSOR_COUNT})
-s
-j
${PROCESSOR_COUNT}
)
setup_target_for_coverage_gcovr( setup_target_for_coverage_gcovr(
NAME coverage NAME coverage
FORMAT ${coverage_format} FORMAT ${coverage_format}
EXCLUDE EXCLUDE "src/test" "src/tests" "include/xrpl/beast/test" "include/xrpl/beast/unit_test" "${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
"src/test" DEPENDENCIES xrpld xrpl.tests
"src/tests"
"include/xrpl/beast/test"
"include/xrpl/beast/unit_test"
"${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
DEPENDENCIES xrpld xrpl.tests
) )
add_code_coverage_to_target(opts INTERFACE) add_code_coverage_to_target(opts INTERFACE)

View File

@@ -3,13 +3,13 @@
#]===================================================================] #]===================================================================]
if(NOT only_docs) if(NOT only_docs)
return() return()
endif() endif()
find_package(Doxygen) find_package(Doxygen)
if(NOT TARGET Doxygen::doxygen) if(NOT TARGET Doxygen::doxygen)
message(STATUS "doxygen executable not found -- skipping docs target") message(STATUS "doxygen executable not found -- skipping docs target")
return() return()
endif() endif()
set(doxygen_output_directory "${CMAKE_BINARY_DIR}/docs") set(doxygen_output_directory "${CMAKE_BINARY_DIR}/docs")
@@ -17,44 +17,40 @@ set(doxygen_include_path "${CMAKE_CURRENT_SOURCE_DIR}/src")
set(doxygen_index_file "${doxygen_output_directory}/html/index.html") set(doxygen_index_file "${doxygen_output_directory}/html/index.html")
set(doxyfile "${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile") set(doxyfile "${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile")
file( file(GLOB_RECURSE doxygen_input
GLOB_RECURSE doxygen_input docs/*.md
docs/*.md include/*.h
include/*.h include/*.cpp
include/*.cpp include/*.md
include/*.md src/*.h
src/*.h src/*.cpp
src/*.cpp src/*.md
src/*.md Builds/*.md
Builds/*.md *.md)
*.md list(APPEND doxygen_input
) external/README.md
list(APPEND doxygen_input external/README.md) )
set(dependencies "${doxygen_input}" "${doxyfile}") set(dependencies "${doxygen_input}" "${doxyfile}")
function(verbose_find_path variable name) function(verbose_find_path variable name)
# find_path sets a CACHE variable, so don't try using a "local" variable. # find_path sets a CACHE variable, so don't try using a "local" variable.
find_path(${variable} "${name}" ${ARGN}) find_path(${variable} "${name}" ${ARGN})
if(NOT ${variable}) if(NOT ${variable})
message(NOTICE "could not find ${name}") message(NOTICE "could not find ${name}")
else() else()
message(STATUS "found ${name}: ${${variable}}/${name}") message(STATUS "found ${name}: ${${variable}}/${name}")
endif() endif()
endfunction() endfunction()
verbose_find_path( verbose_find_path(doxygen_plantuml_jar_path plantuml.jar PATH_SUFFIXES share/plantuml)
doxygen_plantuml_jar_path
plantuml.jar
PATH_SUFFIXES share/plantuml
)
verbose_find_path(doxygen_dot_path dot) verbose_find_path(doxygen_dot_path dot)
# https://en.cppreference.com/w/Cppreference:Archives # https://en.cppreference.com/w/Cppreference:Archives
# https://stackoverflow.com/questions/60822559/how-to-move-a-file-download-from-configure-step-to-build-step # https://stackoverflow.com/questions/60822559/how-to-move-a-file-download-from-configure-step-to-build-step
set(download_script "${CMAKE_BINARY_DIR}/docs/download-cppreference.cmake") set(download_script "${CMAKE_BINARY_DIR}/docs/download-cppreference.cmake")
file( file(WRITE
WRITE "${download_script}" "${download_script}"
"file(DOWNLOAD \ "file(DOWNLOAD \
https://github.com/PeterFeicht/cppreference-doc/releases/download/v20250209/html-book-20250209.zip \ https://github.com/PeterFeicht/cppreference-doc/releases/download/v20250209/html-book-20250209.zip \
${CMAKE_BINARY_DIR}/docs/cppreference.zip \ ${CMAKE_BINARY_DIR}/docs/cppreference.zip \
EXPECTED_HASH MD5=bda585f72fbca4b817b29a3d5746567b \ EXPECTED_HASH MD5=bda585f72fbca4b817b29a3d5746567b \
@@ -65,27 +61,23 @@ file(
) )
set(tagfile "${CMAKE_BINARY_DIR}/docs/cppreference-doxygen-web.tag.xml") set(tagfile "${CMAKE_BINARY_DIR}/docs/cppreference-doxygen-web.tag.xml")
add_custom_command( add_custom_command(
OUTPUT "${tagfile}" OUTPUT "${tagfile}"
COMMAND "${CMAKE_COMMAND}" -P "${download_script}" COMMAND "${CMAKE_COMMAND}" -P "${download_script}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/docs" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/docs"
) )
set(doxygen_tagfiles "${tagfile}=http://en.cppreference.com/w/") set(doxygen_tagfiles "${tagfile}=http://en.cppreference.com/w/")
add_custom_command( add_custom_command(
OUTPUT "${doxygen_index_file}" OUTPUT "${doxygen_index_file}"
COMMAND COMMAND "${CMAKE_COMMAND}" -E env
"${CMAKE_COMMAND}" -E env "DOXYGEN_OUTPUT_DIRECTORY=${doxygen_output_directory}"
"DOXYGEN_OUTPUT_DIRECTORY=${doxygen_output_directory}" "DOXYGEN_INCLUDE_PATH=${doxygen_include_path}"
"DOXYGEN_INCLUDE_PATH=${doxygen_include_path}" "DOXYGEN_TAGFILES=${doxygen_tagfiles}"
"DOXYGEN_TAGFILES=${doxygen_tagfiles}" "DOXYGEN_PLANTUML_JAR_PATH=${doxygen_plantuml_jar_path}"
"DOXYGEN_PLANTUML_JAR_PATH=${doxygen_plantuml_jar_path}" "DOXYGEN_DOT_PATH=${doxygen_dot_path}"
"DOXYGEN_DOT_PATH=${doxygen_dot_path}" "${DOXYGEN_EXECUTABLE}" "${DOXYGEN_EXECUTABLE}" "${doxyfile}"
"${doxyfile}" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" DEPENDS "${dependencies}" "${tagfile}")
DEPENDS "${dependencies}" "${tagfile}" add_custom_target(docs
) DEPENDS "${doxygen_index_file}"
add_custom_target( SOURCES "${dependencies}")
docs
DEPENDS "${doxygen_index_file}"
SOURCES "${dependencies}"
)

View File

@@ -2,38 +2,79 @@
install stuff install stuff
#]===================================================================] #]===================================================================]
include(GNUInstallDirs) include(create_symbolic_link)
if(is_root_project AND TARGET xrpld) install (
install( TARGETS
TARGETS xrpld common
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT runtime opts
) xrpl_boost
xrpl_libs
install( xrpl_syslibs
FILES "${CMAKE_CURRENT_SOURCE_DIR}/cfg/xrpld-example.cfg" xrpl.imports.main
DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/xrpld" xrpl.libpb
RENAME xrpld.cfg xrpl.libxrpl
COMPONENT runtime xrpl.libxrpl.basics
) xrpl.libxrpl.beast
xrpl.libxrpl.core
install( xrpl.libxrpl.crypto
FILES "${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt" xrpl.libxrpl.json
DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/xrpld" xrpl.libxrpl.ledger
RENAME validators.txt xrpl.libxrpl.net
COMPONENT runtime xrpl.libxrpl.nodestore
) xrpl.libxrpl.protocol
endif() xrpl.libxrpl.resource
xrpl.libxrpl.server
xrpl.libxrpl.shamap
antithesis-sdk-cpp
EXPORT XrplExports
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include)
install( install(
TARGETS xrpl.libpb xrpl.libxrpl DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT development DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT development
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT development
) )
install( install (EXPORT XrplExports
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl" FILE XrplTargets.cmake
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" NAMESPACE Xrpl::
COMPONENT development DESTINATION lib/cmake/xrpl)
) include (CMakePackageConfigHelpers)
write_basic_package_version_file (
XrplConfigVersion.cmake
VERSION ${xrpld_version}
COMPATIBILITY SameMajorVersion)
if (is_root_project AND TARGET xrpld)
install (TARGETS xrpld RUNTIME DESTINATION bin)
set_target_properties(xrpld PROPERTIES INSTALL_RPATH_USE_LINK_PATH ON)
# sample configs should not overwrite existing files
# install if-not-exists workaround as suggested by
# https://cmake.org/Bug/view.php?id=12646
install(CODE "
macro (copy_if_not_exists SRC DEST NEWNAME)
if (NOT EXISTS \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${DEST}/\${NEWNAME}\")
file (INSTALL FILE_PERMISSIONS OWNER_READ OWNER_WRITE DESTINATION \"\${CMAKE_INSTALL_PREFIX}/\${DEST}\" FILES \"\${SRC}\" RENAME \"\${NEWNAME}\")
else ()
message (\"-- Skipping : \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${DEST}/\${NEWNAME}\")
endif ()
endmacro()
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/xrpld-example.cfg\" etc xrpld.cfg)
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt\" etc validators.txt)
")
install(CODE "
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
include(create_symbolic_link)
create_symbolic_link(xrpld${suffix} \
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/rippled${suffix})
")
endif ()
install (
FILES
${CMAKE_CURRENT_SOURCE_DIR}/cmake/XrplConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/XrplConfigVersion.cmake
DESTINATION lib/cmake/xrpl)

View File

@@ -4,93 +4,80 @@
include(CompilationEnv) include(CompilationEnv)
# Set defaults for optional variables to avoid uninitialized variable warnings add_library (opts INTERFACE)
if(NOT DEFINED voidstar) add_library (Xrpl::opts ALIAS opts)
set(voidstar OFF) target_compile_definitions (opts
endif() INTERFACE
BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS
BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
BOOST_CONTAINER_FWD_BAD_DEQUE
HAS_UNCAUGHT_EXCEPTIONS=1
$<$<BOOL:${boost_show_deprecated}>:
BOOST_ASIO_NO_DEPRECATED
BOOST_FILESYSTEM_NO_DEPRECATED
>
$<$<NOT:$<BOOL:${boost_show_deprecated}>>:
BOOST_COROUTINES_NO_DEPRECATION_WARNING
BOOST_BEAST_ALLOW_DEPRECATED
BOOST_FILESYSTEM_DEPRECATED
>
$<$<BOOL:${beast_no_unit_test_inline}>:BEAST_NO_UNIT_TEST_INLINE=1>
$<$<BOOL:${beast_disable_autolink}>:BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES=1>
$<$<BOOL:${single_io_service_thread}>:XRPL_SINGLE_IO_SERVICE_THREAD=1>
$<$<BOOL:${voidstar}>:ENABLE_VOIDSTAR>)
target_compile_options (opts
INTERFACE
$<$<AND:$<BOOL:${is_gcc}>,$<COMPILE_LANGUAGE:CXX>>:-Wsuggest-override>
$<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized>
$<$<BOOL:${perf}>:-fno-omit-frame-pointer>
$<$<BOOL:${profile}>:-pg>
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>)
add_library(opts INTERFACE) target_link_libraries (opts
add_library(Xrpl::opts ALIAS opts) INTERFACE
target_compile_definitions( $<$<BOOL:${profile}>:-pg>
opts $<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>)
INTERFACE
BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS
BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
BOOST_CONTAINER_FWD_BAD_DEQUE
HAS_UNCAUGHT_EXCEPTIONS=1
$<$<BOOL:${boost_show_deprecated}>:
BOOST_ASIO_NO_DEPRECATED
BOOST_FILESYSTEM_NO_DEPRECATED
>
$<$<NOT:$<BOOL:${boost_show_deprecated}>>:
BOOST_COROUTINES2_NO_DEPRECATION_WARNING
BOOST_BEAST_ALLOW_DEPRECATED
BOOST_FILESYSTEM_DEPRECATED
>
$<$<BOOL:${beast_no_unit_test_inline}>:BEAST_NO_UNIT_TEST_INLINE=1>
$<$<BOOL:${beast_disable_autolink}>:BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES=1>
$<$<BOOL:${single_io_service_thread}>:XRPL_SINGLE_IO_SERVICE_THREAD=1>
$<$<BOOL:${voidstar}>:ENABLE_VOIDSTAR>
)
target_compile_options(
opts
INTERFACE
$<$<AND:$<BOOL:${is_gcc}>,$<COMPILE_LANGUAGE:CXX>>:-Wsuggest-override>
$<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized>
$<$<BOOL:${perf}>:-fno-omit-frame-pointer>
$<$<BOOL:${profile}>:-pg>
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>
)
target_link_libraries(
opts
INTERFACE
$<$<BOOL:${profile}>:-pg>
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>
)
if(jemalloc) if(jemalloc)
find_package(jemalloc REQUIRED) find_package(jemalloc REQUIRED)
target_compile_definitions(opts INTERFACE PROFILE_JEMALLOC) target_compile_definitions(opts INTERFACE PROFILE_JEMALLOC)
target_link_libraries(opts INTERFACE jemalloc::jemalloc) target_link_libraries(opts INTERFACE jemalloc::jemalloc)
endif() endif ()
#[===================================================================[ #[===================================================================[
xrpld transitive library deps via an interface library xrpld transitive library deps via an interface library
#]===================================================================] #]===================================================================]
add_library(xrpl_syslibs INTERFACE) add_library (xrpl_syslibs INTERFACE)
add_library(Xrpl::syslibs ALIAS xrpl_syslibs) add_library (Xrpl::syslibs ALIAS xrpl_syslibs)
target_link_libraries( target_link_libraries (xrpl_syslibs
xrpl_syslibs INTERFACE
INTERFACE $<$<BOOL:${MSVC}>:
$<$<BOOL:${is_msvc}>: legacy_stdio_definitions.lib
legacy_stdio_definitions.lib Shlwapi
Shlwapi kernel32
kernel32 user32
user32 gdi32
gdi32 winspool
winspool comdlg32
comdlg32 advapi32
advapi32 shell32
shell32 ole32
ole32 oleaut32
oleaut32 uuid
uuid odbc32
odbc32 odbccp32
odbccp32 crypt32
crypt32 >
> $<$<NOT:$<BOOL:${MSVC}>>:dl>
$<$<NOT:$<BOOL:${is_msvc}>>:dl> $<$<NOT:$<OR:$<BOOL:${MSVC}>,$<BOOL:${APPLE}>>>:rt>)
$<$<NOT:$<OR:$<BOOL:${is_msvc}>,$<BOOL:${is_macos}>>>:rt>
)
if(NOT is_msvc) if (NOT MSVC)
set(THREADS_PREFER_PTHREAD_FLAG ON) set (THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads) find_package (Threads)
target_link_libraries(xrpl_syslibs INTERFACE Threads::Threads) target_link_libraries (xrpl_syslibs INTERFACE Threads::Threads)
endif() endif ()
add_library(xrpl_libs INTERFACE) add_library (xrpl_libs INTERFACE)
add_library(Xrpl::libs ALIAS xrpl_libs) add_library (Xrpl::libs ALIAS xrpl_libs)
target_link_libraries(xrpl_libs INTERFACE Xrpl::syslibs) target_link_libraries (xrpl_libs INTERFACE Xrpl::syslibs)

View File

@@ -1,309 +0,0 @@
#[===================================================================[
Protocol Autogen - Code generation for protocol wrapper classes
#]===================================================================]
# Options for code generation
option(
XRPL_NO_CODEGEN
"Disable code generation (use pre-generated files from repository)"
OFF
)
set(CODEGEN_VENV_DIR
""
CACHE PATH
"Path to Python virtual environment for code generation. If provided, automatic venv setup is skipped."
)
# Function to set up code generation for protocol_autogen module
# This runs at configure time to generate C++ wrapper classes from macro files
function(setup_protocol_autogen)
# Directory paths
set(MACRO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl/protocol/detail")
set(AUTOGEN_HEADER_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl/protocol_autogen"
)
set(AUTOGEN_TEST_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/src/tests/libxrpl/protocol_autogen"
)
set(SCRIPTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/scripts")
# Input macro files
set(TRANSACTIONS_MACRO "${MACRO_DIR}/transactions.macro")
set(LEDGER_ENTRIES_MACRO "${MACRO_DIR}/ledger_entries.macro")
set(SFIELDS_MACRO "${MACRO_DIR}/sfields.macro")
# Python scripts and templates
set(GENERATE_TX_SCRIPT "${SCRIPTS_DIR}/generate_tx_classes.py")
set(GENERATE_LEDGER_SCRIPT "${SCRIPTS_DIR}/generate_ledger_classes.py")
set(REQUIREMENTS_FILE "${SCRIPTS_DIR}/requirements.txt")
set(MACRO_PARSER_COMMON "${SCRIPTS_DIR}/macro_parser_common.py")
set(TX_TEMPLATE "${SCRIPTS_DIR}/templates/Transaction.h.mako")
set(TX_TEST_TEMPLATE "${SCRIPTS_DIR}/templates/TransactionTests.cpp.mako")
set(LEDGER_TEMPLATE "${SCRIPTS_DIR}/templates/LedgerEntry.h.mako")
set(LEDGER_TEST_TEMPLATE
"${SCRIPTS_DIR}/templates/LedgerEntryTests.cpp.mako"
)
# Check if code generation is disabled
if(XRPL_NO_CODEGEN)
message(
WARNING
"Protocol autogen: Code generation is disabled (XRPL_NO_CODEGEN=ON). "
"Generated files may be out of date."
)
return()
endif()
# Create output directories
file(MAKE_DIRECTORY "${AUTOGEN_HEADER_DIR}/transactions")
file(MAKE_DIRECTORY "${AUTOGEN_HEADER_DIR}/ledger_entries")
file(MAKE_DIRECTORY "${AUTOGEN_TEST_DIR}/ledger_entries")
file(MAKE_DIRECTORY "${AUTOGEN_TEST_DIR}/transactions")
# Find Python3 - check if already found by Conan or find it ourselves
if(NOT Python3_EXECUTABLE)
find_package(Python3 COMPONENTS Interpreter QUIET)
endif()
if(NOT Python3_EXECUTABLE)
# Try finding python3 executable directly
find_program(Python3_EXECUTABLE NAMES python3 python)
endif()
if(NOT Python3_EXECUTABLE)
message(
FATAL_ERROR
"Python3 not found. Code generation cannot proceed.\n"
"Please install Python 3, or set -DXRPL_NO_CODEGEN=ON to use existing generated files."
)
return()
endif()
message(STATUS "Using Python3 for code generation: ${Python3_EXECUTABLE}")
# Set up Python virtual environment for code generation
if(CODEGEN_VENV_DIR)
# User-provided venv - skip automatic setup
set(VENV_DIR "${CODEGEN_VENV_DIR}")
message(STATUS "Using user-provided Python venv: ${VENV_DIR}")
else()
# Use default venv in build directory
set(VENV_DIR "${CMAKE_CURRENT_BINARY_DIR}/codegen_venv")
endif()
# Determine the Python executable path in the venv
if(WIN32)
set(VENV_PYTHON "${VENV_DIR}/Scripts/python.exe")
set(VENV_PIP "${VENV_DIR}/Scripts/pip.exe")
else()
set(VENV_PYTHON "${VENV_DIR}/bin/python")
set(VENV_PIP "${VENV_DIR}/bin/pip")
endif()
# Only auto-setup venv if not user-provided
if(NOT CODEGEN_VENV_DIR)
# Check if venv needs to be created or updated
set(VENV_NEEDS_UPDATE FALSE)
if(NOT EXISTS "${VENV_PYTHON}")
set(VENV_NEEDS_UPDATE TRUE)
message(
STATUS
"Creating Python virtual environment for code generation..."
)
elseif(
"${REQUIREMENTS_FILE}"
IS_NEWER_THAN
"${VENV_DIR}/.requirements_installed"
)
set(VENV_NEEDS_UPDATE TRUE)
message(
STATUS
"Updating Python virtual environment (requirements changed)..."
)
endif()
# Create/update virtual environment if needed
if(VENV_NEEDS_UPDATE)
message(
STATUS
"Setting up Python virtual environment at ${VENV_DIR}"
)
execute_process(
COMMAND ${Python3_EXECUTABLE} -m venv "${VENV_DIR}"
RESULT_VARIABLE VENV_RESULT
ERROR_VARIABLE VENV_ERROR
)
if(NOT VENV_RESULT EQUAL 0)
message(
FATAL_ERROR
"Failed to create virtual environment: ${VENV_ERROR}"
)
endif()
# Check pip index URL configuration
execute_process(
COMMAND ${VENV_PIP} config get global.index-url
OUTPUT_VARIABLE PIP_INDEX_URL
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
# Default PyPI URL
set(DEFAULT_PIP_INDEX "https://pypi.org/simple")
# Show warning if using non-default index
if(PIP_INDEX_URL AND NOT PIP_INDEX_URL STREQUAL "")
if(NOT PIP_INDEX_URL STREQUAL DEFAULT_PIP_INDEX)
message(
WARNING
"Private pip index URL detected: ${PIP_INDEX_URL}\n"
"You may need to connect to VPN to access this URL."
)
endif()
endif()
message(STATUS "Installing Python dependencies...")
execute_process(
COMMAND ${VENV_PIP} install --upgrade pip
RESULT_VARIABLE PIP_UPGRADE_RESULT
OUTPUT_QUIET
ERROR_VARIABLE PIP_UPGRADE_ERROR
)
if(NOT PIP_UPGRADE_RESULT EQUAL 0)
message(WARNING "Failed to upgrade pip: ${PIP_UPGRADE_ERROR}")
endif()
execute_process(
COMMAND ${VENV_PIP} install -r "${REQUIREMENTS_FILE}"
RESULT_VARIABLE PIP_INSTALL_RESULT
ERROR_VARIABLE PIP_INSTALL_ERROR
)
if(NOT PIP_INSTALL_RESULT EQUAL 0)
message(
FATAL_ERROR
"Failed to install Python dependencies: ${PIP_INSTALL_ERROR}"
)
endif()
# Mark requirements as installed
file(TOUCH "${VENV_DIR}/.requirements_installed")
message(STATUS "Python virtual environment ready")
endif()
endif()
# At configure time - get list of output files for transactions
execute_process(
COMMAND
${VENV_PYTHON} "${GENERATE_TX_SCRIPT}" "${TRANSACTIONS_MACRO}"
--header-dir "${AUTOGEN_HEADER_DIR}/transactions" --test-dir
"${AUTOGEN_TEST_DIR}/transactions" --list-outputs
OUTPUT_VARIABLE TX_OUTPUT_FILES
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE TX_LIST_RESULT
ERROR_VARIABLE TX_LIST_ERROR
)
if(NOT TX_LIST_RESULT EQUAL 0)
message(
FATAL_ERROR
"Failed to list transaction output files:\n${TX_LIST_ERROR}"
)
endif()
# Convert newline-separated list to CMake list
string(REPLACE "\\" "/" TX_OUTPUT_FILES "${TX_OUTPUT_FILES}")
string(REPLACE "\n" ";" TX_OUTPUT_FILES "${TX_OUTPUT_FILES}")
# At configure time - get list of output files for ledger entries
execute_process(
COMMAND
${VENV_PYTHON} "${GENERATE_LEDGER_SCRIPT}" "${LEDGER_ENTRIES_MACRO}"
--header-dir "${AUTOGEN_HEADER_DIR}/ledger_entries" --test-dir
"${AUTOGEN_TEST_DIR}/ledger_entries" --list-outputs
OUTPUT_VARIABLE LEDGER_OUTPUT_FILES
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE LEDGER_LIST_RESULT
ERROR_VARIABLE LEDGER_LIST_ERROR
)
if(NOT LEDGER_LIST_RESULT EQUAL 0)
message(
FATAL_ERROR
"Failed to list ledger entry output files:\n${LEDGER_LIST_ERROR}"
)
endif()
# Convert newline-separated list to CMake list
string(REPLACE "\\" "/" LEDGER_OUTPUT_FILES "${LEDGER_OUTPUT_FILES}")
string(REPLACE "\n" ";" LEDGER_OUTPUT_FILES "${LEDGER_OUTPUT_FILES}")
# Custom command to generate transaction classes at build time
add_custom_command(
OUTPUT ${TX_OUTPUT_FILES}
COMMAND
${VENV_PYTHON} "${GENERATE_TX_SCRIPT}" "${TRANSACTIONS_MACRO}"
--header-dir "${AUTOGEN_HEADER_DIR}/transactions" --test-dir
"${AUTOGEN_TEST_DIR}/transactions" --sfields-macro
"${SFIELDS_MACRO}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS
"${TRANSACTIONS_MACRO}"
"${SFIELDS_MACRO}"
"${GENERATE_TX_SCRIPT}"
"${MACRO_PARSER_COMMON}"
"${TX_TEMPLATE}"
"${TX_TEST_TEMPLATE}"
"${REQUIREMENTS_FILE}"
COMMENT "Generating transaction classes from transactions.macro..."
VERBATIM
)
# Custom command to generate ledger entry classes at build time
add_custom_command(
OUTPUT ${LEDGER_OUTPUT_FILES}
COMMAND
${VENV_PYTHON} "${GENERATE_LEDGER_SCRIPT}" "${LEDGER_ENTRIES_MACRO}"
--header-dir "${AUTOGEN_HEADER_DIR}/ledger_entries" --test-dir
"${AUTOGEN_TEST_DIR}/ledger_entries" --sfields-macro
"${SFIELDS_MACRO}"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS
"${LEDGER_ENTRIES_MACRO}"
"${SFIELDS_MACRO}"
"${GENERATE_LEDGER_SCRIPT}"
"${MACRO_PARSER_COMMON}"
"${LEDGER_TEMPLATE}"
"${LEDGER_TEST_TEMPLATE}"
"${REQUIREMENTS_FILE}"
COMMENT "Generating ledger entry classes from ledger_entries.macro..."
VERBATIM
)
# Create a custom target that depends on all generated files
add_custom_target(
protocol_autogen_generate
DEPENDS ${TX_OUTPUT_FILES} ${LEDGER_OUTPUT_FILES}
COMMENT "Protocol autogen code generation"
)
# Extract test files from output lists (files ending in Tests.cpp)
set(PROTOCOL_AUTOGEN_TEST_SOURCES "")
foreach(FILE ${TX_OUTPUT_FILES} ${LEDGER_OUTPUT_FILES})
if(FILE MATCHES "Tests\\.cpp$")
list(APPEND PROTOCOL_AUTOGEN_TEST_SOURCES "${FILE}")
endif()
endforeach()
# Export test sources to parent scope for use in test CMakeLists.txt
set(PROTOCOL_AUTOGEN_TEST_SOURCES
"${PROTOCOL_AUTOGEN_TEST_SOURCES}"
CACHE INTERNAL
"Generated protocol_autogen test sources"
)
# Register dependencies so CMake reconfigures when macro files change
# (to update the list of output files)
set_property(
DIRECTORY
APPEND
PROPERTY
CMAKE_CONFIGURE_DEPENDS
"${TRANSACTIONS_MACRO}"
"${LEDGER_ENTRIES_MACRO}"
)
endfunction()

View File

@@ -43,10 +43,7 @@
include(CompilationEnv) include(CompilationEnv)
# Read environment variable # Read environment variable
set(SANITIZERS "") set(SANITIZERS $ENV{SANITIZERS})
if(DEFINED ENV{SANITIZERS})
set(SANITIZERS "$ENV{SANITIZERS}")
endif()
# Set SANITIZERS_ENABLED flag for use in other modules # Set SANITIZERS_ENABLED flag for use in other modules
if(SANITIZERS MATCHES "address|thread|undefinedbehavior") if(SANITIZERS MATCHES "address|thread|undefinedbehavior")
@@ -58,11 +55,8 @@ endif()
# Sanitizers are not supported on Windows/MSVC # Sanitizers are not supported on Windows/MSVC
if(is_msvc) if(is_msvc)
message( message(FATAL_ERROR "Sanitizers are not supported on Windows/MSVC. "
FATAL_ERROR "Please unset the SANITIZERS environment variable.")
"Sanitizers are not supported on Windows/MSVC. "
"Please unset the SANITIZERS environment variable."
)
endif() endif()
message(STATUS "Configuring sanitizers: ${SANITIZERS}") message(STATUS "Configuring sanitizers: ${SANITIZERS}")
@@ -85,21 +79,15 @@ foreach(san IN LISTS san_list)
elseif(san STREQUAL "undefinedbehavior") elseif(san STREQUAL "undefinedbehavior")
set(enable_ubsan TRUE) set(enable_ubsan TRUE)
else() else()
message( message(FATAL_ERROR "Unsupported sanitizer type: ${san}"
FATAL_ERROR "Supported: address, thread, undefinedbehavior and their combinations.")
"Unsupported sanitizer type: ${san}"
"Supported: address, thread, undefinedbehavior and their combinations."
)
endif() endif()
endforeach() endforeach()
# Validate sanitizer compatibility # Validate sanitizer compatibility
if(enable_asan AND enable_tsan) if(enable_asan AND enable_tsan)
message( message(FATAL_ERROR "AddressSanitizer and ThreadSanitizer are incompatible and cannot be enabled simultaneously. "
FATAL_ERROR "Use 'address' or 'thread', optionally with 'undefinedbehavior'.")
"AddressSanitizer and ThreadSanitizer are incompatible and cannot be enabled simultaneously. "
"Use 'address' or 'thread', optionally with 'undefinedbehavior'."
)
endif() endif()
# Frame pointer is required for meaningful stack traces. Sanitizers recommend minimum of -O1 for reasonable performance # Frame pointer is required for meaningful stack traces. Sanitizers recommend minimum of -O1 for reasonable performance
@@ -118,28 +106,25 @@ if(enable_ubsan)
# UB sanitizer flags # UB sanitizer flags
list(APPEND SANITIZER_TYPES "undefined" "float-divide-by-zero") list(APPEND SANITIZER_TYPES "undefined" "float-divide-by-zero")
if(is_clang) if(is_clang)
# Clang supports additional UB checks. More info here # Clang supports additional UB checks. More info here https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
# https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
list(APPEND SANITIZER_TYPES "unsigned-integer-overflow") list(APPEND SANITIZER_TYPES "unsigned-integer-overflow")
endif() endif()
endif() endif()
# Configure code model for GCC on amd64 Use large code model for ASAN to avoid relocation errors Use medium code model # Configure code model for GCC on amd64
# for TSAN (large is not compatible with TSAN) # Use large code model for ASAN to avoid relocation errors
# Use medium code model for TSAN (large is not compatible with TSAN)
set(SANITIZERS_RELOCATION_FLAGS) set(SANITIZERS_RELOCATION_FLAGS)
# Compiler-specific configuration # Compiler-specific configuration
if(is_gcc) if(is_gcc)
# Disable mold, gold and lld linkers for GCC with sanitizers Use default linker (bfd/ld) which is more lenient with # Disable mold, gold and lld linkers for GCC with sanitizers
# mixed code models This is needed since the size of instrumented binary exceeds the limits set by mold, lld and # Use default linker (bfd/ld) which is more lenient with mixed code models
# gold linkers # This is needed since the size of instrumented binary exceeds the limits set by mold, lld and gold linkers
set(use_mold OFF CACHE BOOL "Use mold linker" FORCE) set(use_mold OFF CACHE BOOL "Use mold linker" FORCE)
set(use_gold OFF CACHE BOOL "Use gold linker" FORCE) set(use_gold OFF CACHE BOOL "Use gold linker" FORCE)
set(use_lld OFF CACHE BOOL "Use lld linker" FORCE) set(use_lld OFF CACHE BOOL "Use lld linker" FORCE)
message( message(STATUS " Disabled mold, gold, and lld linkers for GCC with sanitizers")
STATUS
" Disabled mold, gold, and lld linkers for GCC with sanitizers"
)
# Suppress false positive warnings in GCC with stringop-overflow # Suppress false positive warnings in GCC with stringop-overflow
list(APPEND SANITIZERS_COMPILE_FLAGS "-Wno-stringop-overflow") list(APPEND SANITIZERS_COMPILE_FLAGS "-Wno-stringop-overflow")
@@ -161,26 +146,17 @@ if(is_gcc)
# Add sanitizer to compile and link flags # Add sanitizer to compile and link flags
list(APPEND SANITIZERS_COMPILE_FLAGS "-fsanitize=${SANITIZER_TYPES_STR}") list(APPEND SANITIZERS_COMPILE_FLAGS "-fsanitize=${SANITIZER_TYPES_STR}")
set(SANITIZERS_LINK_FLAGS set(SANITIZERS_LINK_FLAGS "${SANITIZERS_RELOCATION_FLAGS}" "-fsanitize=${SANITIZER_TYPES_STR}")
"${SANITIZERS_RELOCATION_FLAGS}"
"-fsanitize=${SANITIZER_TYPES_STR}"
)
elseif(is_clang) elseif(is_clang)
# Add ignorelist for Clang (GCC doesn't support this) Use CMAKE_SOURCE_DIR to get the path to the ignorelist # Add ignorelist for Clang (GCC doesn't support this)
set(IGNORELIST_PATH # Use CMAKE_SOURCE_DIR to get the path to the ignorelist
"${CMAKE_SOURCE_DIR}/sanitizers/suppressions/sanitizer-ignorelist.txt" set(IGNORELIST_PATH "${CMAKE_SOURCE_DIR}/sanitizers/suppressions/sanitizer-ignorelist.txt")
)
if(NOT EXISTS "${IGNORELIST_PATH}") if(NOT EXISTS "${IGNORELIST_PATH}")
message( message(FATAL_ERROR "Sanitizer ignorelist not found: ${IGNORELIST_PATH}")
FATAL_ERROR
"Sanitizer ignorelist not found: ${IGNORELIST_PATH}"
)
endif() endif()
list( list(APPEND SANITIZERS_COMPILE_FLAGS "-fsanitize-ignorelist=${IGNORELIST_PATH}")
APPEND SANITIZERS_COMPILE_FLAGS
"-fsanitize-ignorelist=${IGNORELIST_PATH}"
)
message(STATUS " Using sanitizer ignorelist: ${IGNORELIST_PATH}") message(STATUS " Using sanitizer ignorelist: ${IGNORELIST_PATH}")
# Join sanitizer flags with commas for -fsanitize option # Join sanitizer flags with commas for -fsanitize option
@@ -194,12 +170,11 @@ endif()
message(STATUS " Compile flags: ${SANITIZERS_COMPILE_FLAGS}") message(STATUS " Compile flags: ${SANITIZERS_COMPILE_FLAGS}")
message(STATUS " Link flags: ${SANITIZERS_LINK_FLAGS}") message(STATUS " Link flags: ${SANITIZERS_LINK_FLAGS}")
# Apply the sanitizer flags to the 'common' interface library This is the same library used by XrplCompiler.cmake # Apply the sanitizer flags to the 'common' interface library
target_compile_options( # This is the same library used by XrplCompiler.cmake
common target_compile_options(common INTERFACE
INTERFACE $<$<COMPILE_LANGUAGE:CXX>:${SANITIZERS_COMPILE_FLAGS}>
$<$<COMPILE_LANGUAGE:CXX>:${SANITIZERS_COMPILE_FLAGS}> $<$<COMPILE_LANGUAGE:C>:${SANITIZERS_COMPILE_FLAGS}>
$<$<COMPILE_LANGUAGE:C>:${SANITIZERS_COMPILE_FLAGS}>
) )
# Apply linker flags # Apply linker flags

View File

@@ -6,57 +6,40 @@ include(CompilationEnv)
get_property(is_multiconfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) get_property(is_multiconfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE) set (CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE)
if(NOT is_multiconfig) if (NOT is_multiconfig)
if(NOT CMAKE_BUILD_TYPE) if (NOT CMAKE_BUILD_TYPE)
message(STATUS "Build type not specified - defaulting to Release") message (STATUS "Build type not specified - defaulting to Release")
set(CMAKE_BUILD_TYPE Release CACHE STRING "build type" FORCE) set (CMAKE_BUILD_TYPE Release CACHE STRING "build type" FORCE)
elseif( elseif (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL Release))
NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL Release) # for simplicity, these are the only two config types we care about. Limiting
) # the build types simplifies dealing with external project builds especially
# for simplicity, these are the only two config types we care about. Limiting the build types simplifies dealing message (FATAL_ERROR " *** Only Debug or Release build types are currently supported ***")
# with external project builds especially endif ()
message( endif ()
FATAL_ERROR
" *** Only Debug or Release build types are currently supported ***"
)
endif()
endif()
if(is_clang) # both Clang and AppleClang if (is_clang) # both Clang and AppleClang
if( if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0)
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0 message (FATAL_ERROR "This project requires clang 16 or later")
) endif ()
message(FATAL_ERROR "This project requires clang 16 or later") elseif (is_gcc)
endif() if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
elseif(is_gcc) message (FATAL_ERROR "This project requires GCC 12 or later")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0) endif ()
message(FATAL_ERROR "This project requires GCC 12 or later") endif ()
endif()
endif()
# check for in-source build and fail # check for in-source build and fail
if("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
message( message (FATAL_ERROR "Builds (in-source) are not allowed in "
FATAL_ERROR "${CMAKE_CURRENT_SOURCE_DIR}. Please remove CMakeCache.txt and the CMakeFiles "
"Builds (in-source) are not allowed in " "directory from ${CMAKE_CURRENT_SOURCE_DIR} and try building in a separate directory.")
"${CMAKE_CURRENT_SOURCE_DIR}. Please remove CMakeCache.txt and the CMakeFiles " endif ()
"directory from ${CMAKE_CURRENT_SOURCE_DIR} and try building in a separate directory."
)
endif()
if(MSVC AND CMAKE_GENERATOR_PLATFORM STREQUAL "Win32") if (MSVC AND CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
message(FATAL_ERROR "Visual Studio 32-bit build is not supported.") message (FATAL_ERROR "Visual Studio 32-bit build is not supported.")
endif() endif ()
if(voidstar AND NOT is_amd64) if (APPLE AND NOT HOMEBREW)
message( find_program (HOMEBREW brew)
FATAL_ERROR endif ()
"The voidstar library only supported on amd64/x86_64. Detected archictecture was: ${CMAKE_SYSTEM_PROCESSOR}"
)
endif()
if(APPLE AND NOT HOMEBREW)
find_program(HOMEBREW brew)
endif()

View File

@@ -4,18 +4,17 @@
include(CompilationEnv) include(CompilationEnv)
set(is_ci FALSE) if("$ENV{CI}" STREQUAL "true" OR "$ENV{CONTINUOUS_INTEGRATION}" STREQUAL "true")
if(DEFINED ENV{CI}) set(is_ci TRUE)
if("$ENV{CI}" STREQUAL "true") else()
set(is_ci TRUE) set(is_ci FALSE)
endif()
endif() endif()
get_directory_property(has_parent PARENT_DIRECTORY) get_directory_property(has_parent PARENT_DIRECTORY)
if(has_parent) if(has_parent)
set(is_root_project OFF) set(is_root_project OFF)
else() else()
set(is_root_project ON) set(is_root_project ON)
endif() endif()
option(assert "Enables asserts, even in release builds" OFF) option(assert "Enables asserts, even in release builds" OFF)
@@ -24,132 +23,106 @@ option(xrpld "Build xrpld" ON)
option(tests "Build tests" ON) option(tests "Build tests" ON)
if(tests) if(tests)
# This setting allows making a separate workflow to test fees other than default 10 # This setting allows making a separate workflow to test fees other than default 10
if(NOT UNIT_TEST_REFERENCE_FEE) if(NOT UNIT_TEST_REFERENCE_FEE)
set(UNIT_TEST_REFERENCE_FEE "10" CACHE STRING "") set(UNIT_TEST_REFERENCE_FEE "10" CACHE STRING "")
endif() endif()
endif() endif()
option(unity "Creates a build using UNITY support in cmake." OFF) option(unity "Creates a build using UNITY support in cmake." OFF)
if(unity) if(unity)
if(NOT is_ci) if(NOT is_ci)
set(CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "") set(CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "")
endif() endif()
set(CMAKE_UNITY_BUILD ON CACHE BOOL "Do a unity build") set(CMAKE_UNITY_BUILD ON CACHE BOOL "Do a unity build")
endif() endif()
if(is_clang AND is_linux) if(is_clang AND is_linux)
option(voidstar "Enable Antithesis instrumentation." OFF) option(voidstar "Enable Antithesis instrumentation." OFF)
endif() endif()
if(is_gcc OR is_clang) if(is_gcc OR is_clang)
include(ProcessorCount) include(ProcessorCount)
ProcessorCount(PROCESSOR_COUNT) ProcessorCount(PROCESSOR_COUNT)
option(coverage "Generates coverage info." OFF) option(coverage "Generates coverage info." OFF)
option(profile "Add profiling flags" OFF) option(profile "Add profiling flags" OFF)
set(coverage_format set(coverage_format "html-details" CACHE STRING
"html-details" "Output format of the coverage report.")
CACHE STRING set(coverage_extra_args "" CACHE STRING
"Output format of the coverage report." "Additional arguments to pass to gcovr.")
) option(wextra "compile with extra gcc/clang warnings enabled" ON)
set(coverage_extra_args
""
CACHE STRING
"Additional arguments to pass to gcovr."
)
option(wextra "compile with extra gcc/clang warnings enabled" ON)
else() else()
set(profile OFF CACHE BOOL "gcc/clang only" FORCE) set(profile OFF CACHE BOOL "gcc/clang only" FORCE)
set(coverage OFF CACHE BOOL "gcc/clang only" FORCE) set(coverage OFF CACHE BOOL "gcc/clang only" FORCE)
set(wextra OFF CACHE BOOL "gcc/clang only" FORCE) set(wextra OFF CACHE BOOL "gcc/clang only" FORCE)
endif() endif()
if(is_linux AND NOT SANITIZER) if(is_linux AND NOT SANITIZER)
option(BUILD_SHARED_LIBS "build shared xrpl libraries" OFF) option(BUILD_SHARED_LIBS "build shared xrpl libraries" OFF)
option(static "link protobuf, openssl, libc++, and boost statically" ON) option(static "link protobuf, openssl, libc++, and boost statically" ON)
option(perf "Enables flags that assist with perf recording" OFF) option(perf "Enables flags that assist with perf recording" OFF)
option(use_gold "enables detection of gold (binutils) linker" ON) option(use_gold "enables detection of gold (binutils) linker" ON)
option(use_mold "enables detection of mold (binutils) linker" ON) option(use_mold "enables detection of mold (binutils) linker" ON)
# Set a default value for the log flag based on the build type. This provides a sensible default (on for debug, off # Set a default value for the log flag based on the build type.
# for release) while still allowing the user to override it for any build. # This provides a sensible default (on for debug, off for release)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") # while still allowing the user to override it for any build.
set(TRUNCATED_LOGS_DEFAULT ON) if(CMAKE_BUILD_TYPE STREQUAL "Debug")
else() set(TRUNCATED_LOGS_DEFAULT ON)
set(TRUNCATED_LOGS_DEFAULT OFF) else()
endif() set(TRUNCATED_LOGS_DEFAULT OFF)
option( endif()
TRUNCATED_THREAD_NAME_LOGS option(TRUNCATED_THREAD_NAME_LOGS
"Show warnings about truncated thread names on Linux." "Show warnings about truncated thread names on Linux."
${TRUNCATED_LOGS_DEFAULT} ${TRUNCATED_LOGS_DEFAULT}
) )
if(TRUNCATED_THREAD_NAME_LOGS) if(TRUNCATED_THREAD_NAME_LOGS)
add_compile_definitions(TRUNCATED_THREAD_NAME_LOGS) add_compile_definitions(TRUNCATED_THREAD_NAME_LOGS)
endif() endif()
else() else()
# we are not ready to allow shared-libs on windows because it would require export declarations. On macos it's more # we are not ready to allow shared-libs on windows because it would require
# feasible, but static openssl produces odd linker errors, thus we disable shared lib builds for now. # export declarations. On macos it's more feasible, but static openssl
set(BUILD_SHARED_LIBS # produces odd linker errors, thus we disable shared lib builds for now.
OFF set(BUILD_SHARED_LIBS OFF CACHE BOOL "build shared xrpl libraries - OFF for win/macos" FORCE)
CACHE BOOL set(static ON CACHE BOOL "static link, linux only. ON for WIN/macos" FORCE)
"build shared xrpl libraries - OFF for win/macos" set(perf OFF CACHE BOOL "perf flags, linux only" FORCE)
FORCE set(use_gold OFF CACHE BOOL "gold linker, linux only" FORCE)
) set(use_mold OFF CACHE BOOL "mold linker, linux only" FORCE)
set(static ON CACHE BOOL "static link, linux only. ON for WIN/macos" FORCE)
set(perf OFF CACHE BOOL "perf flags, linux only" FORCE)
set(use_gold OFF CACHE BOOL "gold linker, linux only" FORCE)
set(use_mold OFF CACHE BOOL "mold linker, linux only" FORCE)
endif() endif()
if(is_clang) if(is_clang)
option(use_lld "enables detection of lld linker" ON) option(use_lld "enables detection of lld linker" ON)
else() else()
set(use_lld OFF CACHE BOOL "try lld linker, clang only" FORCE) set(use_lld OFF CACHE BOOL "try lld linker, clang only" FORCE)
endif() endif()
option(jemalloc "Enables jemalloc for heap profiling" OFF) option(jemalloc "Enables jemalloc for heap profiling" OFF)
option(werr "treat warnings as errors" OFF) option(werr "treat warnings as errors" OFF)
option( option(local_protobuf
local_protobuf "Force a local build of protobuf instead of looking for an installed version." OFF)
"Force a local build of protobuf instead of looking for an installed version." option(local_grpc
OFF "Force a local build of gRPC instead of looking for an installed version." OFF)
)
option(
local_grpc
"Force a local build of gRPC instead of looking for an installed version."
OFF
)
# the remaining options are obscure and rarely used # the remaining options are obscure and rarely used
option( option(beast_no_unit_test_inline
beast_no_unit_test_inline "Prevents unit test definitions from being inserted into global table"
"Prevents unit test definitions from being inserted into global table" OFF)
OFF option(single_io_service_thread
) "Restricts the number of threads calling io_context::run to one. \
option(
single_io_service_thread
"Restricts the number of threads calling io_context::run to one. \
This can be useful when debugging." This can be useful when debugging."
OFF OFF)
) option(boost_show_deprecated
option( "Allow boost to fail on deprecated usage. Only useful if you're trying\
boost_show_deprecated
"Allow boost to fail on deprecated usage. Only useful if you're trying\
to find deprecated calls." to find deprecated calls."
OFF OFF)
)
if(WIN32) if(WIN32)
option( option(beast_disable_autolink "Disables autolinking of system libraries on WIN32" OFF)
beast_disable_autolink
"Disables autolinking of system libraries on WIN32"
OFF
)
else() else()
set(beast_disable_autolink OFF CACHE BOOL "WIN32 only" FORCE) set(beast_disable_autolink OFF CACHE BOOL "WIN32 only" FORCE)
endif() endif()
if(coverage) if(coverage)
message(STATUS "coverage build requested - forcing Debug build") message(STATUS "coverage build requested - forcing Debug build")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "build type" FORCE) set(CMAKE_BUILD_TYPE Debug CACHE STRING "build type" FORCE)
endif() endif()

View File

@@ -1,26 +1,20 @@
option( option (validator_keys "Enables building of validator-keys tool as a separate target (imported via FetchContent)" OFF)
if (validator_keys)
git_branch (current_branch)
# default to tracking VK master branch unless we are on release
if (NOT (current_branch STREQUAL "release"))
set (current_branch "master")
endif ()
message (STATUS "Tracking ValidatorKeys branch: ${current_branch}")
FetchContent_Declare (
validator_keys validator_keys
"Enables building of validator-keys tool as a separate target (imported via FetchContent)" GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git
OFF GIT_TAG "${current_branch}"
) )
FetchContent_MakeAvailable(validator_keys)
set_target_properties(validator-keys PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
if(validator_keys) endif ()
git_branch(current_branch)
# default to tracking VK master branch unless we are on release
if(NOT (current_branch STREQUAL "release"))
set(current_branch "master")
endif()
message(STATUS "Tracking ValidatorKeys branch: ${current_branch}")
FetchContent_Declare(
validator_keys
GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git
GIT_TAG "${current_branch}"
)
FetchContent_MakeAvailable(validator_keys)
set_target_properties(
validator-keys
PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()

View File

@@ -4,12 +4,12 @@
file(STRINGS src/libxrpl/protocol/BuildInfo.cpp BUILD_INFO) file(STRINGS src/libxrpl/protocol/BuildInfo.cpp BUILD_INFO)
foreach(line_ ${BUILD_INFO}) foreach(line_ ${BUILD_INFO})
if(line_ MATCHES "versionString[ ]*=[ ]*\"(.+)\"") if(line_ MATCHES "versionString[ ]*=[ ]*\"(.+)\"")
set(xrpld_version ${CMAKE_MATCH_1}) set(xrpld_version ${CMAKE_MATCH_1})
endif() endif()
endforeach() endforeach()
if(xrpld_version) if(xrpld_version)
message(STATUS "xrpld version: ${xrpld_version}") message(STATUS "xrpld version: ${xrpld_version}")
else() else()
message(FATAL_ERROR "unable to determine xrpld version") message(FATAL_ERROR "unable to determine xrpld version")
endif() endif()

View File

@@ -13,28 +13,25 @@ include(isolate_headers)
# add_module(parent b) # add_module(parent b)
# target_link_libraries(project.libparent.b PUBLIC project.libparent.a) # target_link_libraries(project.libparent.b PUBLIC project.libparent.a)
function(add_module parent name) function(add_module parent name)
set(target ${PROJECT_NAME}.lib${parent}.${name}) set(target ${PROJECT_NAME}.lib${parent}.${name})
add_library(${target} OBJECT) add_library(${target} OBJECT)
file( file(GLOB_RECURSE sources CONFIGURE_DEPENDS
GLOB_RECURSE sources "${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}/*.cpp"
CONFIGURE_DEPENDS )
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}/*.cpp" target_sources(${target} PRIVATE ${sources})
) target_include_directories(${target} PUBLIC
target_sources(${target} PRIVATE ${sources}) "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
target_include_directories( )
${target} isolate_headers(
PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" ${target}
) "${CMAKE_CURRENT_SOURCE_DIR}/include"
isolate_headers( "${CMAKE_CURRENT_SOURCE_DIR}/include/${parent}/${name}"
${target} PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/include" )
"${CMAKE_CURRENT_SOURCE_DIR}/include/${parent}/${name}" isolate_headers(
PUBLIC ${target}
) "${CMAKE_CURRENT_SOURCE_DIR}/src"
isolate_headers( "${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}"
${target} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src" )
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}"
PRIVATE
)
endfunction() endfunction()

View File

@@ -1,21 +1,20 @@
# file(CREATE_SYMLINK) only works on Windows with administrator privileges. https://stackoverflow.com/a/61244115/618906 # file(CREATE_SYMLINK) only works on Windows with administrator privileges.
# https://stackoverflow.com/a/61244115/618906
function(create_symbolic_link target link) function(create_symbolic_link target link)
if(WIN32) if(WIN32)
if(NOT IS_SYMLINK "${link}")
if(NOT IS_ABSOLUTE "${target}")
# Relative links work do not work on Windows.
set(target "${link}/../${target}")
endif()
file(TO_NATIVE_PATH "${target}" target)
file(TO_NATIVE_PATH "${link}" link)
execute_process(
COMMAND cmd.exe /c mklink /J "${link}" "${target}"
)
endif()
else()
file(CREATE_LINK "${target}" "${link}" SYMBOLIC)
endif()
if(NOT IS_SYMLINK "${link}") if(NOT IS_SYMLINK "${link}")
message(ERROR "failed to create symlink: <${link}>") if(NOT IS_ABSOLUTE "${target}")
# Relative links work do not work on Windows.
set(target "${link}/../${target}")
endif()
file(TO_NATIVE_PATH "${target}" target)
file(TO_NATIVE_PATH "${link}" link)
execute_process(COMMAND cmd.exe /c mklink /J "${link}" "${target}")
endif() endif()
else()
file(CREATE_LINK "${target}" "${link}" SYMBOLIC)
endif()
if(NOT IS_SYMLINK "${link}")
message(ERROR "failed to create symlink: <${link}>")
endif()
endfunction() endfunction()

View File

@@ -1,63 +1,50 @@
include(CompilationEnv) include(CompilationEnv)
include(XrplSanitizers) include(XrplSanitizers)
find_package( find_package(Boost REQUIRED
Boost COMPONENTS
REQUIRED chrono
COMPONENTS container
chrono coroutine
container date_time
context filesystem
date_time json
filesystem program_options
json regex
program_options system
regex thread
system
thread
) )
add_library(xrpl_boost INTERFACE) add_library(xrpl_boost INTERFACE)
add_library(Xrpl::boost ALIAS xrpl_boost) add_library(Xrpl::boost ALIAS xrpl_boost)
target_link_libraries( target_link_libraries(xrpl_boost
xrpl_boost INTERFACE
INTERFACE Boost::headers
Boost::headers Boost::chrono
Boost::chrono Boost::container
Boost::container Boost::coroutine
Boost::context Boost::date_time
Boost::date_time Boost::filesystem
Boost::filesystem Boost::json
Boost::json Boost::process
Boost::process Boost::program_options
Boost::program_options Boost::regex
Boost::regex Boost::system
Boost::thread Boost::thread)
)
if(Boost_COMPILER) if(Boost_COMPILER)
target_link_libraries(xrpl_boost INTERFACE Boost::disable_autolinking) target_link_libraries(xrpl_boost INTERFACE Boost::disable_autolinking)
endif() endif()
if(SANITIZERS_ENABLED AND is_clang)
# GCC 14+ has a false positive -Wuninitialized warning in Boost.Coroutine2's # TODO: gcc does not support -fsanitize-blacklist...can we do something else
# state.hpp when compiled with -O3. This is due to GCC's intentional behavior # for gcc ?
# change (Bug #98871, #119388) where warnings from inlined system header code if(NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)
# are no longer suppressed by -isystem. The warning occurs in operator|= in get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
# boost/coroutine2/detail/state.hpp when inlined from push_control_block::destroy(). endif()
# See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119388 message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist")
if(is_gcc AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 14) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt "src:${Boost_INCLUDE_DIRS}/*")
target_compile_options(xrpl_boost INTERFACE -Wno-uninitialized) target_compile_options(opts
endif() INTERFACE
# ignore boost headers for sanitizing
# Boost.Context's ucontext backend has ASAN fiber-switching annotations -fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt)
# (start/finish_switch_fiber) that are compiled in when BOOST_USE_ASAN is defined.
# This tells ASAN about coroutine stack switches, preventing false positive
# stack-use-after-scope errors. BOOST_USE_UCONTEXT ensures the ucontext backend
# is selected (fcontext does not support ASAN annotations).
# These defines must match what Boost was compiled with (see conan/profiles/sanitizers).
if(enable_asan)
target_compile_definitions(
xrpl_boost
INTERFACE BOOST_USE_ASAN BOOST_USE_UCONTEXT
)
endif() endif()

View File

@@ -38,11 +38,11 @@ include(create_symbolic_link)
# #
# isolate_headers(target A B scope) # isolate_headers(target A B scope)
function(isolate_headers target A B scope) function(isolate_headers target A B scope)
file(RELATIVE_PATH C "${A}" "${B}") file(RELATIVE_PATH C "${A}" "${B}")
set(X "${CMAKE_CURRENT_BINARY_DIR}/modules/${target}") set(X "${CMAKE_CURRENT_BINARY_DIR}/modules/${target}")
set(Y "${X}/${C}") set(Y "${X}/${C}")
cmake_path(GET Y PARENT_PATH parent) cmake_path(GET Y PARENT_PATH parent)
file(MAKE_DIRECTORY "${parent}") file(MAKE_DIRECTORY "${parent}")
create_symbolic_link("${B}" "${Y}") create_symbolic_link("${B}" "${Y}")
target_include_directories(${target} ${scope} "$<BUILD_INTERFACE:${X}>") target_include_directories(${target} ${scope} "$<BUILD_INTERFACE:${X}>")
endfunction() endfunction()

View File

@@ -7,21 +7,18 @@
# add_library(project.libparent) # add_library(project.libparent)
# target_link_modules(parent PUBLIC a b) # target_link_modules(parent PUBLIC a b)
function(target_link_modules parent scope) function(target_link_modules parent scope)
set(library ${PROJECT_NAME}.lib${parent}) set(library ${PROJECT_NAME}.lib${parent})
foreach(name ${ARGN}) foreach(name ${ARGN})
set(module ${library}.${name}) set(module ${library}.${name})
get_target_property(sources ${library} SOURCES) get_target_property(sources ${library} SOURCES)
list(LENGTH sources before) list(LENGTH sources before)
get_target_property(dupes ${module} SOURCES) get_target_property(dupes ${module} SOURCES)
list(LENGTH dupes expected) list(LENGTH dupes expected)
list(REMOVE_ITEM sources ${dupes}) list(REMOVE_ITEM sources ${dupes})
list(LENGTH sources after) list(LENGTH sources after)
math(EXPR actual "${before} - ${after}") math(EXPR actual "${before} - ${after}")
message( message(STATUS "${module} with ${expected} sources took ${actual} sources from ${library}")
STATUS set_target_properties(${library} PROPERTIES SOURCES "${sources}")
"${module} with ${expected} sources took ${actual} sources from ${library}" target_link_libraries(${library} ${scope} ${module})
) endforeach()
set_target_properties(${library} PROPERTIES SOURCES "${sources}")
target_link_libraries(${library} ${scope} ${module})
endforeach()
endfunction() endfunction()

View File

@@ -36,30 +36,27 @@ find_package(Protobuf REQUIRED)
# ARGN: # ARGN:
# A list of .proto files. # A list of .proto files.
function(target_protobuf_sources target prefix) function(target_protobuf_sources target prefix)
set(dir "${CMAKE_CURRENT_BINARY_DIR}/pb-${target}") set(dir "${CMAKE_CURRENT_BINARY_DIR}/pb-${target}")
file(MAKE_DIRECTORY "${dir}/${prefix}") file(MAKE_DIRECTORY "${dir}/${prefix}")
protobuf_generate( protobuf_generate(
TARGET ${target} TARGET ${target}
PROTOC_OUT_DIR "${dir}/${prefix}" PROTOC_OUT_DIR "${dir}/${prefix}"
"${ARGN}" "${ARGN}"
) )
target_include_directories( target_include_directories(${target} SYSTEM PUBLIC
${target} # Allows #include <package/path/to/file.proto> used by consumer files.
SYSTEM $<BUILD_INTERFACE:${dir}>
PUBLIC # Allows #include <package/path/to/file.proto> used by consumer files. # Allows #include "path/to/file.proto" used by generated files.
$<BUILD_INTERFACE:${dir}> $<BUILD_INTERFACE:${dir}/${prefix}>
# Allows #include "path/to/file.proto" used by generated files. # Allows #include <package/path/to/file.proto> used by consumer files.
$<BUILD_INTERFACE:${dir}/${prefix}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
# Allows #include <package/path/to/file.proto> used by consumer files. # Allows #include "path/to/file.proto" used by generated files.
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${prefix}>
# Allows #include "path/to/file.proto" used by generated files. )
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${prefix}> install(
) DIRECTORY ${dir}/
install( DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
DIRECTORY ${dir}/ FILES_MATCHING PATTERN "*.h"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
FILES_MATCHING
PATTERN "*.h"
)
endfunction() endfunction()

View File

@@ -1,60 +1,58 @@
{ {
"version": "0.5", "version": "0.5",
"requires": [ "requires": [
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809", "zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987", "xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
"sqlite3/3.51.0#66aa11eabd0e34954c5c1c061ad44abe%1774467355.988", "sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1765850149.926",
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231", "soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1765850149.46",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878", "snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
"secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329", "secp256k1/0.7.0#9c4ab67bdc3860c16ea5b36aed8f74ea%1765850147.928",
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1765850186.86", "rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1765850186.86",
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1774398111.888", "re2/20230301#ca3b241baec15bd31ea9187150e0b333%1765850148.103",
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12", "protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038",
"openssl/3.6.1#e6399de266349245a4542fc5f6c71552%1774458290.139", "openssl/3.5.4#1b986e61b38fdfda3b40bebc1b234393%1768312656.257",
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1774883011.384", "nudb/2.0.9#fb8dfd1a5557f5e0528114c2da17721e%1765850143.957",
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914", "lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492", "libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492",
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03", "libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03",
"libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1765850144.736", "libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1765850144.736",
"jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244", "jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244",
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152", "gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152",
"grpc/1.78.1#b1a9e74b145cc471bed4dc64dc6eb2c1%1774467387.342", "grpc/1.72.0#f244a57bff01e708c55a1100b12e1589%1765850193.734",
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772", "ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772",
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772", "date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772",
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681", "c-ares/1.34.5#5581c2b62a608b40bb85d965ab3ec7c8%1765850144.336",
"bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837", "bzip2/1.0.8#c470882369c2d95c5c77e970c0c7e321%1765850143.837",
"boost/1.90.0#d5e8defe7355494953be18524a7f135b%1769454080.269", "boost/1.88.0#8852c0b72ce8271fb8ff7c53456d4983%1765850172.862",
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196" "abseil/20250127.0#99262a368bd01c0ccca8790dfced9719%1766517936.993"
], ],
"build_requires": [ "build_requires": [
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809", "zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76%1765850150.075",
"strawberryperl/5.32.1.1#8d114504d172cfea8ea1662d09b6333e%1774447376.964", "strawberryperl/5.32.1.1#707032463aa0620fa17ec0d887f5fe41%1765850165.196",
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12", "protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038",
"nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707", "nasm/2.16.01#31e26f2ee3c4346ecd347911bd126904%1765850144.707",
"msys2/cci.latest#d22fe7b2808f5fd34d0a7923ace9c54f%1770657326.649", "msys2/cci.latest#1996656c3c98e5765b25b60ff5cf77b4%1764840888.758",
"m4/1.4.19#5d7a4994e5875d76faf7acf3ed056036%1774365463.87", "m4/1.4.19#70dc8bbb33e981d119d2acc0175cf381%1763158052.846",
"cmake/4.3.0#b939a42e98f593fb34d3a8c5cc860359%1774439249.183", "cmake/4.2.0#ae0a44f44a1ef9ab68fd4b3e9a1f8671%1765850153.937",
"b2/5.4.2#ffd6084a119587e70f11cd45d1a386e2%1774439233.447", "cmake/3.31.10#313d16a1aa16bbdb2ca0792467214b76%1765850153.479",
"b2/5.3.3#107c15377719889654eb9a162a673975%1765850144.355",
"automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56", "automake/1.16.5#b91b7c384c3deaa9d535be02da14d04f%1755524470.56",
"autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86", "autoconf/2.71#51077f068e61700d65bb05541ea1e4b0%1731054366.86",
"abseil/20250127.0#bb0baf1f362bc4a725a24eddd419b8f7%1774365460.196" "abseil/20250127.0#99262a368bd01c0ccca8790dfced9719%1766517936.993"
], ],
"python_requires": [], "python_requires": [],
"overrides": { "overrides": {
"protobuf/[>=5.27.0 <7]": [ "protobuf/5.27.0": [
"protobuf/6.33.5" "protobuf/6.32.1"
], ],
"lz4/1.9.4": [ "lz4/1.9.4": [
"lz4/1.10.0" "lz4/1.10.0"
], ],
"boost/[>=1.83.0 <1.91.0]": [
"boost/1.90.0"
],
"sqlite3/[>=3.44 <4]": [
"sqlite3/3.51.0"
],
"boost/1.83.0": [ "boost/1.83.0": [
"boost/1.90.0" "boost/1.88.0"
],
"sqlite3/3.44.2": [
"sqlite3/3.49.1"
], ],
"lz4/[>=1.9.4 <2]": [ "lz4/[>=1.9.4 <2]": [
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504" "lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504"

View File

@@ -7,21 +7,16 @@ include(default)
{% if compiler == "gcc" %} {% if compiler == "gcc" %}
{% if "address" in sanitizers or "thread" in sanitizers or "undefinedbehavior" in sanitizers %} {% if "address" in sanitizers or "thread" in sanitizers or "undefinedbehavior" in sanitizers %}
{% set sanitizer_list = [] %} {% set sanitizer_list = [] %}
{% set defines = [] %}
{% set model_code = "" %} {% set model_code = "" %}
{% set extra_cxxflags = ["-fno-omit-frame-pointer", "-O1", "-Wno-stringop-overflow"] %} {% set extra_cxxflags = ["-fno-omit-frame-pointer", "-O1", "-Wno-stringop-overflow"] %}
{% if "address" in sanitizers %} {% if "address" in sanitizers %}
{% set _ = sanitizer_list.append("address") %} {% set _ = sanitizer_list.append("address") %}
{% set model_code = "-mcmodel=large" %} {% set model_code = "-mcmodel=large" %}
{% set _ = defines.append("BOOST_USE_ASAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% elif "thread" in sanitizers %} {% elif "thread" in sanitizers %}
{% set _ = sanitizer_list.append("thread") %} {% set _ = sanitizer_list.append("thread") %}
{% set model_code = "-mcmodel=medium" %} {% set model_code = "-mcmodel=medium" %}
{% set _ = extra_cxxflags.append("-Wno-tsan") %} {% set _ = extra_cxxflags.append("-Wno-tsan") %}
{% set _ = defines.append("BOOST_USE_TSAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% endif %} {% endif %}
{% if "undefinedbehavior" in sanitizers %} {% if "undefinedbehavior" in sanitizers %}
@@ -34,22 +29,16 @@ include(default)
tools.build:cxxflags+=['{{sanitizer_flags}} {{" ".join(extra_cxxflags)}}'] tools.build:cxxflags+=['{{sanitizer_flags}} {{" ".join(extra_cxxflags)}}']
tools.build:sharedlinkflags+=['{{sanitizer_flags}}'] tools.build:sharedlinkflags+=['{{sanitizer_flags}}']
tools.build:exelinkflags+=['{{sanitizer_flags}}'] tools.build:exelinkflags+=['{{sanitizer_flags}}']
tools.build:defines+={{defines}}
{% endif %} {% endif %}
{% elif compiler == "apple-clang" or compiler == "clang" %} {% elif compiler == "apple-clang" or compiler == "clang" %}
{% if "address" in sanitizers or "thread" in sanitizers or "undefinedbehavior" in sanitizers %} {% if "address" in sanitizers or "thread" in sanitizers or "undefinedbehavior" in sanitizers %}
{% set sanitizer_list = [] %} {% set sanitizer_list = [] %}
{% set defines = [] %}
{% set extra_cxxflags = ["-fno-omit-frame-pointer", "-O1"] %} {% set extra_cxxflags = ["-fno-omit-frame-pointer", "-O1"] %}
{% if "address" in sanitizers %} {% if "address" in sanitizers %}
{% set _ = sanitizer_list.append("address") %} {% set _ = sanitizer_list.append("address") %}
{% set _ = defines.append("BOOST_USE_ASAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% elif "thread" in sanitizers %} {% elif "thread" in sanitizers %}
{% set _ = sanitizer_list.append("thread") %} {% set _ = sanitizer_list.append("thread") %}
{% set _ = defines.append("BOOST_USE_TSAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% endif %} {% endif %}
{% if "undefinedbehavior" in sanitizers %} {% if "undefinedbehavior" in sanitizers %}
@@ -63,24 +52,8 @@ include(default)
tools.build:cxxflags+=['{{sanitizer_flags}} {{" ".join(extra_cxxflags)}}'] tools.build:cxxflags+=['{{sanitizer_flags}} {{" ".join(extra_cxxflags)}}']
tools.build:sharedlinkflags+=['{{sanitizer_flags}}'] tools.build:sharedlinkflags+=['{{sanitizer_flags}}']
tools.build:exelinkflags+=['{{sanitizer_flags}}'] tools.build:exelinkflags+=['{{sanitizer_flags}}']
tools.build:defines+={{defines}}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags", "tools.build:defines"] tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags"]
[options]
{% if sanitizers %}
{% if "address" in sanitizers %}
# Build Boost.Context with ucontext backend (not fcontext) so that
# ASAN fiber-switching annotations (__sanitizer_start/finish_switch_fiber)
# are compiled into the library. fcontext (assembly) has no ASAN support.
# define=BOOST_USE_ASAN=1 is critical: it must be defined when building
# Boost.Context itself so the ucontext backend compiles in the ASAN annotations.
boost/*:extra_b2_flags=context-impl=ucontext address-sanitizer=on define=BOOST_USE_ASAN=1
boost/*:without_context=False
# Boost stacktrace fails to build with some sanitizers
boost/*:without_stacktrace=True
{% endif %}
{% endif %}

View File

@@ -1,9 +1,9 @@
import os
import re import re
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
from conan import ConanFile from conan import ConanFile
from conan import __version__ as conan_version
class Xrpl(ConanFile): class Xrpl(ConanFile):
@@ -29,11 +29,11 @@ class Xrpl(ConanFile):
requires = [ requires = [
"ed25519/2015.03", "ed25519/2015.03",
"grpc/1.78.1", "grpc/1.72.0",
"libarchive/3.8.1", "libarchive/3.8.1",
"nudb/2.0.9", "nudb/2.0.9",
"openssl/3.6.1", "openssl/3.5.4",
"secp256k1/0.7.1", "secp256k1/0.7.0",
"soci/4.0.3", "soci/4.0.3",
"zlib/1.3.1", "zlib/1.3.1",
] ]
@@ -43,7 +43,7 @@ class Xrpl(ConanFile):
] ]
tool_requires = [ tool_requires = [
"protobuf/6.33.5", "protobuf/6.32.1",
] ]
default_options = { default_options = {
@@ -57,9 +57,6 @@ class Xrpl(ConanFile):
"tests": False, "tests": False,
"unity": False, "unity": False,
"xrpld": False, "xrpld": False,
"boost/*:without_context": False,
"boost/*:without_coroutine": True,
"boost/*:without_coroutine2": False,
"date/*:header_only": True, "date/*:header_only": True,
"ed25519/*:shared": False, "ed25519/*:shared": False,
"grpc/*:shared": False, "grpc/*:shared": False,
@@ -129,23 +126,21 @@ class Xrpl(ConanFile):
if self.settings.compiler in ["clang", "gcc"]: if self.settings.compiler in ["clang", "gcc"]:
self.options["boost"].without_cobalt = True self.options["boost"].without_cobalt = True
# Check if environment variable exists
if "SANITIZERS" in os.environ:
sanitizers = os.environ["SANITIZERS"]
if "address" in sanitizers.lower():
self.default_options["fPIC"] = False
def requirements(self): def requirements(self):
self.requires("boost/1.90.0", force=True, transitive_headers=True) # Conan 2 requires transitive headers to be specified
self.requires("date/3.0.4", transitive_headers=True) transitive_headers_opt = (
{"transitive_headers": True} if conan_version.split(".")[0] == "2" else {}
)
self.requires("boost/1.88.0", force=True, **transitive_headers_opt)
self.requires("date/3.0.4", **transitive_headers_opt)
self.requires("lz4/1.10.0", force=True) self.requires("lz4/1.10.0", force=True)
self.requires("protobuf/6.33.5", force=True) self.requires("protobuf/6.32.1", force=True)
self.requires("sqlite3/3.51.0", force=True) self.requires("sqlite3/3.49.1", force=True)
if self.options.jemalloc: if self.options.jemalloc:
self.requires("jemalloc/5.3.0") self.requires("jemalloc/5.3.0")
if self.options.rocksdb: if self.options.rocksdb:
self.requires("rocksdb/10.5.1") self.requires("rocksdb/10.5.1")
self.requires("xxhash/0.8.3", transitive_headers=True) self.requires("xxhash/0.8.3", **transitive_headers_opt)
exports_sources = ( exports_sources = (
"CMakeLists.txt", "CMakeLists.txt",
@@ -201,13 +196,14 @@ class Xrpl(ConanFile):
"boost::headers", "boost::headers",
"boost::chrono", "boost::chrono",
"boost::container", "boost::container",
"boost::context", "boost::coroutine",
"boost::date_time", "boost::date_time",
"boost::filesystem", "boost::filesystem",
"boost::json", "boost::json",
"boost::program_options", "boost::program_options",
"boost::process", "boost::process",
"boost::regex", "boost::regex",
"boost::system",
"boost::thread", "boost::thread",
"date::date", "date::date",
"ed25519::ed25519", "ed25519::ed25519",

View File

@@ -17,8 +17,8 @@ guideline is to maintain the standards that are used in those libraries.
## Guidelines ## Guidelines
If you want to do something contrary to these guidelines, understand If you want to do something contrary to these guidelines, understand
why you're doing it. Think, use common sense, and consider that these why you're doing it. Think, use common sense, and consider that this
changes will probably need to be maintained long after you've your changes will probably need to be maintained long after you've
moved on to other projects. moved on to other projects.
- Use white space and blank lines to guide the eye and keep your intent clear. - Use white space and blank lines to guide the eye and keep your intent clear.

View File

@@ -3,8 +3,6 @@ environment complete with Git, Python, Conan, CMake, and a C++ compiler.
This document exists to help readers set one up on any of the Big Three This document exists to help readers set one up on any of the Big Three
platforms: Linux, macOS, or Windows. platforms: Linux, macOS, or Windows.
As an alternative to system packages, the Nix development shell can be used to provide a development environment. See [using nix development shell](./nix.md) for more details.
[BUILD.md]: ../../BUILD.md [BUILD.md]: ../../BUILD.md
## Linux ## Linux
@@ -109,32 +107,3 @@ Install CMake with Homebrew too:
``` ```
brew install cmake brew install cmake
``` ```
## Clang-tidy
Clang-tidy is required to run static analysis checks locally (see [CONTRIBUTING.md](../../CONTRIBUTING.md)).
It is not required to build the project. Currently this project uses clang-tidy version 21.
### Linux
LLVM 21 is not available in the default Debian 12 (Bookworm) repositories.
Install it using the official LLVM apt installer:
```
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 21
sudo apt install --yes clang-tidy-21
```
Then use `run-clang-tidy-21` when running clang-tidy locally.
### macOS
Install LLVM 21 via Homebrew:
```
brew install llvm@21
```
Then use `run-clang-tidy` from the LLVM 21 Homebrew prefix when running clang-tidy locally.

95
docs/build/nix.md vendored
View File

@@ -1,95 +0,0 @@
# Using Nix Development Shell for xrpld Development
This guide explains how to use Nix to set up a reproducible development environment for xrpld. Using Nix eliminates the need to manually install utilities and ensures consistent tooling across different machines.
## Benefits of Using Nix
- **Reproducible environment**: Everyone gets the same versions of tools and compilers
- **No system pollution**: Dependencies are isolated and don't affect your system packages
- **Multiple compiler versions**: Easily switch between different GCC and Clang versions
- **Quick setup**: Get started with a single command
- **Works on Linux and macOS**: Consistent experience across platforms
## Install Nix
Please follow [the official installation instructions of nix package manager](https://nixos.org/download/) for your system.
## Entering the Development Shell
### Basic Usage
From the root of the xrpld repository, enter the default development shell:
```bash
nix --experimental-features 'nix-command flakes' develop
```
This will:
- Download and set up all required development tools (CMake, Ninja, Conan, etc.)
- Configure the appropriate compiler for your platform:
- **macOS**: Apple Clang (default system compiler)
- **Linux**: GCC 15
The first time you run this command, it will take a few minutes to download and build the environment. Subsequent runs will be much faster.
> [!TIP]
> To avoid typing `--experimental-features 'nix-command flakes'` every time, you can permanently enable flakes by creating `~/.config/nix/nix.conf`:
>
> ```bash
> mkdir -p ~/.config/nix
> echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
> ```
>
> After this, you can simply use `nix develop` instead.
> [!NOTE]
> The examples below assume you've enabled flakes in your config. If you haven't, add `--experimental-features 'nix-command flakes'` after each `nix` command.
### Choosing a different compiler
A compiler can be chosen by providing its name with the `.#` prefix, e.g. `nix develop .#gcc15`.
Use `nix flake show` to see all the available development shells.
Use `nix develop .#no_compiler` to use the compiler from your system.
### Example Usage
```bash
# Use GCC 14
nix develop .#gcc14
# Use Clang 19
nix develop .#clang19
# Use default for your platform
nix develop
```
### Using a different shell
`nix develop` opens bash by default. If you want to use another shell this could be done by adding `-c` flag. For example:
```bash
nix develop -c zsh
```
## Building xrpld with Nix
Once inside the Nix development shell, follow the standard [build instructions](../../BUILD.md#steps). The Nix shell provides all necessary tools (CMake, Ninja, Conan, etc.).
## Automatic Activation with direnv
[direnv](https://direnv.net/) or [nix-direnv](https://github.com/nix-community/nix-direnv) can automatically activate the Nix development shell when you enter the repository directory.
## Conan and Prebuilt Packages
Please note that there is no guarantee that binaries from conan cache will work when using nix. If you encounter any errors, please use `--build '*'` to force conan to compile everything from source:
```bash
conan install .. --output-folder . --build '*' --settings build_type=Release
```
## Updating `flake.lock` file
To update `flake.lock` to the latest revision use `nix flake update` command.

View File

@@ -89,8 +89,8 @@ cmake --build . --parallel 4
**IMPORTANT**: ASAN with Boost produces many false positives. Use these options: **IMPORTANT**: ASAN with Boost produces many false positives. Use these options:
```bash ```bash
export ASAN_OPTIONS="include=sanitizers/suppressions/runtime-asan-options.txt:suppressions=sanitizers/suppressions/asan.supp" export ASAN_OPTIONS="print_stacktrace=1:detect_container_overflow=0:suppressions=path/to/asan.supp:halt_on_error=0:log_path=asan.log"
export LSAN_OPTIONS="include=sanitizers/suppressions/runtime-lsan-options.txt:suppressions=sanitizers/suppressions/lsan.supp" export LSAN_OPTIONS="suppressions=path/to/lsan.supp:halt_on_error=0:log_path=lsan.log"
# Run tests # Run tests
./xrpld --unittest --unittest-jobs=5 ./xrpld --unittest --unittest-jobs=5
@@ -108,7 +108,7 @@ export LSAN_OPTIONS="include=sanitizers/suppressions/runtime-lsan-options.txt:su
### ThreadSanitizer (TSan) ### ThreadSanitizer (TSan)
```bash ```bash
export TSAN_OPTIONS="include=sanitizers/suppressions/runtime-tsan-options.txt:suppressions=sanitizers/suppressions/tsan.supp" export TSAN_OPTIONS="suppressions=path/to/tsan.supp halt_on_error=0 log_path=tsan.log"
# Run tests # Run tests
./xrpld --unittest --unittest-jobs=5 ./xrpld --unittest --unittest-jobs=5
@@ -129,7 +129,7 @@ More details [here](https://github.com/google/sanitizers/wiki/AddressSanitizerLe
### UndefinedBehaviorSanitizer (UBSan) ### UndefinedBehaviorSanitizer (UBSan)
```bash ```bash
export UBSAN_OPTIONS="include=sanitizers/suppressions/runtime-ubsan-options.txt:suppressions=sanitizers/suppressions/ubsan.supp" export UBSAN_OPTIONS="suppressions=path/to/ubsan.supp:print_stacktrace=1:halt_on_error=0:log_path=ubsan.log"
# Run tests # Run tests
./xrpld --unittest --unittest-jobs=5 ./xrpld --unittest --unittest-jobs=5

26
flake.lock generated
View File

@@ -1,26 +0,0 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1769461804,
"narHash": "sha256-6h5sROT/3CTHvzPy9koKBmoCa2eJKh4fzQK8eYFEgl8=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b579d443b37c9c5373044201ea77604e37e748c8",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View File

@@ -1,16 +0,0 @@
{
description = "Nix related things for xrpld";
inputs = {
nixpkgs.url = "nixpkgs/nixos-unstable";
};
outputs =
{ nixpkgs, ... }:
let
forEachSystem = (import ./nix/utils.nix { inherit nixpkgs; }).forEachSystem;
in
{
devShells = forEachSystem (import ./nix/devshell.nix);
formatter = forEachSystem ({ pkgs, ... }: pkgs.nixfmt);
};
}

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_ARCHIVE_H_INCLUDED
#define XRPL_BASICS_ARCHIVE_H_INCLUDED
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
@@ -12,6 +13,10 @@ namespace xrpl {
@throws runtime_error @throws runtime_error
*/ */
void void
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst); extractTarLz4(
boost::filesystem::path const& src,
boost::filesystem::path const& dst);
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_BASICCONFIG_H_INCLUDED
#define XRPL_BASICS_BASICCONFIG_H_INCLUDED
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
@@ -13,7 +14,8 @@
namespace xrpl { namespace xrpl {
using IniFileSections = std::unordered_map<std::string, std::vector<std::string>>; using IniFileSections =
std::unordered_map<std::string, std::vector<std::string>>;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -231,7 +233,10 @@ public:
The previous value, if any, is overwritten. The previous value, if any, is overwritten.
*/ */
void void
overwrite(std::string const& section, std::string const& key, std::string const& value); overwrite(
std::string const& section,
std::string const& key,
std::string const& value);
/** Remove all the key/value pairs from the section. /** Remove all the key/value pairs from the section.
*/ */
@@ -269,8 +274,9 @@ public:
bool bool
had_trailing_comments() const had_trailing_comments() const
{ {
return std::any_of( return std::any_of(map_.cbegin(), map_.cend(), [](auto s) {
map_.cbegin(), map_.cend(), [](auto s) { return s.second.had_trailing_comments(); }); return s.second.had_trailing_comments();
});
} }
protected: protected:
@@ -309,9 +315,12 @@ set(T& target, std::string const& name, Section const& section)
*/ */
template <class T> template <class T>
bool bool
set(T& target, T const& defaultValue, std::string const& name, Section const& section) set(T& target,
T const& defaultValue,
std::string const& name,
Section const& section)
{ {
bool const found_and_valid = set<T>(target, name, section); bool found_and_valid = set<T>(target, name, section);
if (!found_and_valid) if (!found_and_valid)
target = defaultValue; target = defaultValue;
return found_and_valid; return found_and_valid;
@@ -324,7 +333,9 @@ set(T& target, T const& defaultValue, std::string const& name, Section const& se
// NOTE This routine might be more clumsy than the previous two // NOTE This routine might be more clumsy than the previous two
template <class T = std::string> template <class T = std::string>
T T
get(Section const& section, std::string const& name, T const& defaultValue = T{}) get(Section const& section,
std::string const& name,
T const& defaultValue = T{})
{ {
try try
{ {
@@ -370,3 +381,5 @@ get_if_exists<bool>(Section const& section, std::string const& name, bool& v)
} }
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_BLOB_H_INCLUDED
#define XRPL_BASICS_BLOB_H_INCLUDED
#include <vector> #include <vector>
@@ -10,3 +11,5 @@ namespace xrpl {
using Blob = std::vector<unsigned char>; using Blob = std::vector<unsigned char>;
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_BUFFER_H_INCLUDED
#define XRPL_BASICS_BUFFER_H_INCLUDED
#include <xrpl/basics/Slice.h> #include <xrpl/basics/Slice.h>
#include <xrpl/beast/utility/instrumentation.h> #include <xrpl/beast/utility/instrumentation.h>
@@ -24,7 +25,8 @@ public:
Buffer() = default; Buffer() = default;
/** Create an uninitialized buffer with the given size. */ /** Create an uninitialized buffer with the given size. */
explicit Buffer(std::size_t size) : p_(size ? new std::uint8_t[size] : nullptr), size_(size) explicit Buffer(std::size_t size)
: p_(size ? new std::uint8_t[size] : nullptr), size_(size)
{ {
} }
@@ -60,7 +62,8 @@ public:
/** Move-construct. /** Move-construct.
The other buffer is reset. The other buffer is reset.
*/ */
Buffer(Buffer&& other) noexcept : p_(std::move(other.p_)), size_(other.size_) Buffer(Buffer&& other) noexcept
: p_(std::move(other.p_)), size_(other.size_)
{ {
other.size_ = 0; other.size_ = 0;
} }
@@ -91,7 +94,8 @@ public:
{ {
// Ensure the slice isn't a subset of the buffer. // Ensure the slice isn't a subset of the buffer.
XRPL_ASSERT( XRPL_ASSERT(
s.size() == 0 || size_ == 0 || s.data() < p_.get() || s.data() >= p_.get() + size_, s.size() == 0 || size_ == 0 || s.data() < p_.get() ||
s.data() >= p_.get() + size_,
"xrpl::Buffer::operator=(Slice) : input not a subset"); "xrpl::Buffer::operator=(Slice) : input not a subset");
if (auto p = alloc(s.size())) if (auto p = alloc(s.size()))
@@ -212,3 +216,5 @@ operator!=(Buffer const& lhs, Buffer const& rhs) noexcept
} }
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_BYTEUTILITIES_H_INCLUDED
#define XRPL_BASICS_BYTEUTILITIES_H_INCLUDED
namespace xrpl { namespace xrpl {
@@ -19,3 +20,5 @@ megabytes(T value) noexcept
static_assert(kilobytes(2) == 2048, "kilobytes(2) == 2048"); static_assert(kilobytes(2) == 2048, "kilobytes(2) == 2048");
static_assert(megabytes(3) == 3145728, "megabytes(3) == 3145728"); static_assert(megabytes(3) == 3145728, "megabytes(3) == 3145728");
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_COMPRESSIONALGORITHMS_H_INCLUDED
#define XRPL_COMPRESSIONALGORITHMS_H_INCLUDED
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
@@ -115,7 +116,9 @@ lz4Decompress(
compressed.resize(inSize); compressed.resize(inSize);
} }
chunkSize = chunkSize < (inSize - copiedInSize) ? chunkSize : (inSize - copiedInSize); chunkSize = chunkSize < (inSize - copiedInSize)
? chunkSize
: (inSize - copiedInSize);
std::copy(chunk, chunk + chunkSize, compressed.data() + copiedInSize); std::copy(chunk, chunk + chunkSize, compressed.data() + copiedInSize);
@@ -132,7 +135,8 @@ lz4Decompress(
if (in.ByteCount() > (currentBytes + copiedInSize)) if (in.ByteCount() > (currentBytes + copiedInSize))
in.BackUp(in.ByteCount() - currentBytes - copiedInSize); in.BackUp(in.ByteCount() - currentBytes - copiedInSize);
if ((copiedInSize == 0 && chunkSize < inSize) || (copiedInSize > 0 && copiedInSize != inSize)) if ((copiedInSize == 0 && chunkSize < inSize) ||
(copiedInSize > 0 && copiedInSize != inSize))
Throw<std::runtime_error>("lz4 decompress: insufficient input size"); Throw<std::runtime_error>("lz4 decompress: insufficient input size");
return lz4Decompress(chunk, inSize, decompressed, decompressedSize); return lz4Decompress(chunk, inSize, decompressed, decompressedSize);
@@ -141,3 +145,5 @@ lz4Decompress(
} // namespace compression_algorithms } // namespace compression_algorithms
} // namespace xrpl } // namespace xrpl
#endif // XRPL_COMPRESSIONALGORITHMS_H_INCLUDED

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_COUNTEDOBJECT_H_INCLUDED
#define XRPL_BASICS_COUNTEDOBJECT_H_INCLUDED
#include <xrpl/beast/type_name.h> #include <xrpl/beast/type_name.h>
@@ -34,7 +35,7 @@ public:
{ {
// Insert ourselves at the front of the lock-free linked list // Insert ourselves at the front of the lock-free linked list
CountedObjects& instance = CountedObjects::getInstance(); CountedObjects& instance = CountedObjects::getInstance();
Counter* head = nullptr; Counter* head;
do do
{ {
@@ -133,3 +134,5 @@ public:
}; };
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_DECAYINGSAMPLE_H_INCLUDED
#define XRPL_BASICS_DECAYINGSAMPLE_H_INCLUDED
#include <chrono> #include <chrono>
#include <cmath> #include <cmath>
@@ -56,7 +57,8 @@ private:
if (m_value != value_type()) if (m_value != value_type())
{ {
std::size_t elapsed = std::size_t elapsed =
std::chrono::duration_cast<std::chrono::seconds>(now - m_when).count(); std::chrono::duration_cast<std::chrono::seconds>(now - m_when)
.count();
// A span larger than four times the window decays the // A span larger than four times the window decays the
// value to an insignificant amount so just reset it. // value to an insignificant amount so just reset it.
@@ -93,7 +95,7 @@ class DecayWindow
public: public:
using time_point = typename Clock::time_point; using time_point = typename Clock::time_point;
explicit DecayWindow(time_point now) : when_(now) explicit DecayWindow(time_point now) : value_(0), when_(now)
{ {
} }
@@ -125,8 +127,10 @@ private:
when_ = now; when_ = now;
} }
double value_{0}; double value_;
time_point when_; time_point when_;
}; };
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_EXPECTED_H_INCLUDED
#define XRPL_BASICS_EXPECTED_H_INCLUDED
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
@@ -107,14 +108,16 @@ Unexpected(E (&)[N]) -> Unexpected<E const*>;
// Definition of Expected. All of the machinery comes from boost::result. // Definition of Expected. All of the machinery comes from boost::result.
template <class T, class E> template <class T, class E>
class [[nodiscard]] Expected : private boost::outcome_v2::result<T, E, detail::throw_policy> class [[nodiscard]] Expected
: private boost::outcome_v2::result<T, E, detail::throw_policy>
{ {
using Base = boost::outcome_v2::result<T, E, detail::throw_policy>; using Base = boost::outcome_v2::result<T, E, detail::throw_policy>;
public: public:
template <typename U> template <typename U>
requires std::convertible_to<U, T> requires std::convertible_to<U, T>
constexpr Expected(U&& r) : Base(boost::outcome_v2::in_place_type_t<T>{}, std::forward<U>(r)) constexpr Expected(U&& r)
: Base(boost::outcome_v2::in_place_type_t<T>{}, std::forward<U>(r))
{ {
} }
@@ -192,8 +195,8 @@ public:
// Specialization of Expected<void, E>. Allows returning either success // Specialization of Expected<void, E>. Allows returning either success
// (without a value) or the reason for the failure. // (without a value) or the reason for the failure.
template <class E> template <class E>
class [[nodiscard]] class [[nodiscard]] Expected<void, E>
Expected<void, E> : private boost::outcome_v2::result<void, E, detail::throw_policy> : private boost::outcome_v2::result<void, E, detail::throw_policy>
{ {
using Base = boost::outcome_v2::result<void, E, detail::throw_policy>; using Base = boost::outcome_v2::result<void, E, detail::throw_policy>;
@@ -230,3 +233,5 @@ public:
}; };
} // namespace xrpl } // namespace xrpl
#endif // XRPL_BASICS_EXPECTED_H_INCLUDED

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_FILEUTILITIES_H_INCLUDED
#define XRPL_BASICS_FILEUTILITIES_H_INCLUDED
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp> #include <boost/system/error_code.hpp>
@@ -20,3 +21,5 @@ writeFileContents(
std::string const& contents); std::string const& contents);
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_INTRUSIVEPOINTER_H_INCLUDED
#define XRPL_BASICS_INTRUSIVEPOINTER_H_INCLUDED
#include <concepts> #include <concepts>
#include <cstdint> #include <cstdint>
@@ -84,8 +85,7 @@ public:
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> requires std::convertible_to<TT*, T*>
SharedIntrusive( SharedIntrusive(SharedIntrusive<TT>&& rhs);
SharedIntrusive<TT>&& rhs); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
SharedIntrusive& SharedIntrusive&
operator=(SharedIntrusive const& rhs); operator=(SharedIntrusive const& rhs);
@@ -107,8 +107,7 @@ public:
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> requires std::convertible_to<TT*, T*>
SharedIntrusive& SharedIntrusive&
operator=( operator=(SharedIntrusive<TT>&& rhs);
SharedIntrusive<TT>&& rhs); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
/** Adopt the raw pointer. The strong reference may or may not be /** Adopt the raw pointer. The strong reference may or may not be
incremented, depending on the TAdoptTag incremented, depending on the TAdoptTag
@@ -123,7 +122,9 @@ public:
controlled by the rhs param. controlled by the rhs param.
*/ */
template <class TT> template <class TT>
SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs); SharedIntrusive(
StaticCastTagSharedIntrusive,
SharedIntrusive<TT> const& rhs);
/** Create a new SharedIntrusive by statically casting the pointer /** Create a new SharedIntrusive by statically casting the pointer
controlled by the rhs param. controlled by the rhs param.
@@ -135,7 +136,9 @@ public:
controlled by the rhs param. controlled by the rhs param.
*/ */
template <class TT> template <class TT>
SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs); SharedIntrusive(
DynamicCastTagSharedIntrusive,
SharedIntrusive<TT> const& rhs);
/** Create a new SharedIntrusive by dynamically casting the pointer /** Create a new SharedIntrusive by dynamically casting the pointer
controlled by the rhs param. controlled by the rhs param.
@@ -301,7 +304,9 @@ class SharedWeakUnion
// Tagged pointer. Low bit determines if this is a strong or a weak // Tagged pointer. Low bit determines if this is a strong or a weak
// pointer. The low bit must be masked to zero when converting back to a // pointer. The low bit must be masked to zero when converting back to a
// pointer. If the low bit is '1', this is a weak pointer. // pointer. If the low bit is '1', this is a weak pointer.
static_assert(alignof(T) >= 2, "Bad alignment: Combo pointer requires low bit to be zero"); static_assert(
alignof(T) >= 2,
"Bad alignment: Combo pointer requires low bit to be zero");
public: public:
SharedWeakUnion() = default; SharedWeakUnion() = default;
@@ -316,8 +321,7 @@ public:
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> requires std::convertible_to<TT*, T*>
SharedWeakUnion( SharedWeakUnion(SharedIntrusive<TT>&& rhs);
SharedIntrusive<TT>&& rhs); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
SharedWeakUnion& SharedWeakUnion&
operator=(SharedWeakUnion const& rhs); operator=(SharedWeakUnion const& rhs);
@@ -330,8 +334,7 @@ public:
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> requires std::convertible_to<TT*, T*>
SharedWeakUnion& SharedWeakUnion&
operator=( operator=(SharedIntrusive<TT>&& rhs);
SharedIntrusive<TT>&& rhs); // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
~SharedWeakUnion(); ~SharedWeakUnion();
@@ -448,7 +451,8 @@ make_SharedIntrusive(Args&&... args)
static_assert( static_assert(
noexcept(SharedIntrusive<TT>( noexcept(SharedIntrusive<TT>(
std::declval<TT*>(), std::declval<SharedIntrusiveAdoptNoIncrementTag>())), std::declval<TT*>(),
std::declval<SharedIntrusiveAdoptNoIncrementTag>())),
"SharedIntrusive constructor should not throw or this can leak " "SharedIntrusive constructor should not throw or this can leak "
"memory"); "memory");
@@ -489,3 +493,4 @@ dynamic_pointer_cast(TT const& v)
} }
} // namespace intr_ptr } // namespace intr_ptr
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_INTRUSIVEPOINTER_IPP_INCLUDED
#define XRPL_BASICS_INTRUSIVEPOINTER_IPP_INCLUDED
#include <xrpl/basics/IntrusivePointer.h> #include <xrpl/basics/IntrusivePointer.h>
#include <xrpl/basics/IntrusiveRefCounts.h> #include <xrpl/basics/IntrusiveRefCounts.h>
@@ -11,7 +12,9 @@ template <class T>
template <CAdoptTag TAdoptTag> template <CAdoptTag TAdoptTag>
SharedIntrusive<T>::SharedIntrusive(T* p, TAdoptTag) noexcept : ptr_{p} SharedIntrusive<T>::SharedIntrusive(T* p, TAdoptTag) noexcept : ptr_{p}
{ {
if constexpr (std::is_same_v<TAdoptTag, SharedIntrusiveAdoptIncrementStrongTag>) if constexpr (std::is_same_v<
TAdoptTag,
SharedIntrusiveAdoptIncrementStrongTag>)
{ {
if (p) if (p)
p->addStrongRef(); p->addStrongRef();
@@ -43,14 +46,16 @@ SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT> const& rhs)
} }
template <class T> template <class T>
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive&& rhs) : ptr_{rhs.unsafeExchange(nullptr)} SharedIntrusive<T>::SharedIntrusive(SharedIntrusive&& rhs)
: ptr_{rhs.unsafeExchange(nullptr)}
{ {
} }
template <class T> template <class T>
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> requires std::convertible_to<TT*, T*>
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT>&& rhs) : ptr_{rhs.unsafeExchange(nullptr)} SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT>&& rhs)
: ptr_{rhs.unsafeExchange(nullptr)}
{ {
} }
template <class T> template <class T>
@@ -68,7 +73,9 @@ SharedIntrusive<T>::operator=(SharedIntrusive const& rhs)
template <class T> template <class T>
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> // clang-format off
requires std::convertible_to<TT*, T*>
// clang-format on
SharedIntrusive<T>& SharedIntrusive<T>&
SharedIntrusive<T>::operator=(SharedIntrusive<TT> const& rhs) SharedIntrusive<T>::operator=(SharedIntrusive<TT> const& rhs)
{ {
@@ -99,11 +106,15 @@ SharedIntrusive<T>::operator=(SharedIntrusive&& rhs)
template <class T> template <class T>
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> // clang-format off
requires std::convertible_to<TT*, T*>
// clang-format on
SharedIntrusive<T>& SharedIntrusive<T>&
SharedIntrusive<T>::operator=(SharedIntrusive<TT>&& rhs) SharedIntrusive<T>::operator=(SharedIntrusive<TT>&& rhs)
{ {
static_assert(!std::is_same_v<T, TT>, "This overload should not be instantiated for T == TT"); static_assert(
!std::is_same_v<T, TT>,
"This overload should not be instantiated for T == TT");
unsafeReleaseAndStore(rhs.unsafeExchange(nullptr)); unsafeReleaseAndStore(rhs.unsafeExchange(nullptr));
return *this; return *this;
@@ -128,7 +139,9 @@ template <CAdoptTag TAdoptTag>
void void
SharedIntrusive<T>::adopt(T* p) SharedIntrusive<T>::adopt(T* p)
{ {
if constexpr (std::is_same_v<TAdoptTag, SharedIntrusiveAdoptIncrementStrongTag>) if constexpr (std::is_same_v<
TAdoptTag,
SharedIntrusiveAdoptIncrementStrongTag>)
{ {
if (p) if (p)
p->addStrongRef(); p->addStrongRef();
@@ -144,7 +157,9 @@ SharedIntrusive<T>::~SharedIntrusive()
template <class T> template <class T>
template <class TT> template <class TT>
SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs) SharedIntrusive<T>::SharedIntrusive(
StaticCastTagSharedIntrusive,
SharedIntrusive<TT> const& rhs)
: ptr_{[&] { : ptr_{[&] {
auto p = static_cast<T*>(rhs.unsafeGetRawPtr()); auto p = static_cast<T*>(rhs.unsafeGetRawPtr());
if (p) if (p)
@@ -156,14 +171,18 @@ SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusiv
template <class T> template <class T>
template <class TT> template <class TT>
SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusive<TT>&& rhs) SharedIntrusive<T>::SharedIntrusive(
StaticCastTagSharedIntrusive,
SharedIntrusive<TT>&& rhs)
: ptr_{static_cast<T*>(rhs.unsafeExchange(nullptr))} : ptr_{static_cast<T*>(rhs.unsafeExchange(nullptr))}
{ {
} }
template <class T> template <class T>
template <class TT> template <class TT>
SharedIntrusive<T>::SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusive<TT> const& rhs) SharedIntrusive<T>::SharedIntrusive(
DynamicCastTagSharedIntrusive,
SharedIntrusive<TT> const& rhs)
: ptr_{[&] { : ptr_{[&] {
auto p = dynamic_cast<T*>(rhs.unsafeGetRawPtr()); auto p = dynamic_cast<T*>(rhs.unsafeGetRawPtr());
if (p) if (p)
@@ -175,7 +194,9 @@ SharedIntrusive<T>::SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusi
template <class T> template <class T>
template <class TT> template <class TT>
SharedIntrusive<T>::SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusive<TT>&& rhs) SharedIntrusive<T>::SharedIntrusive(
DynamicCastTagSharedIntrusive,
SharedIntrusive<TT>&& rhs)
{ {
// This can be simplified without the `exchange`, but the `exchange` is kept // This can be simplified without the `exchange`, but the `exchange` is kept
// in anticipation of supporting atomic operations. // in anticipation of supporting atomic operations.
@@ -204,8 +225,7 @@ SharedIntrusive<T>::operator->() const noexcept
} }
template <class T> template <class T>
SharedIntrusive<T>:: SharedIntrusive<T>::operator bool() const noexcept
operator bool() const noexcept
{ {
return bool(unsafeGetRawPtr()); return bool(unsafeGetRawPtr());
} }
@@ -295,7 +315,8 @@ WeakIntrusive<T>::WeakIntrusive(WeakIntrusive&& rhs) : ptr_{rhs.ptr_}
} }
template <class T> template <class T>
WeakIntrusive<T>::WeakIntrusive(SharedIntrusive<T> const& rhs) : ptr_{rhs.unsafeGetRawPtr()} WeakIntrusive<T>::WeakIntrusive(SharedIntrusive<T> const& rhs)
: ptr_{rhs.unsafeGetRawPtr()}
{ {
if (ptr_) if (ptr_)
ptr_->addWeakRef(); ptr_->addWeakRef();
@@ -303,7 +324,9 @@ WeakIntrusive<T>::WeakIntrusive(SharedIntrusive<T> const& rhs) : ptr_{rhs.unsafe
template <class T> template <class T>
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> // clang-format off
requires std::convertible_to<TT*, T*>
// clang-format on
WeakIntrusive<T>& WeakIntrusive<T>&
WeakIntrusive<T>::operator=(SharedIntrusive<TT> const& rhs) WeakIntrusive<T>::operator=(SharedIntrusive<TT> const& rhs)
{ {
@@ -448,7 +471,9 @@ SharedWeakUnion<T>::operator=(SharedWeakUnion const& rhs)
template <class T> template <class T>
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> // clang-format off
requires std::convertible_to<TT*, T*>
// clang-format on
SharedWeakUnion<T>& SharedWeakUnion<T>&
SharedWeakUnion<T>::operator=(SharedIntrusive<TT> const& rhs) SharedWeakUnion<T>::operator=(SharedIntrusive<TT> const& rhs)
{ {
@@ -462,7 +487,9 @@ SharedWeakUnion<T>::operator=(SharedIntrusive<TT> const& rhs)
template <class T> template <class T>
template <class TT> template <class TT>
requires std::convertible_to<TT*, T*> // clang-format off
requires std::convertible_to<TT*, T*>
// clang-format on
SharedWeakUnion<T>& SharedWeakUnion<T>&
SharedWeakUnion<T>::operator=(SharedIntrusive<TT>&& rhs) SharedWeakUnion<T>::operator=(SharedIntrusive<TT>&& rhs)
{ {
@@ -494,8 +521,7 @@ SharedWeakUnion<T>::getStrong() const
} }
template <class T> template <class T>
SharedWeakUnion<T>:: SharedWeakUnion<T>::operator bool() const noexcept
operator bool() const noexcept
{ {
return bool(get()); return bool(get());
} }
@@ -694,3 +720,4 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
} }
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_INTRUSIVEREFCOUNTS_H_INCLUDED
#define XRPL_BASICS_INTRUSIVEREFCOUNTS_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h> #include <xrpl/beast/utility/instrumentation.h>
@@ -159,19 +160,22 @@ private:
See description of the `refCounts` field for a fuller description of See description of the `refCounts` field for a fuller description of
this field. this field.
*/ */
static constexpr FieldType partialDestroyStartedMask = (one << (FieldTypeBits - 1)); static constexpr FieldType partialDestroyStartedMask =
(one << (FieldTypeBits - 1));
/** Flag that is set when the partialDestroy function has finished running /** Flag that is set when the partialDestroy function has finished running
See description of the `refCounts` field for a fuller description of See description of the `refCounts` field for a fuller description of
this field. this field.
*/ */
static constexpr FieldType partialDestroyFinishedMask = (one << (FieldTypeBits - 2)); static constexpr FieldType partialDestroyFinishedMask =
(one << (FieldTypeBits - 2));
/** Mask that will zero out all the `count` bits and leave the tag bits /** Mask that will zero out all the `count` bits and leave the tag bits
unchanged. unchanged.
*/ */
static constexpr FieldType tagMask = partialDestroyStartedMask | partialDestroyFinishedMask; static constexpr FieldType tagMask =
partialDestroyStartedMask | partialDestroyFinishedMask;
/** Mask that will zero out the `tag` bits and leave the count bits /** Mask that will zero out the `tag` bits and leave the count bits
unchanged. unchanged.
@@ -180,7 +184,8 @@ private:
/** Mask that will zero out everything except the strong count. /** Mask that will zero out everything except the strong count.
*/ */
static constexpr FieldType strongMask = ((one << StrongCountNumBits) - 1) & valueMask; static constexpr FieldType strongMask =
((one << StrongCountNumBits) - 1) & valueMask;
/** Mask that will zero out everything except the weak count. /** Mask that will zero out everything except the weak count.
*/ */
@@ -269,7 +274,8 @@ IntrusiveRefCounts::releaseStrongRef() const
} }
} }
if (refCounts.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel)) if (refCounts.compare_exchange_weak(
prevIntVal, nextIntVal, std::memory_order_acq_rel))
{ {
// Can't be in partial destroy because only decrementing the strong // Can't be in partial destroy because only decrementing the strong
// count to zero can start a partial destroy, and that can't happen // count to zero can start a partial destroy, and that can't happen
@@ -325,7 +331,8 @@ IntrusiveRefCounts::addWeakReleaseStrongRef() const
action = partialDestroy; action = partialDestroy;
} }
} }
if (refCounts.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel)) if (refCounts.compare_exchange_weak(
prevIntVal, nextIntVal, std::memory_order_acq_rel))
{ {
XRPL_ASSERT( XRPL_ASSERT(
(!(prevIntVal & partialDestroyStartedMask)), (!(prevIntVal & partialDestroyStartedMask)),
@@ -369,7 +376,8 @@ IntrusiveRefCounts::checkoutStrongRefFromWeak() const noexcept
auto curValue = RefCountPair{1, 1}.combinedValue(); auto curValue = RefCountPair{1, 1}.combinedValue();
auto desiredValue = RefCountPair{2, 1}.combinedValue(); auto desiredValue = RefCountPair{2, 1}.combinedValue();
while (!refCounts.compare_exchange_weak(curValue, desiredValue, std::memory_order_acq_rel)) while (!refCounts.compare_exchange_weak(
curValue, desiredValue, std::memory_order_acq_rel))
{ {
RefCountPair const prev{curValue}; RefCountPair const prev{curValue};
if (!prev.strong) if (!prev.strong)
@@ -399,15 +407,19 @@ inline IntrusiveRefCounts::~IntrusiveRefCounts() noexcept
#ifndef NDEBUG #ifndef NDEBUG
auto v = refCounts.load(std::memory_order_acquire); auto v = refCounts.load(std::memory_order_acquire);
XRPL_ASSERT( XRPL_ASSERT(
(!(v & valueMask)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero"); (!(v & valueMask)),
"xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
auto t = v & tagMask; auto t = v & tagMask;
XRPL_ASSERT((!t || t == tagMask), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag"); XRPL_ASSERT(
(!t || t == tagMask),
"xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
#endif #endif
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline IntrusiveRefCounts::RefCountPair::RefCountPair(IntrusiveRefCounts::FieldType v) noexcept inline IntrusiveRefCounts::RefCountPair::RefCountPair(
IntrusiveRefCounts::FieldType v) noexcept
: strong{static_cast<CountType>(v & strongMask)} : strong{static_cast<CountType>(v & strongMask)}
, weak{static_cast<CountType>((v & weakMask) >> StrongCountNumBits)} , weak{static_cast<CountType>((v & weakMask) >> StrongCountNumBits)}
, partialDestroyStartedBit{v & partialDestroyStartedMask} , partialDestroyStartedBit{v & partialDestroyStartedMask}
@@ -439,8 +451,8 @@ IntrusiveRefCounts::RefCountPair::combinedValue() const noexcept
"inside range"); "inside range");
return (static_cast<IntrusiveRefCounts::FieldType>(weak) return (static_cast<IntrusiveRefCounts::FieldType>(weak)
<< IntrusiveRefCounts::StrongCountNumBits) | << IntrusiveRefCounts::StrongCountNumBits) |
static_cast<IntrusiveRefCounts::FieldType>(strong) | partialDestroyStartedBit | static_cast<IntrusiveRefCounts::FieldType>(strong) |
partialDestroyFinishedBit; partialDestroyStartedBit | partialDestroyFinishedBit;
} }
template <class T> template <class T>
@@ -448,10 +460,11 @@ inline void
partialDestructorFinished(T** o) partialDestructorFinished(T** o)
{ {
T& self = **o; T& self = **o;
IntrusiveRefCounts::RefCountPair const p = IntrusiveRefCounts::RefCountPair p =
self.refCounts.fetch_or(IntrusiveRefCounts::partialDestroyFinishedMask); self.refCounts.fetch_or(IntrusiveRefCounts::partialDestroyFinishedMask);
XRPL_ASSERT( XRPL_ASSERT(
(!p.partialDestroyFinishedBit && p.partialDestroyStartedBit && !p.strong), (!p.partialDestroyFinishedBit && p.partialDestroyStartedBit &&
!p.strong),
"xrpl::partialDestructorFinished : not a weak ref"); "xrpl::partialDestructorFinished : not a weak ref");
if (!p.weak) if (!p.weak)
{ {
@@ -467,3 +480,4 @@ partialDestructorFinished(T** o)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_KEYCACHE_H
#define XRPL_BASICS_KEYCACHE_H
#include <xrpl/basics/TaggedCache.h> #include <xrpl/basics/TaggedCache.h>
#include <xrpl/basics/base_uint.h> #include <xrpl/basics/base_uint.h>
@@ -8,3 +9,5 @@ namespace xrpl {
using KeyCache = TaggedCache<uint256, int, true>; using KeyCache = TaggedCache<uint256, int, true>;
} // namespace xrpl } // namespace xrpl
#endif // XRPL_BASICS_KEYCACHE_H

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_LOCALVALUE_H_INCLUDED
#define XRPL_BASICS_LOCALVALUE_H_INCLUDED
#include <boost/thread/tss.hpp> #include <boost/thread/tss.hpp>
@@ -54,7 +55,8 @@ template <class = void>
boost::thread_specific_ptr<detail::LocalValues>& boost::thread_specific_ptr<detail::LocalValues>&
getLocalValues() getLocalValues()
{ {
static boost::thread_specific_ptr<detail::LocalValues> tsp(&detail::LocalValues::cleanup); static boost::thread_specific_ptr<detail::LocalValues> tsp(
&detail::LocalValues::cleanup);
return tsp; return tsp;
} }
@@ -103,7 +105,10 @@ LocalValue<T>::operator*()
} }
return *reinterpret_cast<T*>( return *reinterpret_cast<T*>(
lvs->values.emplace(this, std::make_unique<detail::LocalValues::Value<T>>(t_)) lvs->values
.emplace(this, std::make_unique<detail::LocalValues::Value<T>>(t_))
.first->second->get()); .first->second->get());
} }
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_LOG_H_INCLUDED
#define XRPL_BASICS_LOG_H_INCLUDED
#include <xrpl/basics/UnorderedContainers.h> #include <xrpl/basics/UnorderedContainers.h>
#include <xrpl/beast/utility/Journal.h> #include <xrpl/beast/utility/Journal.h>
@@ -38,17 +39,22 @@ private:
std::string partition_; std::string partition_;
public: public:
Sink(std::string const& partition, beast::severities::Severity thresh, Logs& logs); Sink(
std::string const& partition,
beast::severities::Severity thresh,
Logs& logs);
Sink(Sink const&) = delete; Sink(Sink const&) = delete;
Sink& Sink&
operator=(Sink const&) = delete; operator=(Sink const&) = delete;
void void
write(beast::severities::Severity level, std::string const& text) override; write(beast::severities::Severity level, std::string const& text)
override;
void void
writeAlways(beast::severities::Severity level, std::string const& text) override; writeAlways(beast::severities::Severity level, std::string const& text)
override;
}; };
/** Manages a system file containing logged output. /** Manages a system file containing logged output.
@@ -134,7 +140,11 @@ private:
}; };
std::mutex mutable mutex_; std::mutex mutable mutex_;
std::map<std::string, std::unique_ptr<beast::Journal::Sink>, boost::beast::iless> sinks_; std::map<
std::string,
std::unique_ptr<beast::Journal::Sink>,
boost::beast::iless>
sinks_;
beast::severities::Severity thresh_; beast::severities::Severity thresh_;
File file_; File file_;
bool silent_ = false; bool silent_ = false;
@@ -191,7 +201,9 @@ public:
} }
virtual std::unique_ptr<beast::Journal::Sink> virtual std::unique_ptr<beast::Journal::Sink>
makeSink(std::string const& partition, beast::severities::Severity startingLevel); makeSink(
std::string const& partition,
beast::severities::Severity startingLevel);
public: public:
static LogSeverity static LogSeverity
@@ -261,3 +273,5 @@ beast::Journal
debugLog(); debugLog();
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,73 +0,0 @@
#pragma once
#include <xrpl/beast/utility/Journal.h>
#include <chrono>
#include <cstdint>
#include <string_view>
namespace xrpl {
// cSpell:ignore ptmalloc
// -----------------------------------------------------------------------------
// Allocator interaction note:
// - This facility invokes glibc's malloc_trim(0) on Linux/glibc to request that
// ptmalloc return free heap pages to the OS.
// - If an alternative allocator (e.g. jemalloc or tcmalloc) is linked or
// preloaded (LD_PRELOAD), calling glibc's malloc_trim typically has no effect
// on the *active* heap. The call is harmless but may not reclaim memory
// because those allocators manage their own arenas.
// - Only glibc sbrk/arena space is eligible for trimming; large mmap-backed
// allocations are usually returned to the OS on free regardless of trimming.
// - Call at known reclamation points (e.g., after cache sweeps / online delete)
// and consider rate limiting to avoid churn.
// -----------------------------------------------------------------------------
struct MallocTrimReport
{
bool supported{false};
int trimResult{-1};
std::int64_t rssBeforeKB{-1};
std::int64_t rssAfterKB{-1};
std::chrono::microseconds durationUs{-1};
std::int64_t minfltDelta{-1};
std::int64_t majfltDelta{-1};
[[nodiscard]] std::int64_t
deltaKB() const noexcept
{
if (rssBeforeKB < 0 || rssAfterKB < 0)
return 0;
return rssAfterKB - rssBeforeKB;
}
};
/**
* @brief Attempt to return freed memory to the operating system.
*
* On Linux with glibc malloc, this issues ::malloc_trim(0), which may release
* free space from ptmalloc arenas back to the kernel. On other platforms, or if
* a different allocator is in use, this function is a no-op and the report will
* indicate that trimming is unsupported or had no effect.
*
* @param tag Identifier for logging/debugging purposes.
* @param journal Journal for diagnostic logging.
* @return Report containing before/after metrics and the trim result.
*
* @note If an alternative allocator (jemalloc/tcmalloc) is linked or preloaded,
* calling glibc's malloc_trim may have no effect on the active heap. The
* call is harmless but typically does not reclaim memory under those
* allocators.
*
* @note Only memory served from glibc's sbrk/arena heaps is eligible for trim.
* Large allocations satisfied via mmap are usually returned on free
* independently of trimming.
*
* @note Intended for use after operations that free significant memory (e.g.,
* cache sweeps, ledger cleanup, online delete). Consider rate limiting.
*/
MallocTrimReport
mallocTrim(std::string_view tag, beast::Journal journal);
} // namespace xrpl

View File

@@ -1,4 +1,5 @@
#pragma once #ifndef XRPL_BASICS_MATHUTILITIES_H_INCLUDED
#define XRPL_BASICS_MATHUTILITIES_H_INCLUDED
#include <algorithm> #include <algorithm>
#include <cassert> #include <cassert>
@@ -44,3 +45,5 @@ static_assert(calculatePercent(50'000'001, 100'000'000) == 51);
static_assert(calculatePercent(99'999'999, 100'000'000) == 100); static_assert(calculatePercent(99'999'999, 100'000'000) == 100);
} // namespace xrpl } // namespace xrpl
#endif

View File

@@ -1,155 +0,0 @@
/*
This file is part of clio: https://github.com/XRPLF/clio
Copyright (c) 2024, 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.
*/
#pragma once
#include <mutex>
#include <type_traits>
namespace xrpl {
template <typename ProtectedDataType, typename MutexType>
class Mutex;
/**
* @brief A lock on a mutex that provides access to the protected data.
*
* @tparam ProtectedDataType data type to hold
* @tparam LockType type of lock
* @tparam MutexType type of mutex
*/
template <typename ProtectedDataType, template <typename...> typename LockType, typename MutexType>
class Lock
{
LockType<MutexType> lock_;
ProtectedDataType& data_;
public:
/** @cond */
ProtectedDataType const&
operator*() const
{
return data_;
}
ProtectedDataType&
operator*()
{
return data_;
}
ProtectedDataType const&
get() const
{
return data_;
}
ProtectedDataType&
get()
{
return data_;
}
ProtectedDataType const*
operator->() const
{
return &data_;
}
ProtectedDataType*
operator->()
{
return &data_;
}
operator LockType<MutexType>&() &
{
return lock_;
}
operator LockType<MutexType> const&() const&
{
return lock_;
}
/** @endcond */
private:
friend class Mutex<std::remove_const_t<ProtectedDataType>, MutexType>;
Lock(MutexType& mutex, ProtectedDataType& data) : lock_(mutex), data_(data)
{
}
};
/**
* @brief A container for data that is protected by a mutex. Inspired by Mutex in Rust.
*
* @tparam ProtectedDataType data type to hold
* @tparam MutexType type of mutex
*/
template <typename ProtectedDataType, typename MutexType = std::mutex>
class Mutex
{
mutable MutexType mutex_;
ProtectedDataType data_{};
public:
Mutex() = default;
/**
* @brief Construct a new Mutex object with the given data
*
* @param data The data to protect
*/
explicit Mutex(ProtectedDataType data) : data_(std::move(data))
{
}
/**
* @brief Make a new Mutex object with the given data
*
* @tparam Args The types of the arguments to forward to the constructor of the protected data
* @param args The arguments to forward to the constructor of the protected data
* @return The Mutex object that protects the given data
*/
template <typename... Args>
static Mutex
make(Args&&... args)
{
return Mutex{ProtectedDataType{std::forward<Args>(args)...}};
}
/**
* @brief Lock the mutex and get a lock object allowing access to the protected data
*
* @tparam LockType The type of lock to use
* @return A lock on the mutex and a reference to the protected data
*/
template <template <typename...> typename LockType = std::lock_guard>
Lock<ProtectedDataType const, LockType, MutexType>
lock() const
{
return {mutex_, data_};
}
/**
* @brief Lock the mutex and get a lock object allowing access to the protected data
*
* @tparam LockType The type of lock to use
* @return A lock on the mutex and a reference to the protected data
*/
template <template <typename...> typename LockType = std::lock_guard>
Lock<ProtectedDataType, LockType, MutexType>
lock()
{
return {mutex_, data_};
}
};
} // namespace xrpl

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