Compare commits

..

19 Commits

Author SHA1 Message Date
Jingchen
058b38a488 Merge branch 'develop' into a1q123456/add-levelization-python-script 2026-03-06 11:40:39 +00:00
Vito Tumas
5865bd017f refactor: Update transaction folder structure (#6483)
This change reorganizes the `tx/transactors` directory for consistency and discoverability. There are no behavioral changes, this is a pure refactor. Underscores were chosen as the way to separate multi-words as this is the more popular option in C++ projects.
 
Specific changes:
- Rename all subdirectories to lowercase/snake_case (`AMM` → `amm`, `Check` → `check`, `NFT` → `nft`, `PermissionedDomain` → `permissioned_domain`, etc.)
- Merge `AMM/` and `Offer/` into `dex/`, including `PermissionedDEXHelpers`
- Rename `MPT/` → `token/`, absorbing `SetTrust` and `Clawback`
- Move top-level transactors into named groups: `account/`, `bridge/`, `credentials/`, `did/`, `escrow/`, `oracle/`, `payment/`, `payment_channel/`, `system/`
- Update all include paths across the codebase and `transactions.macro`
2026-03-06 08:25:31 +00:00
Ayaz Salikhov
af0ec7defd chore: Apply gersemi changes (#6486) 2026-03-05 19:54:44 +00:00
Ayaz Salikhov
0c74270b05 chore: Use gersemi instead of ancient cmake-format (#6486) 2026-03-05 19:54:37 +00:00
Alex Kremer
dde450784d Add Formats and Flags to server_definitions (#6321)
This change implements https://github.com/XRPLF/XRPL-Standards/discussions/418: "System XLS: Add Formats and Flags to server_definitions".
2026-03-05 16:11:27 +00:00
Michael Legleux
08e734457f fix: Fix docs deployment for pull requests (#6482) 2026-03-05 00:12:41 -08:00
Michael Legleux
77518394e8 fix: Stop committing generated docs to prevent repo bloat (#6474) 2026-03-04 19:19:57 -08:00
Ayaz Salikhov
c69091bded chore: Add Git information compile-time info to only one file (#6464)
The existing code added the git commit info (`GIT_COMMIT_HASH` and `GIT_BRANCH`) to every file, which was a problem for leveraging `ccache` to cache build objects. This change adds a separate C++ file from where these compile-time variables are propagated to wherever they are needed. A new CMake file is added to set the commit info if the `git` binary is available.
2026-03-04 19:45:28 +00:00
Alex Kremer
595f0dd461 chore: Enable clang-tidy bugprone-sizeof-expression check (#6466) 2026-03-04 19:15:22 +00:00
Alex Kremer
b451d5e412 chore: Enable clang-tidy bugprone-return-const-ref-from-parameter check (#6459) 2026-03-04 18:10:10 +00:00
Alex Kremer
af97df5a63 chore: Enable clang-tidy bugprone-move-forwarding-reference check (#6457) 2026-03-04 17:03:27 +00:00
Peter Chen
e39954d128 fix: Gateway balance with MPT (#6143)
When `gateway_balances` gets called on an account that is involved in the `EscrowCreate` transaction (with MPT being escrowed), the method returns internal error. This change fixes this case by excluding the MPT type when totaling escrow amount.
2026-03-04 15:50:51 +00:00
tequ
3cd1e3d94e refactor: Update PermissionedDomainDelete to use keylet for sle access (#6063) 2026-03-04 04:11:58 +01:00
Ayaz Salikhov
fcec31ed20 chore: Update pre-commit hooks (#6460) 2026-03-03 20:23:22 +00:00
dependabot[bot]
0abd762781 ci: [DEPENDABOT] bump actions/upload-artifact from 6.0.0 to 7.0.0 (#6450) 2026-03-03 17:17:08 +00:00
Sergey Kuznetsov
5300e65686 tests: Improve stability of Subscribe tests (#6420)
The `Subscribe` tests were flaky, because each test performs some operations (e.g. sends transactions) and waits for messages to appear in subscription with a 100ms timeout. If tests are slow (e.g. compiled in debug mode or a slow machine) then some of them could fail. This change adds an attempt to synchronize the background Env's thread and the test's thread by ensuring that all the scheduled operations are started before the test's thread starts to wait for a websocket message. This is done by limiting I/O threads of the app inside Env to 1 and adding a synchronization barrier after closing the ledger.
2026-03-03 08:46:55 -05:00
Alex Kremer
afc660a1b5 refactor: Fix clang-tidy bugprone-empty-catch check (#6419)
This change fixes or suppresses instances detected by the `bugprone-empty-catch` clang-tidy check.
2026-03-02 17:08:56 +00:00
JCW
f638cbae3e Fixed errors
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
2026-02-17 17:08:37 +00:00
JCW
94737f399a Replace levelization shell script with the python version to optimise the performance 2026-02-17 17:08:03 +00:00
260 changed files with 3430 additions and 2175 deletions

View File

@@ -10,6 +10,7 @@ Checks: "-*,
bugprone-copy-constructor-init, bugprone-copy-constructor-init,
bugprone-dangling-handle, bugprone-dangling-handle,
bugprone-dynamic-static-initializers, bugprone-dynamic-static-initializers,
bugprone-empty-catch,
bugprone-fold-init-type, bugprone-fold-init-type,
bugprone-forward-declaration-namespace, bugprone-forward-declaration-namespace,
bugprone-inaccurate-erase, bugprone-inaccurate-erase,
@@ -23,6 +24,7 @@ Checks: "-*,
bugprone-misplaced-operator-in-strlen-in-alloc, bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-arithmetic-in-alloc, bugprone-misplaced-pointer-arithmetic-in-alloc,
bugprone-misplaced-widening-cast, bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multi-level-implicit-pointer-conversion, bugprone-multi-level-implicit-pointer-conversion,
bugprone-multiple-new-in-one-expression, bugprone-multiple-new-in-one-expression,
bugprone-multiple-statement-macro, bugprone-multiple-statement-macro,
@@ -31,10 +33,12 @@ Checks: "-*,
bugprone-parent-virtual-call, bugprone-parent-virtual-call,
bugprone-posix-return, bugprone-posix-return,
bugprone-redundant-branch-condition, bugprone-redundant-branch-condition,
bugprone-return-const-ref-from-parameter,
bugprone-shared-ptr-array-mismatch, bugprone-shared-ptr-array-mismatch,
bugprone-signal-handler, bugprone-signal-handler,
bugprone-signed-char-misuse, bugprone-signed-char-misuse,
bugprone-sizeof-container, bugprone-sizeof-container,
bugprone-sizeof-expression,
bugprone-spuriously-wake-up-functions, bugprone-spuriously-wake-up-functions,
bugprone-standalone-empty, bugprone-standalone-empty,
bugprone-string-constructor, bugprone-string-constructor,
@@ -81,17 +85,14 @@ Checks: "-*,
performance-trivially-destructible performance-trivially-destructible
" "
# --- # ---
# checks that have some issues that need to be resolved: # more checks that have some issues that need to be resolved:
# #
# bugprone-empty-catch,
# bugprone-crtp-constructor-accessibility, # bugprone-crtp-constructor-accessibility,
# bugprone-inc-dec-in-conditions, # bugprone-inc-dec-in-conditions,
# bugprone-reserved-identifier, # bugprone-reserved-identifier,
# bugprone-move-forwarding-reference, # bugprone-move-forwarding-reference,
# bugprone-unused-local-non-trivial-variable, # bugprone-unused-local-non-trivial-variable,
# bugprone-return-const-ref-from-parameter,
# bugprone-switch-missing-default-case, # bugprone-switch-missing-default-case,
# bugprone-sizeof-expression,
# bugprone-suspicious-stringview-data-usage, # bugprone-suspicious-stringview-data-usage,
# bugprone-suspicious-missing-comma, # bugprone-suspicious-missing-comma,
# bugprone-pointer-arithmetic-on-polymorphic-object, # bugprone-pointer-arithmetic-on-polymorphic-object,

View File

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

View File

@@ -70,7 +70,7 @@ that `test` code should _never_ be included in `xrpl` or `xrpld` code.)
## Validation ## Validation
The [levelization](generate.sh) script takes no parameters, The [levelization](generate.py) 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 `levelization.sh`, done anything else to improve levelization, run `generate.py`,
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 `levelization.sh` 1. Run `generate.py`
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`

369
.github/scripts/levelization/generate.py vendored Normal file
View File

@@ -0,0 +1,369 @@
#!/usr/bin/env python3
"""
Usage: generate.py
This script takes no parameters, and can be run from any directory,
as long as it is in the expected.
location in the repo.
"""
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_repo_root(start_path: Path, depth_limit: int = 10) -> Path:
"""
Find the repository root by looking for .git directory or src/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
# Check if this directory has src or include folders
has_src = (current / "src").exists()
has_include = (current / "include").exists()
if has_src or has_include:
return current
# Check if this is a git repository root
if (current / ".git").exists():
# Check if it has src or include nearby
if has_src or has_include:
return current
# 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 get_scan_directories(repo_root: Path) -> List[Path]:
"""
Get the list of directories to scan for include files.
Returns paths that actually exist.
"""
directories = []
for dir_name in ["include", "src"]:
dir_path = repo_root / dir_name
if dir_path.exists() and dir_path.is_dir():
directories.append(dir_path)
if not directories:
raise RuntimeError(f"No 'src' or 'include' directories found in {repo_root}")
return directories
def main():
# Change to the script's directory
script_dir = Path(__file__).parent.resolve()
os.chdir(script_dir)
# If the shell is interactive, clean up any flotsam before analyzing
# Match bash behavior: check if PS1 is set (indicates interactive shell)
# When running a script, PS1 is not set even if stdin/stdout are TTYs
if os.environ.get("PS1"):
try:
subprocess.run(["git", "clean", "-ix"], check=False, timeout=30)
except (subprocess.TimeoutExpired, KeyboardInterrupt):
print("Skipping git clean...")
except Exception:
# If git clean fails for any reason, just continue
pass
# 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 = find_repo_root(script_dir)
scan_dirs = get_scan_directories(repo_root)
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 larger buffer for better 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:
level = get_level(file_path)
include_level = extract_include_level(include_line)
if include_level and 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 behavior (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 optimization - 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()

View File

@@ -1,130 +0,0 @@
#!/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

@@ -32,13 +32,10 @@ We will further set additional CMake arguments as follows:
""" """
def generate_strategy_matrix(all: bool, config: Config, distro: str = "") -> list: def generate_strategy_matrix(all: bool, config: Config) -> list:
configurations = [] configurations = []
os_entries = config.os
if distro:
os_entries = [o for o in os_entries if o["distro_name"] == distro]
for architecture, os, build_type, cmake_args in itertools.product( for architecture, os, build_type, cmake_args in itertools.product(
config.architecture, os_entries, config.build_type, config.cmake_args config.architecture, config.os, config.build_type, config.cmake_args
): ):
# The default CMake target is 'all' for Linux and MacOS and 'install' # The default CMake target is 'all' for Linux and MacOS and 'install'
# for Windows, but it can get overridden for certain configurations. # for Windows, but it can get overridden for certain configurations.
@@ -226,7 +223,7 @@ def generate_strategy_matrix(all: bool, config: Config, distro: str = "") -> lis
if (n := os["compiler_version"]) != "": if (n := os["compiler_version"]) != "":
config_name += f"-{n}" config_name += f"-{n}"
config_name += ( config_name += (
f"-{architecture['platform'][architecture['platform'].find('/') + 1 :]}" f"-{architecture['platform'][architecture['platform'].find('/')+1:]}"
) )
config_name += f"-{build_type.lower()}" config_name += f"-{build_type.lower()}"
if "-Dcoverage=ON" in cmake_args: if "-Dcoverage=ON" in cmake_args:
@@ -316,32 +313,21 @@ if __name__ == "__main__":
required=False, required=False,
type=Path, type=Path,
) )
parser.add_argument(
"-d",
"--distro",
help="Filter OS entries to only include those with this distro_name (e.g. 'debian', 'rhel', 'ubuntu').",
required=False,
type=str,
default="",
)
args = parser.parse_args() args = parser.parse_args()
matrix = [] matrix = []
if args.config is None or args.config == "": if args.config is None or args.config == "":
matrix += generate_strategy_matrix( matrix += generate_strategy_matrix(
args.all, read_config(THIS_DIR / "linux.json"), args.distro args.all, read_config(THIS_DIR / "linux.json")
) )
matrix += generate_strategy_matrix( matrix += generate_strategy_matrix(
args.all, read_config(THIS_DIR / "macos.json"), args.distro args.all, read_config(THIS_DIR / "macos.json")
) )
matrix += generate_strategy_matrix( matrix += generate_strategy_matrix(
args.all, read_config(THIS_DIR / "windows.json"), args.distro args.all, read_config(THIS_DIR / "windows.json")
) )
else: else:
matrix += generate_strategy_matrix( matrix += generate_strategy_matrix(args.all, read_config(args.config))
args.all, read_config(args.config), args.distro
)
# Generate the strategy matrix. # Generate the strategy matrix.
print(f"matrix={json.dumps({'include': matrix})}") print(f"matrix={json.dumps({'include': matrix})}")
# print(json.dumps(matrix, indent=2))

View File

@@ -128,23 +128,12 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: os: [linux, macos, windows]
- os: linux
distro: debian
- os: linux
distro: rhel
- os: linux
distro: ubuntu
- os: macos
distro: ""
- os: windows
distro: ""
with: with:
# Enable ccache only for events targeting the XRPLF repository, since # Enable ccache only for events targeting the XRPLF repository, since
# other accounts will not have access to our remote cache storage. # other accounts will not have access to our remote cache storage.
ccache_enabled: ${{ github.repository_owner == 'XRPLF' }} ccache_enabled: ${{ github.repository_owner == 'XRPLF' }}
os: ${{ matrix.os }} os: ${{ matrix.os }}
distro: ${{ matrix.distro }}
secrets: secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -77,17 +77,7 @@ jobs:
strategy: strategy:
fail-fast: ${{ github.event_name == 'merge_group' }} fail-fast: ${{ github.event_name == 'merge_group' }}
matrix: matrix:
include: os: [linux, macos, windows]
- os: linux
distro: debian
- os: linux
distro: rhel
- os: linux
distro: ubuntu
- os: macos
distro: ""
- os: windows
distro: ""
with: with:
# Enable ccache only for events targeting the XRPLF repository, since # Enable ccache only for events targeting the XRPLF repository, since
# other accounts will not have access to our remote cache storage. # other accounts will not have access to our remote cache storage.
@@ -96,7 +86,6 @@ jobs:
# not identical to a regular compilation. # not identical to a regular compilation.
ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !startsWith(github.ref, 'refs/heads/release') }} ccache_enabled: ${{ github.repository_owner == 'XRPLF' && !startsWith(github.ref, 'refs/heads/release') }}
os: ${{ matrix.os }} os: ${{ matrix.os }}
distro: ${{ matrix.distro }}
strategy_matrix: ${{ github.event_name == 'schedule' && 'all' || 'minimal' }} strategy_matrix: ${{ github.event_name == 'schedule' && 'all' || 'minimal' }}
secrets: secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -40,15 +40,18 @@ env:
NPROC_SUBTRACT: ${{ github.event.repository.private && '1' || '2' }} NPROC_SUBTRACT: ${{ github.event.repository.private && '1' || '2' }}
jobs: jobs:
publish: build:
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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d
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@cf0433aa74563aead044a1e395610c96d65a37cf
id: nproc id: nproc
@@ -78,9 +81,23 @@ jobs:
cmake -Donly_docs=ON .. cmake -Donly_docs=ON ..
cmake --build . --target docs --parallel ${BUILD_NPROC} cmake --build . --target docs --parallel ${BUILD_NPROC}
- name: Publish documentation - name: Create documentation artifact
if: ${{ github.event_name == 'push' }} if: ${{ github.event_name == 'push' }}
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} path: ${{ env.BUILD_DIR }}/docs/html
publish_dir: ${{ env.BUILD_DIR }}/docs/html
deploy:
if: ${{ 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@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5

View File

@@ -177,7 +177,7 @@ jobs:
- name: Upload the binary (Linux) - name: Upload the binary (Linux)
if: ${{ github.repository_owner == 'XRPLF' && runner.os == 'Linux' }} if: ${{ github.repository_owner == 'XRPLF' && runner.os == 'Linux' }}
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: xrpld-${{ inputs.config_name }} name: xrpld-${{ inputs.config_name }}
path: ${{ env.BUILD_DIR }}/xrpld path: ${{ env.BUILD_DIR }}/xrpld

View File

@@ -26,12 +26,6 @@ on:
type: string type: string
default: "minimal" default: "minimal"
distro:
description: 'Filter to only include configs for this distro (e.g. "debian", "rhel", "ubuntu"). Leave empty for no filtering.'
required: false
type: string
default: ""
secrets: secrets:
CODECOV_TOKEN: CODECOV_TOKEN:
description: "The Codecov token to use for uploading coverage reports." description: "The Codecov token to use for uploading coverage reports."
@@ -44,11 +38,9 @@ jobs:
with: with:
os: ${{ inputs.os }} os: ${{ inputs.os }}
strategy_matrix: ${{ inputs.strategy_matrix }} strategy_matrix: ${{ inputs.strategy_matrix }}
distro: ${{ inputs.distro }}
# Build and test the binary for each configuration. # Build and test the binary for each configuration.
build-test-config: build-test-config:
name: ${{ matrix.config_name }}
needs: needs:
- generate-matrix - generate-matrix
uses: ./.github/workflows/reusable-build-test-config.yml uses: ./.github/workflows/reusable-build-test-config.yml

View File

@@ -20,7 +20,7 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check levelization - name: Check levelization
run: .github/scripts/levelization/generate.sh run: python .github/scripts/levelization/generate.py
- 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.sh' in your repo, commit Run '.github/scripts/levelization/generate.py' 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

@@ -84,7 +84,7 @@ jobs:
- name: Upload clang-tidy output - name: Upload clang-tidy output
if: steps.run_clang_tidy.outcome != 'success' if: steps.run_clang_tidy.outcome != 'success'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with: with:
name: clang-tidy-results name: clang-tidy-results
path: clang-tidy-output.txt path: clang-tidy-output.txt

View File

@@ -13,11 +13,6 @@ on:
required: false required: false
type: string type: string
default: "minimal" default: "minimal"
distro:
description: 'Filter to only include configs for this distro (e.g. "debian", "rhel", "ubuntu"). Leave empty for no filtering.'
required: false
type: string
default: ""
outputs: outputs:
matrix: matrix:
description: "The generated strategy matrix." description: "The generated strategy matrix."
@@ -47,5 +42,4 @@ jobs:
env: env:
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }} GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }}
GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }} GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }}
GENERATE_DISTRO: ${{ inputs.distro != '' && format('--distro={0}', inputs.distro) || '' }} run: ./generate.py ${GENERATE_OPTION} ${GENERATE_CONFIG} >> "${GITHUB_OUTPUT}"
run: ./generate.py ${GENERATE_OPTION} ${GENERATE_CONFIG} ${GENERATE_DISTRO} >> "${GITHUB_OUTPUT}"

3
.gitignore vendored
View File

@@ -75,6 +75,9 @@ DerivedData
/.claude /.claude
/CLAUDE.md /CLAUDE.md
# Python
__pycache__
# Direnv's directory # Direnv's directory
/.direnv /.direnv

View File

@@ -20,30 +20,29 @@ 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: 75ca4ad908dc4a99f57921f29b7e6c1521e10b26 # frozen: v21.1.8 rev: cd481d7b0bfb5c7b3090c21846317f9a8262e891 # frozen: v22.1.0
hooks: hooks:
- id: clang-format - id: clang-format
args: [--style=file] args: [--style=file]
"types_or": [c++, c, proto] "types_or": [c++, c, proto]
- repo: https://github.com/cheshirekow/cmake-format-precommit - repo: https://github.com/BlankSpruce/gersemi
rev: e2c2116d86a80e72e7146a06e68b7c228afc6319 # frozen: v0.6.13 rev: 0.26.0
hooks: hooks:
- id: cmake-format - id: gersemi
additional_dependencies: [PyYAML]
- repo: https://github.com/rbubley/mirrors-prettier - repo: https://github.com/rbubley/mirrors-prettier
rev: 5ba47274f9b181bce26a5150a725577f3c336011 # frozen: v3.6.2 rev: c2bc67fe8f8f549cc489e00ba8b45aa18ee713b1 # frozen: v3.8.1
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: 831207fd435b47aeffdf6af853097e64322b4d44 # frozen: v25.12.0 rev: ea488cebbfd88a5f50b8bd95d5c829d0bb76feb8 # frozen: 26.1.0
hooks: hooks:
- id: black - id: black
- repo: https://github.com/streetsidesoftware/cspell-cli - repo: https://github.com/streetsidesoftware/cspell-cli
rev: 1cfa010f078c354f3ffb8413616280cc28f5ba21 # frozen: v9.4.0 rev: a42085ade523f591dca134379a595e7859986445 # frozen: v9.7.0
hooks: hooks:
- id: cspell # Spell check changed files - id: cspell # Spell check changed files
exclude: .config/cspell.config.yaml exclude: .config/cspell.config.yaml

View File

@@ -22,6 +22,19 @@ API version 2 is available in `rippled` version 2.0.0 and later. See [API-VERSIO
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
This section contains changes targeting a future version.
### Additions
- `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.
## XRP Ledger server version 3.1.0 ## 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. [Version 3.1.0](https://github.com/XRPLF/rippled/releases/tag/3.1.0) was released on Jan 27, 2026.

View File

@@ -1,16 +1,16 @@
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) 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 () 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)
@@ -21,77 +21,64 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CompilationEnv) include(CompilationEnv)
if (is_gcc) if(is_gcc)
# GCC-specific fixes # GCC-specific fixes
add_compile_options(-Wno-unknown-pragmas -Wno-subobject-linkage) add_compile_options(-Wno-unknown-pragmas -Wno-subobject-linkage)
# -Wno-subobject-linkage can be removed when we upgrade GCC version to at least 13.3 # -Wno-subobject-linkage can be removed when we upgrade GCC version to at least 13.3
elseif (is_clang) elseif(is_clang)
# Clang-specific fixes # Clang-specific fixes
add_compile_options(-Wno-unknown-warning-option) # Ignore unknown warning options add_compile_options(-Wno-unknown-warning-option) # Ignore unknown warning options
elseif (is_msvc) elseif(is_msvc)
# MSVC-specific fixes # MSVC-specific fixes
add_compile_options(/wd4068) # Ignore unknown pragmas add_compile_options(/wd4068) # Ignore unknown pragmas
endif () 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 if(thread_safety_analysis)
find_package(Git) add_compile_options(
if (Git_FOUND) -Wthread-safety
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
HEAD OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gch) -DXRPL_ENABLE_THREAD_SAFETY_ANNOTATIONS
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)
add_compile_options(-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
-DXRPL_ENABLE_THREAD_SAFETY_ANNOTATIONS)
add_compile_options("-stdlib=libc++") add_compile_options("-stdlib=libc++")
add_link_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(FATAL_ERROR "The target option has been removed - use native cmake options to control build" message(
FATAL_ERROR
"The target option has been removed - use native cmake options to control build"
) )
endif () 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 because of the early return statement
if (packages_only) if(packages_only)
if (NOT TARGET rpm) if(NOT TARGET rpm)
message(FATAL_ERROR "packages_only requested, but targets were not created - is docker installed?" message(
FATAL_ERROR
"packages_only requested, but targets were not created - is docker installed?"
) )
endif () endif()
return() return()
endif () endif()
include(XrplCompiler) include(XrplCompiler)
include(XrplSanitizers) include(XrplSanitizers)
include(XrplInterface) 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)
@@ -110,42 +97,46 @@ find_package(xxHash REQUIRED)
target_link_libraries( target_link_libraries(
xrpl_libs xrpl_libs
INTERFACE 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(RocksDB::rocksdb PROPERTIES INTERFACE_COMPILE_DEFINITIONS set_target_properties(
XRPL_ROCKSDB_AVAILABLE=1) RocksDB::rocksdb
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) 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

@@ -1,29 +1,32 @@
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(COMMAND ${GIT_EXECUTABLE} "rev-parse" "--abbrev-ref" "HEAD" execute_process(
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} "rev-parse" "--abbrev-ref" "HEAD"
RESULT_VARIABLE _git_exit_code WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE _temp_branch RESULT_VARIABLE _git_exit_code
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) OUTPUT_VARIABLE _temp_branch
if (_git_exit_code EQUAL 0) OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
)
if(_git_exit_code EQUAL 0)
set(_branch ${_temp_branch}) set(_branch ${_temp_branch})
endif () endif()
set(${branch_val} "${_branch}" PARENT_SCOPE) set(${branch_val} "${_branch}" PARENT_SCOPE)
endfunction () endfunction()

View File

@@ -1,50 +1,62 @@
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 case we have to find the executable it
# points to. If we cannot find the target executable then we cannot use ccache. # 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(COMMAND bash -c execute_process(
"export LC_ALL='en_US.UTF-8'; ${CCACHE_PATH} --shimgen-noop | grep -oP 'path to executable: \\K.+' | head -c -1" COMMAND
OUTPUT_VARIABLE CCACHE_PATH) bash -c
"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 "CLToolExe=cl.exe" "CLToolPath=${CMAKE_BINARY_DIR}" "TrackFileAccess=false" set(CMAKE_VS_GLOBALS
"UseMultiToolTask=true") "CLToolExe=cl.exe"
"CLToolPath=${CMAKE_BINARY_DIR}"
"TrackFileAccess=false"
"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, which is not compatible with ccache, so
# tell it to use /Z7 instead. # tell it to use /Z7 instead.
if (MSVC) if(MSVC)
foreach (var_ CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG foreach(
CMAKE_CXX_FLAGS_RELEASE) var_
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
)
string(REPLACE "/Zi" "/Z7" ${var_} "${${var_}}") string(REPLACE "/Zi" "/Z7" ${var_} "${${var_}}")
endforeach () endforeach()
endif () endif()

View File

@@ -174,37 +174,45 @@ 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(COMMAND xcrun -f llvm-cov OUTPUT_VARIABLE LLVMCOV_PATH execute_process(
OUTPUT_STRIP_TRAILING_WHITESPACE) COMMAND xcrun -f llvm-cov
else () OUTPUT_VARIABLE LLVMCOV_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else()
find_program(LLVMCOV_PATH llvm-cov) find_program(LLVMCOV_PATH llvm-cov)
endif () endif()
if (LLVMCOV_PATH) if(LLVMCOV_PATH)
set(GCOV_TOOL "${LLVMCOV_PATH} gcov") set(GCOV_TOOL "${LLVMCOV_PATH} gcov")
endif () endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
find_program(GCOV_PATH gcov) find_program(GCOV_PATH gcov)
set(GCOV_TOOL "${GCOV_PATH}") set(GCOV_TOOL "${GCOV_PATH}")
endif () endif()
# Check supported compiler (Clang, GNU and Flang) # Check supported compiler (Clang, GNU and Flang)
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach (LANG ${LANGUAGES}) foreach(LANG ${LANGUAGES})
if ("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
if ("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3) if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3)
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") message(
endif () FATAL_ERROR
elseif (NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU" AND NOT "${CMAKE_${LANG}_COMPILER_ID}" "Clang version must be 3.0.0 or greater! Aborting..."
MATCHES "(LLVM)?[Ff]lang") )
endif()
elseif(
NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU"
AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(LLVM)?[Ff]lang"
)
message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...") message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...")
endif () endif()
endforeach () endforeach()
set(COVERAGE_COMPILER_FLAGS "-g --coverage" CACHE INTERNAL "") set(COVERAGE_COMPILER_FLAGS "-g --coverage" CACHE INTERNAL "")
@@ -213,7 +221,7 @@ set(COVERAGE_C_COMPILER_FLAGS "")
set(COVERAGE_CXX_LINKER_FLAGS "") set(COVERAGE_CXX_LINKER_FLAGS "")
set(COVERAGE_C_LINKER_FLAGS "") set(COVERAGE_C_LINKER_FLAGS "")
if (CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
include(CheckLinkerFlag) include(CheckLinkerFlag)
@@ -224,51 +232,77 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
set(COVERAGE_C_LINKER_FLAGS ${COVERAGE_COMPILER_FLAGS}) set(COVERAGE_C_LINKER_FLAGS ${COVERAGE_COMPILER_FLAGS})
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 "${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-abs-path") set(COVERAGE_CXX_COMPILER_FLAGS
endif () "${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-abs-path"
)
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 "${COVERAGE_C_COMPILER_FLAGS} -fprofile-abs-path") set(COVERAGE_C_COMPILER_FLAGS
endif () "${COVERAGE_C_COMPILER_FLAGS} -fprofile-abs-path"
)
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 "${COVERAGE_CXX_LINKER_FLAGS} -fprofile-abs-path") set(COVERAGE_CXX_LINKER_FLAGS
endif () "${COVERAGE_CXX_LINKER_FLAGS} -fprofile-abs-path"
)
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 "${COVERAGE_C_LINKER_FLAGS} -fprofile-abs-path") set(COVERAGE_C_LINKER_FLAGS
endif () "${COVERAGE_C_LINKER_FLAGS} -fprofile-abs-path"
)
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 "${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-update=atomic") set(COVERAGE_CXX_COMPILER_FLAGS
endif () "${COVERAGE_CXX_COMPILER_FLAGS} -fprofile-update=atomic"
)
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 "${COVERAGE_C_COMPILER_FLAGS} -fprofile-update=atomic") set(COVERAGE_C_COMPILER_FLAGS
endif () "${COVERAGE_C_COMPILER_FLAGS} -fprofile-update=atomic"
)
endif()
check_linker_flag(CXX -fprofile-update=atomic HAVE_cxx_linker_fprofile_update) check_linker_flag(
if (HAVE_cxx_linker_fprofile_update) CXX
set(COVERAGE_CXX_LINKER_FLAGS "${COVERAGE_CXX_LINKER_FLAGS} -fprofile-update=atomic") -fprofile-update=atomic
endif () HAVE_cxx_linker_fprofile_update
)
if(HAVE_cxx_linker_fprofile_update)
set(COVERAGE_CXX_LINKER_FLAGS
"${COVERAGE_CXX_LINKER_FLAGS} -fprofile-update=atomic"
)
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 "${COVERAGE_C_LINKER_FLAGS} -fprofile-update=atomic") set(COVERAGE_C_LINKER_FLAGS
endif () "${COVERAGE_C_LINKER_FLAGS} -fprofile-update=atomic"
)
endif()
endif()
endif () get_property(
GENERATOR_IS_MULTI_CONFIG
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) GLOBAL
if (NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)) PROPERTY GENERATOR_IS_MULTI_CONFIG
message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") )
endif () # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG) if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG))
message(
WARNING
"Code coverage results with an optimised (non-Debug) build may be misleading"
)
endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)
# Defines a target for running and collection code coverage information # Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports. # Builds dependencies, runs the given executable and outputs reports.
@@ -292,125 +326,167 @@ endif () # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)
# ) # )
# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the # The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the
# GCVOR command. # GCVOR command.
function (setup_target_for_coverage_gcovr) function(setup_target_for_coverage_gcovr)
set(options NONE) set(options NONE)
set(oneValueArgs BASE_DIRECTORY NAME FORMAT) set(oneValueArgs BASE_DIRECTORY NAME FORMAT)
set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(
Coverage
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${ARGN}
)
if (NOT GCOV_TOOL) if(NOT GCOV_TOOL)
message(FATAL_ERROR "Could not find gcov or llvm-cov tool! Aborting...") message(FATAL_ERROR "Could not find gcov or llvm-cov tool! Aborting...")
endif () endif()
if (NOT GCOVR_PATH) if(NOT GCOVR_PATH)
message(FATAL_ERROR "Could not find gcovr tool! Aborting...") message(FATAL_ERROR "Could not find gcovr tool! Aborting...")
endif () endif()
# Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR
if (DEFINED Coverage_BASE_DIRECTORY) if(DEFINED Coverage_BASE_DIRECTORY)
get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE)
else () else()
set(BASEDIR ${PROJECT_SOURCE_DIR}) set(BASEDIR ${PROJECT_SOURCE_DIR})
endif () endif()
if (NOT DEFINED Coverage_FORMAT) if(NOT DEFINED Coverage_FORMAT)
set(Coverage_FORMAT xml) set(Coverage_FORMAT xml)
endif () endif()
if (NOT DEFINED Coverage_EXECUTABLE AND DEFINED Coverage_EXECUTABLE_ARGS) if(NOT DEFINED Coverage_EXECUTABLE AND DEFINED Coverage_EXECUTABLE_ARGS)
message(FATAL_ERROR "EXECUTABLE_ARGS must not be set if EXECUTABLE is not set") message(
endif () FATAL_ERROR
"EXECUTABLE_ARGS must not be set if EXECUTABLE is not set"
if ("--output" IN_LIST GCOVR_ADDITIONAL_ARGS)
message(FATAL_ERROR "Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting..."
) )
else () endif()
if ((Coverage_FORMAT STREQUAL "html-details") OR (Coverage_FORMAT STREQUAL "html-nested"))
set(GCOVR_OUTPUT_FILE ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html)
set(GCOVR_CREATE_FOLDER ${PROJECT_BINARY_DIR}/${Coverage_NAME})
elseif (Coverage_FORMAT STREQUAL "html-single")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.html)
elseif ((Coverage_FORMAT STREQUAL "json-summary") OR (Coverage_FORMAT STREQUAL
"json-details")
OR (Coverage_FORMAT STREQUAL "coveralls"))
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.json)
elseif (Coverage_FORMAT STREQUAL "txt")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.txt)
elseif (Coverage_FORMAT STREQUAL "csv")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.csv)
elseif (Coverage_FORMAT STREQUAL "lcov")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.lcov)
else ()
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.xml)
endif ()
endif ()
if ((Coverage_FORMAT STREQUAL "cobertura") OR (Coverage_FORMAT STREQUAL "xml")) if("--output" IN_LIST GCOVR_ADDITIONAL_ARGS)
message(
FATAL_ERROR
"Unsupported --output option detected in GCOVR_ADDITIONAL_ARGS! Aborting..."
)
else()
if(
(Coverage_FORMAT STREQUAL "html-details")
OR (Coverage_FORMAT STREQUAL "html-nested")
)
set(GCOVR_OUTPUT_FILE
${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html
)
set(GCOVR_CREATE_FOLDER ${PROJECT_BINARY_DIR}/${Coverage_NAME})
elseif(Coverage_FORMAT STREQUAL "html-single")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.html)
elseif(
(Coverage_FORMAT STREQUAL "json-summary")
OR (Coverage_FORMAT STREQUAL "json-details")
OR (Coverage_FORMAT STREQUAL "coveralls")
)
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.json)
elseif(Coverage_FORMAT STREQUAL "txt")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.txt)
elseif(Coverage_FORMAT STREQUAL "csv")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.csv)
elseif(Coverage_FORMAT STREQUAL "lcov")
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.lcov)
else()
set(GCOVR_OUTPUT_FILE ${Coverage_NAME}.xml)
endif()
endif()
if(
(Coverage_FORMAT STREQUAL "cobertura")
OR (Coverage_FORMAT STREQUAL "xml")
)
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura "${GCOVR_OUTPUT_FILE}")
list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura-pretty) list(APPEND GCOVR_ADDITIONAL_ARGS --cobertura-pretty)
set(Coverage_FORMAT cobertura) # overwrite xml set(Coverage_FORMAT cobertura) # overwrite xml
elseif (Coverage_FORMAT STREQUAL "sonarqube") elseif(Coverage_FORMAT STREQUAL "sonarqube")
list(APPEND GCOVR_ADDITIONAL_ARGS --sonarqube "${GCOVR_OUTPUT_FILE}") list(APPEND GCOVR_ADDITIONAL_ARGS --sonarqube "${GCOVR_OUTPUT_FILE}")
elseif (Coverage_FORMAT STREQUAL "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(FATAL_ERROR "Unsupported output style ${Coverage_FORMAT}! Aborting...") message(
endif () FATAL_ERROR
"Unsupported output style ${Coverage_FORMAT}! Aborting..."
)
endif()
# Collect excludes (CMake 3.4+: Also compute absolute paths) # Collect excludes (CMake 3.4+: Also compute absolute paths)
set(GCOVR_EXCLUDES "") set(GCOVR_EXCLUDES "")
foreach (EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES}) foreach(
if (CMAKE_VERSION VERSION_GREATER 3.4) EXCLUDE
get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR}) ${Coverage_EXCLUDE}
endif () ${COVERAGE_EXCLUDES}
${COVERAGE_GCOVR_EXCLUDES}
)
if(CMAKE_VERSION VERSION_GREATER 3.4)
get_filename_component(
EXCLUDE
${EXCLUDE}
ABSOLUTE
BASE_DIR ${BASEDIR}
)
endif()
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
endforeach () endforeach()
list(REMOVE_DUPLICATES GCOVR_EXCLUDES) list(REMOVE_DUPLICATES GCOVR_EXCLUDES)
# Combine excludes to several -e arguments # Combine excludes to several -e arguments
set(GCOVR_EXCLUDE_ARGS "") set(GCOVR_EXCLUDE_ARGS "")
foreach (EXCLUDE ${GCOVR_EXCLUDES}) foreach(EXCLUDE ${GCOVR_EXCLUDES})
list(APPEND GCOVR_EXCLUDE_ARGS "-e") list(APPEND GCOVR_EXCLUDE_ARGS "-e")
list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}") list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}")
endforeach () endforeach()
# Set up commands which will be run to generate coverage data # Set up commands which will be run to generate coverage data
# If EXECUTABLE is not set, the user is expected to run the tests manually # If EXECUTABLE is not set, the user is expected to run the tests manually
# 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 ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}) set(GCOVR_EXEC_TESTS_CMD
endif () ${Coverage_EXECUTABLE}
${Coverage_EXECUTABLE_ARGS}
)
endif()
# Create folder # Create folder
if (DEFINED GCOVR_CREATE_FOLDER) if(DEFINED GCOVR_CREATE_FOLDER)
set(GCOVR_FOLDER_CMD ${CMAKE_COMMAND} -E make_directory ${GCOVR_CREATE_FOLDER}) set(GCOVR_FOLDER_CMD
endif () ${CMAKE_COMMAND}
-E
make_directory
${GCOVR_CREATE_FOLDER}
)
endif()
# Running gcovr # Running gcovr
set(GCOVR_CMD set(GCOVR_CMD
@@ -422,56 +498,95 @@ function (setup_target_for_coverage_gcovr)
${BASEDIR} ${BASEDIR}
${GCOVR_ADDITIONAL_ARGS} ${GCOVR_ADDITIONAL_ARGS}
${GCOVR_EXCLUDE_ARGS} ${GCOVR_EXCLUDE_ARGS}
--object-directory=${PROJECT_BINARY_DIR}) --object-directory=${PROJECT_BINARY_DIR}
)
if (CODE_COVERAGE_VERBOSE) if(CODE_COVERAGE_VERBOSE)
message(STATUS "Executed command report") message(STATUS "Executed command report")
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(REPLACE ";" " " GCOVR_EXEC_TESTS_CMD_SPACED "${GCOVR_EXEC_TESTS_CMD}") string(
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(REPLACE ";" " " GCOVR_FOLDER_CMD_SPACED "${GCOVR_FOLDER_CMD}") string(
REPLACE ";"
" "
GCOVR_FOLDER_CMD_SPACED
"${GCOVR_FOLDER_CMD}"
)
message(STATUS "${GCOVR_FOLDER_CMD_SPACED}") message(STATUS "${GCOVR_FOLDER_CMD_SPACED}")
endif () endif()
message(STATUS "Command to generate gcovr coverage data: ") message(STATUS "Command to generate gcovr coverage data: ")
string(REPLACE ";" " " GCOVR_CMD_SPACED "${GCOVR_CMD}") string(REPLACE ";" " " GCOVR_CMD_SPACED "${GCOVR_CMD}")
message(STATUS "${GCOVR_CMD_SPACED}") message(STATUS "${GCOVR_CMD_SPACED}")
endif () endif()
add_custom_target(${Coverage_NAME} add_custom_target(
COMMAND ${GCOVR_EXEC_TESTS_CMD} ${Coverage_NAME}
COMMAND ${GCOVR_FOLDER_CMD} COMMAND ${GCOVR_EXEC_TESTS_CMD}
COMMAND ${GCOVR_CMD} COMMAND ${GCOVR_FOLDER_CMD}
BYPRODUCTS ${GCOVR_OUTPUT_FILE} COMMAND ${GCOVR_CMD}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR} BYPRODUCTS ${GCOVR_OUTPUT_FILE}
DEPENDS ${Coverage_DEPENDENCIES} WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
VERBATIM # Protect arguments to commands DEPENDS ${Coverage_DEPENDENCIES}
COMMENT "Running gcovr to produce code coverage report.") VERBATIM # Protect arguments to commands
COMMENT "Running gcovr to produce code coverage report."
)
# 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 COMMAND echo TARGET ${Coverage_NAME}
COMMENT "Code coverage report saved in ${GCOVR_OUTPUT_FILE} formatted as ${Coverage_FORMAT}" POST_BUILD
COMMAND echo
COMMENT
"Code coverage report saved in ${GCOVR_OUTPUT_FILE} formatted as ${Coverage_FORMAT}"
) )
endfunction () # setup_target_for_coverage_gcovr endfunction() # setup_target_for_coverage_gcovr
function (add_code_coverage_to_target name scope) function(add_code_coverage_to_target name scope)
separate_arguments(COVERAGE_CXX_COMPILER_FLAGS NATIVE_COMMAND "${COVERAGE_CXX_COMPILER_FLAGS}") separate_arguments(
separate_arguments(COVERAGE_C_COMPILER_FLAGS NATIVE_COMMAND "${COVERAGE_C_COMPILER_FLAGS}") COVERAGE_CXX_COMPILER_FLAGS
separate_arguments(COVERAGE_CXX_LINKER_FLAGS NATIVE_COMMAND "${COVERAGE_CXX_LINKER_FLAGS}") NATIVE_COMMAND
separate_arguments(COVERAGE_C_LINKER_FLAGS NATIVE_COMMAND "${COVERAGE_C_LINKER_FLAGS}") "${COVERAGE_CXX_COMPILER_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} $<$<COMPILE_LANGUAGE:CXX>:${COVERAGE_CXX_COMPILER_FLAGS}> ${name}
$<$<COMPILE_LANGUAGE:C>:${COVERAGE_C_COMPILER_FLAGS}>) ${scope}
$<$<COMPILE_LANGUAGE:CXX>:${COVERAGE_CXX_COMPILER_FLAGS}>
$<$<COMPILE_LANGUAGE:C>:${COVERAGE_C_COMPILER_FLAGS}>
)
target_link_libraries(${name} ${scope} $<$<LINK_LANGUAGE:CXX>:${COVERAGE_CXX_LINKER_FLAGS}> target_link_libraries(
$<$<LINK_LANGUAGE:C>:${COVERAGE_C_LINKER_FLAGS}>) ${name}
endfunction () # add_code_coverage_to_target ${scope}
$<$<LINK_LANGUAGE:CXX>:${COVERAGE_CXX_LINKER_FLAGS}>
$<$<LINK_LANGUAGE:C>:${COVERAGE_C_LINKER_FLAGS}>
)
endfunction() # add_code_coverage_to_target

View File

@@ -14,20 +14,20 @@ set(is_gcc FALSE)
set(is_msvc FALSE) set(is_msvc FALSE)
set(is_xcode 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 # Xcode generator detection
if (CMAKE_GENERATOR STREQUAL "Xcode") if(CMAKE_GENERATOR STREQUAL "Xcode")
set(is_xcode TRUE) set(is_xcode TRUE)
endif () endif()
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Operating system detection # Operating system detection
@@ -36,23 +36,23 @@ set(is_linux FALSE)
set(is_windows FALSE) 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()
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# Architecture # Architecture
# -------------------------------------------------------------------- # --------------------------------------------------------------------
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|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()

28
cmake/GitInfo.cmake Normal file
View File

@@ -0,0 +1,28 @@
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,13 +1,17 @@
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(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp" file(
"${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp") GLOB_RECURSE sources
CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp"
)
add_executable(${target} ${ARGN} ${sources}) add_executable(${target} ${ARGN} ${sources})
isolate_headers(${target} "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/tests/${name}" PRIVATE) isolate_headers(${target} "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/tests/${name}" PRIVATE)
add_test(NAME ${target} COMMAND ${target}) add_test(NAME ${target} COMMAND ${target})
endfunction () endfunction()

View File

@@ -14,33 +14,42 @@ 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(common PROPERTIES INTERFACE_POSITION_INDEPENDENT_CODE set_target_properties(
${CMAKE_POSITION_INDEPENDENT_CODE}) common
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 $<$<CONFIG:Debug>:DEBUG INTERFACE
_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 (var_ CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG foreach(
CMAKE_CXX_FLAGS_RELEASE) var_
CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_RELEASE
CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_RELEASE
)
# also remove dynamic runtime # also remove dynamic runtime
string(REGEX REPLACE "[-/]MD[d]*" " " ${var_} "${${var_}}") string(REGEX REPLACE "[-/]MD[d]*" " " ${var_} "${${var_}}")
@@ -48,120 +57,143 @@ if (MSVC)
string(REPLACE "/ZI" "/Zi" ${var_} "${${var_}}") string(REPLACE "/ZI" "/Zi" ${var_} "${${var_}}")
# omit debug info completely under CI (not needed) # omit debug info completely under CI (not needed)
if (is_ci) if(is_ci)
string(REPLACE "/Zi" " " ${var_} "${${var_}}") string(REPLACE "/Zi" " " ${var_} "${${var_}}")
string(REPLACE "/Z7" " " ${var_} "${${var_}}") string(REPLACE "/Z7" " " ${var_} "${${var_}}")
endif () endif()
endforeach () endforeach()
target_compile_options( target_compile_options(
common common
INTERFACE # Increase object file max size INTERFACE # Increase object file max size
-bigobj -bigobj
# Floating point behavior # Floating point behavior
-fp:precise -fp:precise
# __cdecl calling convention # __cdecl calling convention
-Gd -Gd
# Minimal rebuild: disabled # Minimal rebuild: disabled
-Gm- -Gm-
# Function level linking: disabled # Function level linking: disabled
-Gy- -Gy-
# Multiprocessor compilation # Multiprocessor compilation
-MP -MP
# pragma omp: disabled # pragma omp: disabled
-openmp- -openmp-
# No error reporting to Internet # No error reporting to Internet
-errorReport:none -errorReport:none
# Suppress login banner # Suppress login banner
-nologo -nologo
# Disable signed/unsigned comparison warnings # Disable signed/unsigned comparison warnings
-wd4018 -wd4018
# Disable float to int possible loss of data warnings # Disable float to int possible loss of data warnings
-wd4244 -wd4244
# Disable size_t to T possible loss of data warnings # Disable size_t to T possible loss of data warnings
-wd4267 -wd4267
# Disable C4800(int to bool performance) # Disable C4800(int to bool performance)
-wd4800 -wd4800
# Decorated name length exceeded, name was truncated # Decorated name length exceeded, name was truncated
-wd4503 -wd4503
$<$<COMPILE_LANGUAGE:CXX>: $<$<COMPILE_LANGUAGE:CXX>:
-EHa -EHa
-GR -GR
> >
$<$<CONFIG:Release>:-Ox> $<$<CONFIG:Release>:-Ox>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>: $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:
-GS -GS
-Zc:forScope -Zc:forScope
> >
# static runtime # static runtime
$<$<CONFIG:Debug>:-MTd> $<$<CONFIG:Debug>:-MTd>
$<$<NOT:$<CONFIG:Debug>>:-MT> $<$<NOT:$<CONFIG:Debug>>:-MT>
$<$<BOOL:${werr}>:-WX>) $<$<BOOL:${werr}>:-WX>
)
target_compile_definitions( target_compile_definitions(
common common
INTERFACE _WIN32_WINNT=0x6000 INTERFACE
_SCL_SECURE_NO_WARNINGS _WIN32_WINNT=0x6000
_CRT_SECURE_NO_WARNINGS _SCL_SECURE_NO_WARNINGS
WIN32_CONSOLE _CRT_SECURE_NO_WARNINGS
WIN32_LEAN_AND_MEAN WIN32_CONSOLE
NOMINMAX WIN32_LEAN_AND_MEAN
# TODO: Resolve these warnings, don't just silence them NOMINMAX
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS # TODO: Resolve these warnings, don't just silence them
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:_CRTDBG_MAP_ALLOC>) _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:_CRTDBG_MAP_ALLOC>
)
target_link_libraries(common INTERFACE -errorreport:none -machine:X64) target_link_libraries(common INTERFACE -errorreport:none -machine:X64)
else () else()
target_compile_options( target_compile_options(
common common
INTERFACE -Wall INTERFACE
-Wdeprecated -Wall
$<$<BOOL:${is_clang}>:-Wno-deprecated-declarations> -Wdeprecated
$<$<BOOL:${wextra}>:-Wextra $<$<BOOL:${is_clang}>:-Wno-deprecated-declarations>
-Wno-unused-parameter> $<$<BOOL:${wextra}>:-Wextra
$<$<BOOL:${werr}>:-Werror> -Wno-unused-parameter>
-fstack-protector $<$<BOOL:${werr}>:-Werror>
-Wno-sign-compare -fstack-protector
-Wno-unused-but-set-variable -Wno-sign-compare
$<$<NOT:$<CONFIG:Debug>>:-fno-strict-aliasing> -Wno-unused-but-set-variable
# tweak gcc optimization for debug $<$<NOT:$<CONFIG:Debug>>:-fno-strict-aliasing>
$<$<AND:$<BOOL:${is_gcc}>,$<CONFIG:Debug>>:-O0> # tweak gcc optimization for debug
# Add debug symbols to release config $<$<AND:$<BOOL:${is_gcc}>,$<CONFIG:Debug>>:-O0>
$<$<CONFIG:Release>:-g>) # Add debug symbols to release config
$<$<CONFIG:Release>:-g>
)
target_link_libraries( target_link_libraries(
common common
INTERFACE -rdynamic INTERFACE
$<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now,--build-id> -rdynamic
# link to static libc/c++ iff: * static option set and * NOT APPLE (AppleClang does not support static $<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now,--build-id>
# libc/c++) and * NOT SANITIZERS (sanitizers typically don't work with static libc/c++) # link to static libc/c++ iff: * static option set and * NOT APPLE (AppleClang does not support static
$<$<AND:$<BOOL:${static}>,$<NOT:$<BOOL:${APPLE}>>,$<NOT:$<BOOL:${SANITIZERS_ENABLED}>>>: # libc/c++) and * NOT SANITIZERS (sanitizers typically don't work with static libc/c++)
-static-libstdc++ $<$<AND:$<BOOL:${static}>,$<NOT:$<BOOL:${APPLE}>>,$<NOT:$<BOOL:${SANITIZERS_ENABLED}>>>:
-static-libgcc -static-libstdc++
>) -static-libgcc
endif () >
)
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(FATAL_ERROR "Antithesis instrumentation requires Debug build type, aborting...") message(
elseif (NOT is_linux) FATAL_ERROR
message(FATAL_ERROR "Antithesis instrumentation requires Linux, aborting...") "Antithesis instrumentation requires Debug build type, 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 () elseif(NOT is_linux)
endif () message(
FATAL_ERROR
"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(COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=mold -Wl,--version ERROR_QUIET execute_process(
OUTPUT_VARIABLE LD_VERSION) COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=mold -Wl,--version
if ("${LD_VERSION}" MATCHES "mold") ERROR_QUIET
OUTPUT_VARIABLE LD_VERSION
)
if("${LD_VERSION}" MATCHES "mold")
target_link_libraries(common INTERFACE -fuse-ld=mold) target_link_libraries(common INTERFACE -fuse-ld=mold)
endif () endif()
unset(LD_VERSION) unset(LD_VERSION)
elseif (use_gold AND is_gcc) elseif(use_gold AND is_gcc)
# use gold linker if available # use gold linker if available
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET execute_process(
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
@@ -175,32 +207,37 @@ 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 -fuse-ld=gold INTERFACE
-Wl,--no-as-needed -fuse-ld=gold
#[=========================================================[ -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(COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=lld -Wl,--version ERROR_QUIET execute_process(
OUTPUT_VARIABLE LD_VERSION) COMMAND ${CMAKE_CXX_COMPILER} -fuse-ld=lld -Wl,--version
if ("${LD_VERSION}" MATCHES "LLD") ERROR_QUIET
OUTPUT_VARIABLE LD_VERSION
)
if("${LD_VERSION}" MATCHES "LLD")
target_link_libraries(common INTERFACE -fuse-ld=lld) target_link_libraries(common INTERFACE -fuse-ld=lld)
endif () endif()
unset(LD_VERSION) unset(LD_VERSION)
endif () endif()
if (assert) if(assert)
foreach (var_ CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE) foreach(var_ CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE)
string(REGEX REPLACE "[-/]DNDEBUG" "" ${var_} "${${var_}}") string(REGEX REPLACE "[-/]DNDEBUG" "" ${var_} "${${var_}}")
endforeach () endforeach()
endif () endif()

View File

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

View File

@@ -11,24 +11,34 @@ include(target_protobuf_sources)
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(xrpl.libpb xrpl/proto LANGUAGE cpp IMPORT_DIRS include/xrpl/proto target_protobuf_sources(xrpl.libpb xrpl/proto LANGUAGE cpp IMPORT_DIRS include/xrpl/proto
PROTOS include/xrpl/proto/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(xrpl.libpb xrpl/proto LANGUAGE cpp IMPORT_DIRS include/xrpl/proto target_protobuf_sources(xrpl.libpb xrpl/proto LANGUAGE cpp IMPORT_DIRS include/xrpl/proto
PROTOS "${protos}") PROTOS "${protos}"
)
target_protobuf_sources( target_protobuf_sources(
xrpl.libpb xrpl/proto xrpl.libpb xrpl/proto
LANGUAGE grpc LANGUAGE grpc
IMPORT_DIRS include/xrpl/proto IMPORT_DIRS include/xrpl/proto
PROTOS "${protos}" PROTOS "${protos}"
PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin> PLUGIN protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc) GENERATE_EXTENSIONS .grpc.pb.h .grpc.pb.cc
)
target_compile_options( target_compile_options(
xrpl.libpb xrpl.libpb
PUBLIC $<$<BOOL:${is_msvc}>:-wd4996> $<$<BOOL:${is_xcode}>: PUBLIC
--system-header-prefix="google/protobuf" -Wno-deprecated-dynamic-exception-spec > $<$<BOOL:${is_msvc}>:-wd4996>
PRIVATE $<$<BOOL:${is_msvc}>:-wd4065> $<$<NOT:$<BOOL:${is_msvc}>>:-Wno-deprecated-declarations>) $<$<BOOL:${is_xcode}>:
--system-header-prefix="google/protobuf"
-Wno-deprecated-dynamic-exception-spec
>
PRIVATE
$<$<BOOL:${is_msvc}>:-wd4065>
$<$<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++)
@@ -37,19 +47,21 @@ add_library(xrpl.imports.main INTERFACE)
target_link_libraries( target_link_libraries(
xrpl.imports.main xrpl.imports.main
INTERFACE absl::random_random INTERFACE
date::date absl::random_random
ed25519::ed25519 date::date
LibArchive::LibArchive ed25519::ed25519
OpenSSL::Crypto LibArchive::LibArchive
Xrpl::boost OpenSSL::Crypto
Xrpl::libs Xrpl::boost
Xrpl::opts Xrpl::libs
Xrpl::syslibs Xrpl::opts
secp256k1::secp256k1 Xrpl::syslibs
xrpl.libpb secp256k1::secp256k1
xxHash::xxhash xrpl.libpb
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>) xxHash::xxhash
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
)
include(add_module) include(add_module)
include(target_link_modules) include(target_link_modules)
@@ -58,6 +70,16 @@ 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)
@@ -71,12 +93,17 @@ 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(xrpl.libxrpl.protocol PUBLIC xrpl.libxrpl.crypto xrpl.libxrpl.json) target_link_libraries(
xrpl.libxrpl.protocol
PUBLIC xrpl.libxrpl.crypto xrpl.libxrpl.git xrpl.libxrpl.json
)
# Level 05 # Level 05
add_module(xrpl core) add_module(xrpl core)
target_link_libraries(xrpl.libxrpl.core PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json target_link_libraries(
xrpl.libxrpl.protocol) xrpl.libxrpl.core
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol
)
# Level 06 # Level 06
add_module(xrpl resource) add_module(xrpl resource)
@@ -84,23 +111,46 @@ target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
# Level 07 # Level 07
add_module(xrpl net) add_module(xrpl net)
target_link_libraries(xrpl.libxrpl.net PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json target_link_libraries(
xrpl.libxrpl.protocol xrpl.libxrpl.resource) xrpl.libxrpl.net
PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.json
xrpl.libxrpl.protocol
xrpl.libxrpl.resource
)
add_module(xrpl nodestore) add_module(xrpl nodestore)
target_link_libraries(xrpl.libxrpl.nodestore PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json target_link_libraries(
xrpl.libxrpl.protocol) xrpl.libxrpl.nodestore
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol
)
add_module(xrpl shamap) add_module(xrpl shamap)
target_link_libraries(xrpl.libxrpl.shamap PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.crypto target_link_libraries(
xrpl.libxrpl.protocol xrpl.libxrpl.nodestore) xrpl.libxrpl.shamap
PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.crypto
xrpl.libxrpl.protocol
xrpl.libxrpl.nodestore
)
add_module(xrpl rdb) add_module(xrpl rdb)
target_link_libraries(xrpl.libxrpl.rdb PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.core) target_link_libraries(
xrpl.libxrpl.rdb
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.core
)
add_module(xrpl server) add_module(xrpl server)
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol xrpl.libxrpl.core target_link_libraries(
xrpl.libxrpl.rdb xrpl.libxrpl.resource) xrpl.libxrpl.server
PUBLIC
xrpl.libxrpl.protocol
xrpl.libxrpl.core
xrpl.libxrpl.rdb
xrpl.libxrpl.resource
)
add_module(xrpl conditions) add_module(xrpl conditions)
target_link_libraries(xrpl.libxrpl.conditions PUBLIC xrpl.libxrpl.server) target_link_libraries(xrpl.libxrpl.conditions PUBLIC xrpl.libxrpl.server)
@@ -108,13 +158,15 @@ 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 xrpl.libxrpl.ledger
PUBLIC xrpl.libxrpl.basics PUBLIC
xrpl.libxrpl.json xrpl.libxrpl.basics
xrpl.libxrpl.protocol xrpl.libxrpl.json
xrpl.libxrpl.rdb xrpl.libxrpl.protocol
xrpl.libxrpl.server xrpl.libxrpl.rdb
xrpl.libxrpl.shamap xrpl.libxrpl.server
xrpl.libxrpl.conditions) xrpl.libxrpl.shamap
xrpl.libxrpl.conditions
)
add_module(xrpl tx) add_module(xrpl tx)
target_link_libraries(xrpl.libxrpl.tx PUBLIC xrpl.libxrpl.ledger) target_link_libraries(xrpl.libxrpl.tx PUBLIC xrpl.libxrpl.ledger)
@@ -124,7 +176,11 @@ set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
add_library(xrpl::libxrpl ALIAS xrpl.libxrpl) add_library(xrpl::libxrpl ALIAS xrpl.libxrpl)
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/libxrpl/*.cpp") file(
GLOB_RECURSE sources
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(
@@ -135,6 +191,7 @@ target_link_modules(
conditions conditions
core core
crypto crypto
git
json json
ledger ledger
net net
@@ -144,7 +201,8 @@ target_link_modules(
resource resource
server server
shamap shamap
tx) tx
)
# All headers in libxrpl are in modules. # All headers in libxrpl are in modules.
# Uncomment this stanza if you have not yet moved new headers into a module. # Uncomment this stanza if you have not yet moved new headers into a module.
@@ -155,34 +213,51 @@ target_link_modules(
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
# $<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(xrpld PRIVATE UNIT_TEST_REFERENCE_FEE=${UNIT_TEST_REFERENCE_FEE}) target_compile_definitions(
endif () xrpld
target_include_directories(xrpld PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>) PRIVATE UNIT_TEST_REFERENCE_FEE=${UNIT_TEST_REFERENCE_FEE}
)
endif()
target_include_directories(
xrpld
PRIVATE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
)
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld/*.cpp") file(
GLOB_RECURSE sources
CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/xrpld/*.cpp"
)
target_sources(xrpld PRIVATE ${sources}) target_sources(xrpld PRIVATE ${sources})
if (tests) if(tests)
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/test/*.cpp") file(
GLOB_RECURSE sources
CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/test/*.cpp"
)
target_sources(xrpld PRIVATE ${sources}) target_sources(xrpld PRIVATE ${sources})
endif () endif()
target_link_libraries(xrpld Xrpl::boost Xrpl::opts Xrpl::libs xrpl.libxrpl) target_link_libraries(xrpld Xrpl::boost Xrpl::opts Xrpl::libs xrpl.libxrpl)
exclude_if_included(xrpld) exclude_if_included(xrpld)
# define a macro for tests that might need to # define a macro for tests that might need to
# be excluded or run differently in CI environment # be excluded or run differently in CI environment
if (is_ci) if(is_ci)
target_compile_definitions(xrpld PRIVATE XRPL_RUNNING_IN_CI) target_compile_definitions(xrpld PRIVATE XRPL_RUNNING_IN_CI)
endif () endif()
if (voidstar) if(voidstar)
target_compile_options(xrpld PRIVATE -fsanitize-coverage=trace-pc-guard) target_compile_options(xrpld PRIVATE -fsanitize-coverage=trace-pc-guard)
# xrpld requires access to antithesis-sdk-cpp implementation file # xrpld requires access to antithesis-sdk-cpp implementation file
# antithesis_instrumentation.h, which is not exported as INTERFACE # antithesis_instrumentation.h, which is not exported as INTERFACE
target_include_directories(xrpld PRIVATE ${CMAKE_SOURCE_DIR}/external/antithesis-sdk) target_include_directories(
endif () xrpld
endif () PRIVATE ${CMAKE_SOURCE_DIR}/external/antithesis-sdk
)
endif()
endif()

View File

@@ -2,14 +2,17 @@
coverage report target coverage report target
#]===================================================================] #]===================================================================]
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(WARNING "Code coverage on Windows is not supported, ignoring 'coverage' flag") message(
WARNING
"Code coverage on Windows is not supported, ignoring 'coverage' flag"
)
return() return()
endif () endif()
include(ProcessorCount) include(ProcessorCount)
ProcessorCount(PROCESSOR_COUNT) ProcessorCount(PROCESSOR_COUNT)
@@ -21,18 +24,19 @@ include(CodeCoverage)
# `CodeCoverage.cmake`) # `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(APPEND list(
GCOVR_ADDITIONAL_ARGS APPEND GCOVR_ADDITIONAL_ARGS
--exclude-throw-branches --exclude-throw-branches
--exclude-noncode-lines --exclude-noncode-lines
--exclude-unreachable-branches --exclude-unreachable-branches
-s -s
-j -j
${PROCESSOR_COUNT}) ${PROCESSOR_COUNT}
)
setup_target_for_coverage_gcovr( setup_target_for_coverage_gcovr(
NAME NAME
@@ -47,6 +51,7 @@ setup_target_for_coverage_gcovr(
"${CMAKE_BINARY_DIR}/pb-xrpl.libpb" "${CMAKE_BINARY_DIR}/pb-xrpl.libpb"
DEPENDENCIES DEPENDENCIES
xrpld xrpld
xrpl.tests) xrpl.tests
)
add_code_coverage_to_target(opts INTERFACE) add_code_coverage_to_target(opts INTERFACE)

View File

@@ -2,44 +2,45 @@
docs target (optional) docs target (optional)
#]===================================================================] #]===================================================================]
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")
set(doxygen_include_path "${CMAKE_CURRENT_SOURCE_DIR}/src") 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(GLOB_RECURSE file(
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(doxygen_plantuml_jar_path plantuml.jar PATH_SUFFIXES share/plantuml) verbose_find_path(doxygen_plantuml_jar_path plantuml.jar PATH_SUFFIXES share/plantuml)
verbose_find_path(doxygen_dot_path dot) verbose_find_path(doxygen_dot_path dot)
@@ -47,26 +48,40 @@ 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(WRITE "${download_script}" file(
"file(DOWNLOAD \ WRITE "${download_script}"
"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 \
)\n \ )\n \
execute_process( \ execute_process( \
COMMAND \"${CMAKE_COMMAND}\" -E tar -xf cppreference.zip \ COMMAND \"${CMAKE_COMMAND}\" -E tar -xf cppreference.zip \
)\n") )\n"
)
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(OUTPUT "${tagfile}" COMMAND "${CMAKE_COMMAND}" -P "${download_script}" add_custom_command(
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/docs") OUTPUT "${tagfile}"
COMMAND "${CMAKE_COMMAND}" -P "${download_script}"
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 "${CMAKE_COMMAND}" -E env "DOXYGEN_OUTPUT_DIRECTORY=${doxygen_output_directory}" COMMAND
"DOXYGEN_INCLUDE_PATH=${doxygen_include_path}" "DOXYGEN_TAGFILES=${doxygen_tagfiles}" "${CMAKE_COMMAND}" -E env
"DOXYGEN_PLANTUML_JAR_PATH=${doxygen_plantuml_jar_path}" "DOXYGEN_OUTPUT_DIRECTORY=${doxygen_output_directory}"
"DOXYGEN_DOT_PATH=${doxygen_dot_path}" "${DOXYGEN_EXECUTABLE}" "${doxyfile}" "DOXYGEN_INCLUDE_PATH=${doxygen_include_path}"
"DOXYGEN_TAGFILES=${doxygen_tagfiles}"
"DOXYGEN_PLANTUML_JAR_PATH=${doxygen_plantuml_jar_path}"
"DOXYGEN_DOT_PATH=${doxygen_dot_path}" "${DOXYGEN_EXECUTABLE}"
"${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}" SOURCES "${dependencies}") )
add_custom_target(
docs
DEPENDS "${doxygen_index_file}"
SOURCES "${dependencies}"
)

View File

@@ -6,56 +6,71 @@ include(create_symbolic_link)
# If no suffix is defined for executables (e.g. Windows uses .exe but Linux # If no suffix is defined for executables (e.g. Windows uses .exe but Linux
# and macOS use none), then explicitly set it to the empty string. # and macOS use none), then explicitly set it to the empty string.
if (NOT DEFINED suffix) if(NOT DEFINED suffix)
set(suffix "") set(suffix "")
endif () endif()
install(TARGETS common install(
opts TARGETS
xrpl_boost common
xrpl_libs opts
xrpl_syslibs xrpl_boost
xrpl.imports.main xrpl_libs
xrpl.libpb xrpl_syslibs
xrpl.libxrpl xrpl.imports.main
xrpl.libxrpl.basics xrpl.libpb
xrpl.libxrpl.beast xrpl.libxrpl
xrpl.libxrpl.conditions xrpl.libxrpl.basics
xrpl.libxrpl.core xrpl.libxrpl.beast
xrpl.libxrpl.crypto xrpl.libxrpl.conditions
xrpl.libxrpl.json xrpl.libxrpl.core
xrpl.libxrpl.rdb xrpl.libxrpl.crypto
xrpl.libxrpl.ledger xrpl.libxrpl.git
xrpl.libxrpl.net xrpl.libxrpl.json
xrpl.libxrpl.nodestore xrpl.libxrpl.rdb
xrpl.libxrpl.protocol xrpl.libxrpl.ledger
xrpl.libxrpl.resource xrpl.libxrpl.net
xrpl.libxrpl.server xrpl.libxrpl.nodestore
xrpl.libxrpl.shamap xrpl.libxrpl.protocol
xrpl.libxrpl.tx xrpl.libxrpl.resource
antithesis-sdk-cpp xrpl.libxrpl.server
EXPORT XrplExports xrpl.libxrpl.shamap
LIBRARY DESTINATION lib xrpl.libxrpl.tx
ARCHIVE DESTINATION lib antithesis-sdk-cpp
RUNTIME DESTINATION bin EXPORT XrplExports
INCLUDES LIBRARY DESTINATION lib
DESTINATION include) ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl" install(
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
install(EXPORT XrplExports FILE XrplTargets.cmake NAMESPACE Xrpl:: DESTINATION lib/cmake/xrpl) install(
EXPORT XrplExports
FILE XrplTargets.cmake
NAMESPACE Xrpl::
DESTINATION lib/cmake/xrpl
)
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
write_basic_package_version_file(XrplConfigVersion.cmake VERSION ${xrpld_version} write_basic_package_version_file(
COMPATIBILITY SameMajorVersion) XrplConfigVersion.cmake
VERSION ${xrpld_version}
COMPATIBILITY SameMajorVersion
)
if (is_root_project AND TARGET xrpld) if(is_root_project AND TARGET xrpld)
install(TARGETS xrpld RUNTIME DESTINATION bin) install(TARGETS xrpld RUNTIME DESTINATION bin)
set_target_properties(xrpld PROPERTIES INSTALL_RPATH_USE_LINK_PATH ON) set_target_properties(xrpld PROPERTIES INSTALL_RPATH_USE_LINK_PATH ON)
# sample configs should not overwrite existing files # sample configs should not overwrite existing files
# install if-not-exists workaround as suggested by # install if-not-exists workaround as suggested by
# https://cmake.org/Bug/view.php?id=12646 # https://cmake.org/Bug/view.php?id=12646
install(CODE " install(
CODE
"
macro (copy_if_not_exists SRC DEST NEWNAME) macro (copy_if_not_exists SRC DEST NEWNAME)
if (NOT EXISTS \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${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}\") file (INSTALL FILE_PERMISSIONS OWNER_READ OWNER_WRITE DESTINATION \"\${CMAKE_INSTALL_PREFIX}/\${DEST}\" FILES \"\${SRC}\" RENAME \"\${NEWNAME}\")
@@ -65,14 +80,22 @@ if (is_root_project AND TARGET xrpld)
endmacro() 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/xrpld-example.cfg\" etc xrpld.cfg)
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt\" etc validators.txt) copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt\" etc validators.txt)
") "
install(CODE " )
install(
CODE
"
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\") set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
include(create_symbolic_link) include(create_symbolic_link)
create_symbolic_link(xrpld${suffix} \ create_symbolic_link(xrpld${suffix} \
\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/rippled${suffix}) \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/rippled${suffix})
") "
endif () )
endif()
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/XrplConfig.cmake install(
${CMAKE_CURRENT_BINARY_DIR}/XrplConfigVersion.cmake DESTINATION lib/cmake/xrpl) FILES
${CMAKE_CURRENT_SOURCE_DIR}/cmake/XrplConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/XrplConfigVersion.cmake
DESTINATION lib/cmake/xrpl
)

View File

@@ -5,47 +5,55 @@
include(CompilationEnv) include(CompilationEnv)
# Set defaults for optional variables to avoid uninitialized variable warnings # Set defaults for optional variables to avoid uninitialized variable warnings
if (NOT DEFINED voidstar) if(NOT DEFINED voidstar)
set(voidstar OFF) set(voidstar OFF)
endif () endif()
add_library(opts INTERFACE) add_library(opts INTERFACE)
add_library(Xrpl::opts ALIAS opts) add_library(Xrpl::opts ALIAS opts)
target_compile_definitions( target_compile_definitions(
opts opts
INTERFACE BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS INTERFACE
BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS
BOOST_CONTAINER_FWD_BAD_DEQUE BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
HAS_UNCAUGHT_EXCEPTIONS=1 BOOST_CONTAINER_FWD_BAD_DEQUE
$<$<BOOL:${boost_show_deprecated}>: HAS_UNCAUGHT_EXCEPTIONS=1
BOOST_ASIO_NO_DEPRECATED $<$<BOOL:${boost_show_deprecated}>:
BOOST_FILESYSTEM_NO_DEPRECATED BOOST_ASIO_NO_DEPRECATED
> BOOST_FILESYSTEM_NO_DEPRECATED
$<$<NOT:$<BOOL:${boost_show_deprecated}>>: >
BOOST_COROUTINES_NO_DEPRECATION_WARNING $<$<NOT:$<BOOL:${boost_show_deprecated}>>:
BOOST_BEAST_ALLOW_DEPRECATED BOOST_COROUTINES_NO_DEPRECATION_WARNING
BOOST_FILESYSTEM_DEPRECATED 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:${beast_no_unit_test_inline}>:BEAST_NO_UNIT_TEST_INLINE=1>
$<$<BOOL:${single_io_service_thread}>:XRPL_SINGLE_IO_SERVICE_THREAD=1> $<$<BOOL:${beast_disable_autolink}>:BEAST_DONT_AUTOLINK_TO_WIN32_LIBRARIES=1>
$<$<BOOL:${voidstar}>:ENABLE_VOIDSTAR>) $<$<BOOL:${single_io_service_thread}>:XRPL_SINGLE_IO_SERVICE_THREAD=1>
$<$<BOOL:${voidstar}>:ENABLE_VOIDSTAR>
)
target_compile_options( target_compile_options(
opts opts
INTERFACE $<$<AND:$<BOOL:${is_gcc}>,$<COMPILE_LANGUAGE:CXX>>:-Wsuggest-override> INTERFACE
$<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized> $<$<AND:$<BOOL:${is_gcc}>,$<COMPILE_LANGUAGE:CXX>>:-Wsuggest-override>
$<$<BOOL:${perf}>:-fno-omit-frame-pointer> $<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized>
$<$<BOOL:${profile}>:-pg> $<$<BOOL:${perf}>:-fno-omit-frame-pointer>
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>) $<$<BOOL:${profile}>:-pg>
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>
)
target_link_libraries(opts INTERFACE $<$<BOOL:${profile}>:-pg> target_link_libraries(
$<$<AND:$<BOOL:${is_gcc}>,$<BOOL:${profile}>>:-p>) 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
@@ -55,31 +63,33 @@ 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 $<$<BOOL:${is_msvc}>: INTERFACE
legacy_stdio_definitions.lib $<$<BOOL:${is_msvc}>:
Shlwapi legacy_stdio_definitions.lib
kernel32 Shlwapi
user32 kernel32
gdi32 user32
winspool gdi32
comdlg32 winspool
advapi32 comdlg32
shell32 advapi32
ole32 shell32
oleaut32 ole32
uuid oleaut32
odbc32 uuid
odbccp32 odbc32
crypt32 odbccp32
> crypt32
$<$<NOT:$<BOOL:${is_msvc}>>:dl> >
$<$<NOT:$<OR:$<BOOL:${is_msvc}>,$<BOOL:${is_macos}>>>:rt>) $<$<NOT:$<BOOL:${is_msvc}>>:dl>
$<$<NOT:$<OR:$<BOOL:${is_msvc}>,$<BOOL:${is_macos}>>>:rt>
)
if (NOT is_msvc) if(NOT is_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)

View File

@@ -44,23 +44,26 @@ include(CompilationEnv)
# Read environment variable # Read environment variable
set(SANITIZERS "") set(SANITIZERS "")
if (DEFINED ENV{SANITIZERS}) if(DEFINED ENV{SANITIZERS})
set(SANITIZERS "$ENV{SANITIZERS}") set(SANITIZERS "$ENV{SANITIZERS}")
endif () 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")
set(SANITIZERS_ENABLED TRUE) set(SANITIZERS_ENABLED TRUE)
else () else()
set(SANITIZERS_ENABLED FALSE) set(SANITIZERS_ENABLED FALSE)
return() return()
endif () endif()
# Sanitizers are not supported on Windows/MSVC # Sanitizers are not supported on Windows/MSVC
if (is_msvc) if(is_msvc)
message(FATAL_ERROR "Sanitizers are not supported on Windows/MSVC. " message(
"Please unset the SANITIZERS environment variable.") FATAL_ERROR
endif () "Sanitizers are not supported on Windows/MSVC. "
"Please unset the SANITIZERS environment variable."
)
endif()
message(STATUS "Configuring sanitizers: ${SANITIZERS}") message(STATUS "Configuring sanitizers: ${SANITIZERS}")
@@ -74,24 +77,30 @@ set(san_list "${SANITIZERS}")
string(REPLACE "," ";" san_list "${san_list}") string(REPLACE "," ";" san_list "${san_list}")
separate_arguments(san_list) separate_arguments(san_list)
foreach (san IN LISTS san_list) foreach(san IN LISTS san_list)
if (san STREQUAL "address") if(san STREQUAL "address")
set(enable_asan TRUE) set(enable_asan TRUE)
elseif (san STREQUAL "thread") elseif(san STREQUAL "thread")
set(enable_tsan TRUE) set(enable_tsan TRUE)
elseif (san STREQUAL "undefinedbehavior") elseif(san STREQUAL "undefinedbehavior")
set(enable_ubsan TRUE) set(enable_ubsan TRUE)
else () else()
message(FATAL_ERROR "Unsupported sanitizer type: ${san}" message(
"Supported: address, thread, undefinedbehavior and their combinations.") FATAL_ERROR
endif () "Unsupported sanitizer type: ${san}"
endforeach () "Supported: address, thread, undefinedbehavior and their combinations."
)
endif()
endforeach()
# Validate sanitizer compatibility # Validate sanitizer compatibility
if (enable_asan AND enable_tsan) if(enable_asan AND enable_tsan)
message(FATAL_ERROR "AddressSanitizer and ThreadSanitizer are incompatible and cannot be enabled simultaneously. " message(
"Use 'address' or 'thread', optionally with 'undefinedbehavior'.") FATAL_ERROR
endif () "AddressSanitizer and ThreadSanitizer are incompatible and cannot be enabled simultaneously. "
"Use 'address' or 'thread', optionally with 'undefinedbehavior'."
)
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
set(SANITIZERS_COMPILE_FLAGS "-fno-omit-frame-pointer" "-O1") set(SANITIZERS_COMPILE_FLAGS "-fno-omit-frame-pointer" "-O1")
@@ -99,66 +108,79 @@ set(SANITIZERS_COMPILE_FLAGS "-fno-omit-frame-pointer" "-O1")
# Build the sanitizer flags list # Build the sanitizer flags list
set(SANITIZER_TYPES) set(SANITIZER_TYPES)
if (enable_asan) if(enable_asan)
list(APPEND SANITIZER_TYPES "address") list(APPEND SANITIZER_TYPES "address")
elseif (enable_tsan) elseif(enable_tsan)
list(APPEND SANITIZER_TYPES "thread") list(APPEND SANITIZER_TYPES "thread")
endif () endif()
if (enable_ubsan) 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 Use large code model for ASAN to avoid relocation errors Use medium code model
# for TSAN (large is not compatible with TSAN) # 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 Use default linker (bfd/ld) which is more lenient with
# mixed code models This is needed since the size of instrumented binary exceeds the limits set by mold, lld and # mixed code models This is needed since the size of instrumented binary exceeds the limits set by mold, lld and
# gold linkers # 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(STATUS " Disabled mold, gold, and lld linkers for GCC with sanitizers") message(
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")
if (is_amd64 AND enable_asan) if(is_amd64 AND enable_asan)
message(STATUS " Using large code model (-mcmodel=large)") message(STATUS " Using large code model (-mcmodel=large)")
list(APPEND SANITIZERS_COMPILE_FLAGS "-mcmodel=large") list(APPEND SANITIZERS_COMPILE_FLAGS "-mcmodel=large")
list(APPEND SANITIZERS_RELOCATION_FLAGS "-mcmodel=large") list(APPEND SANITIZERS_RELOCATION_FLAGS "-mcmodel=large")
elseif (enable_tsan) elseif(enable_tsan)
# GCC doesn't support atomic_thread_fence with tsan. Suppress warnings. # GCC doesn't support atomic_thread_fence with tsan. Suppress warnings.
list(APPEND SANITIZERS_COMPILE_FLAGS "-Wno-tsan") list(APPEND SANITIZERS_COMPILE_FLAGS "-Wno-tsan")
message(STATUS " Using medium code model (-mcmodel=medium)") message(STATUS " Using medium code model (-mcmodel=medium)")
list(APPEND SANITIZERS_COMPILE_FLAGS "-mcmodel=medium") list(APPEND SANITIZERS_COMPILE_FLAGS "-mcmodel=medium")
list(APPEND SANITIZERS_RELOCATION_FLAGS "-mcmodel=medium") list(APPEND SANITIZERS_RELOCATION_FLAGS "-mcmodel=medium")
endif () endif()
# Join sanitizer flags with commas for -fsanitize option # Join sanitizer flags with commas for -fsanitize option
list(JOIN SANITIZER_TYPES "," SANITIZER_TYPES_STR) list(JOIN SANITIZER_TYPES "," SANITIZER_TYPES_STR)
# 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 "${SANITIZERS_RELOCATION_FLAGS}" "-fsanitize=${SANITIZER_TYPES_STR}") set(SANITIZERS_LINK_FLAGS
"${SANITIZERS_RELOCATION_FLAGS}"
elseif (is_clang) "-fsanitize=${SANITIZER_TYPES_STR}"
)
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) Use CMAKE_SOURCE_DIR to get the path to the ignorelist
set(IGNORELIST_PATH "${CMAKE_SOURCE_DIR}/sanitizers/suppressions/sanitizer-ignorelist.txt") set(IGNORELIST_PATH
if (NOT EXISTS "${IGNORELIST_PATH}") "${CMAKE_SOURCE_DIR}/sanitizers/suppressions/sanitizer-ignorelist.txt"
message(FATAL_ERROR "Sanitizer ignorelist not found: ${IGNORELIST_PATH}") )
endif () if(NOT EXISTS "${IGNORELIST_PATH}")
message(
FATAL_ERROR
"Sanitizer ignorelist not found: ${IGNORELIST_PATH}"
)
endif()
list(APPEND SANITIZERS_COMPILE_FLAGS "-fsanitize-ignorelist=${IGNORELIST_PATH}") list(
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
@@ -167,31 +189,35 @@ elseif (is_clang)
# 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 "-fsanitize=${SANITIZER_TYPES_STR}") set(SANITIZERS_LINK_FLAGS "-fsanitize=${SANITIZER_TYPES_STR}")
endif () 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 This is the same library used by XrplCompiler.cmake
target_compile_options(common INTERFACE $<$<COMPILE_LANGUAGE:CXX>:${SANITIZERS_COMPILE_FLAGS}> target_compile_options(
$<$<COMPILE_LANGUAGE:C>:${SANITIZERS_COMPILE_FLAGS}>) common
INTERFACE
$<$<COMPILE_LANGUAGE:CXX>:${SANITIZERS_COMPILE_FLAGS}>
$<$<COMPILE_LANGUAGE:C>:${SANITIZERS_COMPILE_FLAGS}>
)
# Apply linker flags # Apply linker flags
target_link_options(common INTERFACE ${SANITIZERS_LINK_FLAGS}) target_link_options(common INTERFACE ${SANITIZERS_LINK_FLAGS})
# Define SANITIZERS macro for BuildInfo.cpp # Define SANITIZERS macro for BuildInfo.cpp
set(sanitizers_list) set(sanitizers_list)
if (enable_asan) if(enable_asan)
list(APPEND sanitizers_list "ASAN") list(APPEND sanitizers_list "ASAN")
endif () endif()
if (enable_tsan) if(enable_tsan)
list(APPEND sanitizers_list "TSAN") list(APPEND sanitizers_list "TSAN")
endif () endif()
if (enable_ubsan) if(enable_ubsan)
list(APPEND sanitizers_list "UBSAN") list(APPEND sanitizers_list "UBSAN")
endif () endif()
if (sanitizers_list) if(sanitizers_list)
list(JOIN sanitizers_list "." sanitizers_str) list(JOIN sanitizers_list "." sanitizers_str)
target_compile_definitions(common INTERFACE SANITIZERS=${sanitizers_str}) target_compile_definitions(common INTERFACE SANITIZERS=${sanitizers_str})
endif () endif()

View File

@@ -7,40 +7,49 @@ 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 (NOT (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL Release)) elseif(
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 # for simplicity, these are the only two config types we care about. Limiting the build types simplifies dealing
# with external project builds especially # with external project builds especially
message(FATAL_ERROR " *** Only Debug or Release build types are currently supported ***") message(
endif () FATAL_ERROR
endif () " *** 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 ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS if(
16.0) "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang"
AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 16.0
)
message(FATAL_ERROR "This project requires clang 16 or later") message(FATAL_ERROR "This project requires clang 16 or later")
endif () endif()
elseif (is_gcc) elseif(is_gcc)
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0)
message(FATAL_ERROR "This project requires GCC 12 or later") message(FATAL_ERROR "This project requires GCC 12 or later")
endif () 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(FATAL_ERROR "Builds (in-source) are not allowed in " message(
"${CMAKE_CURRENT_SOURCE_DIR}. Please remove CMakeCache.txt and the CMakeFiles " FATAL_ERROR
"directory from ${CMAKE_CURRENT_SOURCE_DIR} and try building in a separate directory." "Builds (in-source) are not allowed in "
"${CMAKE_CURRENT_SOURCE_DIR}. Please remove CMakeCache.txt and the CMakeFiles "
"directory from ${CMAKE_CURRENT_SOURCE_DIR} and try building in a separate directory."
) )
endif () 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 (APPLE AND NOT HOMEBREW) if(APPLE AND NOT HOMEBREW)
find_program(HOMEBREW brew) find_program(HOMEBREW brew)
endif () endif()

View File

@@ -5,59 +5,67 @@
include(CompilationEnv) include(CompilationEnv)
set(is_ci FALSE) set(is_ci FALSE)
if (DEFINED ENV{CI}) if(DEFINED ENV{CI})
if ("$ENV{CI}" STREQUAL "true") if("$ENV{CI}" STREQUAL "true")
set(is_ci TRUE) set(is_ci TRUE)
endif () 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)
option(xrpld "Build xrpld" ON) 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 "html-details" CACHE STRING "Output format of the coverage report.") set(coverage_format
set(coverage_extra_args "" CACHE STRING "Additional arguments to pass to gcovr.") "html-details"
CACHE STRING
"Output format of the coverage report."
)
set(coverage_extra_args
""
CACHE STRING
"Additional arguments to pass to gcovr."
)
option(wextra "compile with extra gcc/clang warnings enabled" ON) 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)
@@ -65,53 +73,83 @@ if (is_linux AND NOT SANITIZER)
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. This provides a sensible default (on for debug, off
# for release) while still allowing the user to override it for any build. # for release) while still allowing the user to override it for any build.
if (CMAKE_BUILD_TYPE STREQUAL "Debug") if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(TRUNCATED_LOGS_DEFAULT ON) set(TRUNCATED_LOGS_DEFAULT ON)
else () else()
set(TRUNCATED_LOGS_DEFAULT OFF) set(TRUNCATED_LOGS_DEFAULT OFF)
endif () endif()
option(TRUNCATED_THREAD_NAME_LOGS "Show warnings about truncated thread names on Linux." option(
${TRUNCATED_LOGS_DEFAULT}) TRUNCATED_THREAD_NAME_LOGS
if (TRUNCATED_THREAD_NAME_LOGS) "Show warnings about truncated thread names on Linux."
${TRUNCATED_LOGS_DEFAULT}
)
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 export declarations. On macos it's more
# feasible, but static openssl produces odd linker errors, thus we disable shared lib builds for now. # feasible, but static openssl produces odd linker errors, thus we disable shared lib builds for now.
set(BUILD_SHARED_LIBS OFF CACHE BOOL "build shared xrpl libraries - OFF for win/macos" FORCE) set(BUILD_SHARED_LIBS
OFF
CACHE BOOL
"build shared xrpl libraries - OFF for win/macos"
FORCE
)
set(static ON CACHE BOOL "static link, linux only. ON for WIN/macos" FORCE) set(static ON CACHE BOOL "static link, linux only. ON for WIN/macos" FORCE)
set(perf OFF CACHE BOOL "perf flags, linux only" FORCE) set(perf OFF CACHE BOOL "perf flags, linux only" FORCE)
set(use_gold OFF CACHE BOOL "gold linker, 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) 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(local_protobuf option(
"Force a local build of protobuf instead of looking for an installed version." OFF) local_protobuf
option(local_grpc "Force a local build of gRPC instead of looking for an installed version." OFF) "Force a local build of protobuf 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(beast_no_unit_test_inline option(
"Prevents unit test definitions from being inserted into global table" OFF) beast_no_unit_test_inline
option(single_io_service_thread "Restricts the number of threads calling io_context::run to one. \ "Prevents unit test definitions from being inserted into global table"
This can be useful when debugging." OFF) OFF
option(boost_show_deprecated "Allow boost to fail on deprecated usage. Only useful if you're trying\ )
to find deprecated calls." OFF) option(
single_io_service_thread
"Restricts the number of threads calling io_context::run to one. \
This can be useful when debugging."
OFF
)
option(
boost_show_deprecated
"Allow boost to fail on deprecated usage. Only useful if you're trying\
to find deprecated calls."
OFF
)
if (WIN32) if(WIN32)
option(beast_disable_autolink "Disables autolinking of system libraries on WIN32" OFF) option(
else () beast_disable_autolink
"Disables autolinking of system libraries on WIN32"
OFF
)
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,20 +1,26 @@
option(validator_keys option(
"Enables building of validator-keys tool as a separate target (imported via FetchContent)" validator_keys
OFF) "Enables building of validator-keys tool as a separate target (imported via FetchContent)"
OFF
)
if (validator_keys) if(validator_keys)
git_branch(current_branch) git_branch(current_branch)
# default to tracking VK master branch unless we are on release # default to tracking VK master branch unless we are on release
if (NOT (current_branch STREQUAL "release")) if(NOT (current_branch STREQUAL "release"))
set(current_branch "master") set(current_branch "master")
endif () endif()
message(STATUS "Tracking ValidatorKeys branch: ${current_branch}") message(STATUS "Tracking ValidatorKeys branch: ${current_branch}")
FetchContent_Declare( FetchContent_Declare(
validator_keys GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git validator_keys
GIT_TAG "${current_branch}") GIT_REPOSITORY https://github.com/ripple/validator-keys-tool.git
GIT_TAG "${current_branch}"
)
FetchContent_MakeAvailable(validator_keys) FetchContent_MakeAvailable(validator_keys)
set_target_properties(validator-keys PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") set_target_properties(
validator-keys
PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(TARGETS validator-keys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
endif ()

View File

@@ -3,13 +3,13 @@
#]===================================================================] #]===================================================================]
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

@@ -12,15 +12,23 @@ include(isolate_headers)
# add_module(parent a) # add_module(parent a)
# 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(GLOB_RECURSE sources CONFIGURE_DEPENDS file(
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}/*.cpp") GLOB_RECURSE sources
CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}/*.cpp"
)
target_sources(${target} PRIVATE ${sources}) target_sources(${target} PRIVATE ${sources})
target_include_directories(${target} PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>") target_include_directories(
${target}
PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
isolate_headers(${target} "${CMAKE_CURRENT_SOURCE_DIR}/include" isolate_headers(${target} "${CMAKE_CURRENT_SOURCE_DIR}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/include/${parent}/${name}" PUBLIC) "${CMAKE_CURRENT_SOURCE_DIR}/include/${parent}/${name}" PUBLIC
)
isolate_headers(${target} "${CMAKE_CURRENT_SOURCE_DIR}/src" isolate_headers(${target} "${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}" PRIVATE) "${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}" PRIVATE
endfunction () )
endfunction()

View File

@@ -1,19 +1,21 @@
# 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_SYMLINK "${link}")
if (NOT IS_ABSOLUTE "${target}") if(NOT IS_ABSOLUTE "${target}")
# Relative links work do not work on Windows. # Relative links work do not work on Windows.
set(target "${link}/../${target}") set(target "${link}/../${target}")
endif () endif()
file(TO_NATIVE_PATH "${target}" target) file(TO_NATIVE_PATH "${target}" target)
file(TO_NATIVE_PATH "${link}" link) file(TO_NATIVE_PATH "${link}" link)
execute_process(COMMAND cmd.exe /c mklink /J "${link}" "${target}") execute_process(
endif () COMMAND cmd.exe /c mklink /J "${link}" "${target}"
else () )
endif()
else()
file(CREATE_LINK "${target}" "${link}" SYMBOLIC) file(CREATE_LINK "${target}" "${link}" SYMBOLIC)
endif () endif()
if (NOT IS_SYMLINK "${link}") if(NOT IS_SYMLINK "${link}")
message(ERROR "failed to create symlink: <${link}>") message(ERROR "failed to create symlink: <${link}>")
endif () endif()
endfunction () endfunction()

View File

@@ -1,45 +1,60 @@
include(CompilationEnv) include(CompilationEnv)
include(XrplSanitizers) include(XrplSanitizers)
find_package(Boost REQUIRED find_package(
COMPONENTS chrono Boost
container REQUIRED
coroutine COMPONENTS
date_time chrono
filesystem container
json coroutine
program_options date_time
regex filesystem
system json
thread) program_options
regex
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 Boost::headers INTERFACE
Boost::chrono Boost::headers
Boost::container Boost::chrono
Boost::coroutine Boost::container
Boost::date_time Boost::coroutine
Boost::filesystem Boost::date_time
Boost::json Boost::filesystem
Boost::process Boost::json
Boost::program_options Boost::process
Boost::regex Boost::program_options
Boost::thread) Boost::regex
if (Boost_COMPILER) Boost::thread
)
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) if(SANITIZERS_ENABLED AND is_clang)
# TODO: gcc does not support -fsanitize-blacklist...can we do something else for gcc ? # TODO: gcc does not support -fsanitize-blacklist...can we do something else for gcc ?
if (NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers) if(NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)
get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES) get_target_property(
endif () Boost_INCLUDE_DIRS
Boost::headers
INTERFACE_INCLUDE_DIRECTORIES
)
endif()
message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist") message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt "src:${Boost_INCLUDE_DIRS}/*") file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt
"src:${Boost_INCLUDE_DIRS}/*"
)
target_compile_options( target_compile_options(
opts INTERFACE # ignore boost headers for sanitizing opts
-fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt) INTERFACE # ignore boost headers for sanitizing
endif () -fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt
)
endif()

View File

@@ -37,7 +37,7 @@ include(create_symbolic_link)
# `${CMAKE_CURRENT_BINARY_DIR}/include/${target}`. # `${CMAKE_CURRENT_BINARY_DIR}/include/${target}`.
# #
# 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}")
@@ -45,4 +45,4 @@ function (isolate_headers target A B scope)
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

@@ -6,9 +6,9 @@
# target_link_libraries(project.libparent.b PUBLIC project.libparent.a) # target_link_libraries(project.libparent.b PUBLIC project.libparent.a)
# 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)
@@ -17,8 +17,11 @@ function (target_link_modules parent scope)
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(STATUS "${module} with ${expected} sources took ${actual} sources from ${library}") message(
STATUS
"${module} with ${expected} sources took ${actual} sources from ${library}"
)
set_target_properties(${library} PROPERTIES SOURCES "${sources}") set_target_properties(${library} PROPERTIES SOURCES "${sources}")
target_link_libraries(${library} ${scope} ${module}) target_link_libraries(${library} ${scope} ${module})
endforeach () endforeach()
endfunction () endfunction()

View File

@@ -35,20 +35,31 @@ find_package(Protobuf REQUIRED)
# This prefix should appear at the start of all your consumer includes. # This prefix should appear at the start of all your consumer includes.
# 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(TARGET ${target} PROTOC_OUT_DIR "${dir}/${prefix}" "${ARGN}") protobuf_generate(
TARGET ${target}
PROTOC_OUT_DIR "${dir}/${prefix}"
"${ARGN}"
)
target_include_directories( target_include_directories(
${target} SYSTEM ${target}
SYSTEM
PUBLIC # Allows #include <package/path/to/file.proto> used by consumer files. PUBLIC # Allows #include <package/path/to/file.proto> used by consumer files.
$<BUILD_INTERFACE:${dir}> $<BUILD_INTERFACE:${dir}>
# Allows #include "path/to/file.proto" used by generated files. # Allows #include "path/to/file.proto" used by generated files.
$<BUILD_INTERFACE:${dir}/${prefix}> $<BUILD_INTERFACE:${dir}/${prefix}>
# Allows #include <package/path/to/file.proto> used by consumer files. # Allows #include <package/path/to/file.proto> used by consumer files.
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
# Allows #include "path/to/file.proto" used by generated files. # Allows #include "path/to/file.proto" used by generated files.
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${prefix}>) $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${prefix}>
install(DIRECTORY ${dir}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h") )
endfunction () install(
DIRECTORY ${dir}/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING
PATTERN "*.h"
)
endfunction()

View File

@@ -176,6 +176,8 @@ words:
- nixfmt - nixfmt
- nixos - nixos
- nixpkgs - nixpkgs
- NOLINT
- NOLINTNEXTLINE
- nonxrp - nonxrp
- noripple - noripple
- nudb - nudb

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <string> #include <string>
#include <string_view>
#include <vector> #include <vector>
namespace beast { namespace beast {
@@ -26,14 +27,14 @@ public:
SemanticVersion(); SemanticVersion();
SemanticVersion(std::string const& version); SemanticVersion(std::string_view version);
/** Parse a semantic version string. /** Parse a semantic version string.
The parsing is as strict as possible. The parsing is as strict as possible.
@return `true` if the string was parsed. @return `true` if the string was parsed.
*/ */
bool bool
parse(std::string const& input); parse(std::string_view input);
/** Produce a string from semantic version components. */ /** Produce a string from semantic version components. */
std::string std::string

13
include/xrpl/git/Git.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <string>
namespace xrpl::git {
std::string const&
getCommitHash();
std::string const&
getBuildBranch();
} // namespace xrpl::git

View File

@@ -23,13 +23,13 @@ public:
static constexpr size_t initialBufferSize = kilobytes(256); static constexpr size_t initialBufferSize = kilobytes(256);
RawStateTable() RawStateTable()
: monotonic_resource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>( : monotonic_resource_{
initialBufferSize)} std::make_unique<boost::container::pmr::monotonic_buffer_resource>(initialBufferSize)}
, items_{monotonic_resource_.get()} {}; , items_{monotonic_resource_.get()} {};
RawStateTable(RawStateTable const& rhs) RawStateTable(RawStateTable const& rhs)
: monotonic_resource_{std::make_unique<boost::container::pmr::monotonic_buffer_resource>( : monotonic_resource_{
initialBufferSize)} std::make_unique<boost::container::pmr::monotonic_buffer_resource>(initialBufferSize)}
, items_{rhs.items_, monotonic_resource_.get()} , items_{rhs.items_, monotonic_resource_.get()}
, dropsDestroyed_{rhs.dropsDestroyed_} {}; , dropsDestroyed_{rhs.dropsDestroyed_} {};

View File

@@ -49,7 +49,7 @@ getFullVersionString();
@return the encoded version in a 64-bit integer @return the encoded version in a 64-bit integer
*/ */
std::uint64_t std::uint64_t
encodeSoftwareVersion(char const* const versionStr); encodeSoftwareVersion(std::string_view versionStr);
/** Returns this server's version packed in a 64-bit integer. */ /** Returns this server's version packed in a 64-bit integer. */
std::uint64_t std::uint64_t

View File

@@ -30,9 +30,11 @@ public:
Item( Item(
char const* name, char const* name,
KeyType type, KeyType type,
std::initializer_list<SOElement> uniqueFields, std::vector<SOElement> uniqueFields,
std::initializer_list<SOElement> commonFields) std::vector<SOElement> commonFields)
: soTemplate_(uniqueFields, commonFields), name_(name), type_(type) : soTemplate_(std::move(uniqueFields), std::move(commonFields))
, name_(name)
, type_(type)
{ {
// Verify that KeyType is appropriate. // Verify that KeyType is appropriate.
static_assert( static_assert(
@@ -142,16 +144,16 @@ protected:
@param name The name of this format. @param name The name of this format.
@param type The type of this format. @param type The type of this format.
@param uniqueFields An std::initializer_list of unique fields @param uniqueFields A std::vector of unique fields
@param commonFields An std::initializer_list of common fields @param commonFields A std::vector of common fields
@return The created format. @return The created format.
*/ */
Item const& Item const&
add(char const* name, add(char const* name,
KeyType type, KeyType type,
std::initializer_list<SOElement> uniqueFields, std::vector<SOElement> uniqueFields,
std::initializer_list<SOElement> commonFields = {}) std::vector<SOElement> commonFields = {})
{ {
if (auto const item = findByType(type)) if (auto const item = findByType(type))
{ {
@@ -160,7 +162,7 @@ protected:
item->getName()); item->getName());
} }
formats_.emplace_front(name, type, uniqueFields, commonFields); formats_.emplace_front(name, type, std::move(uniqueFields), std::move(commonFields));
Item const& item{formats_.front()}; Item const& item{formats_.front()};
names_[name] = &item; names_[name] = &item;

View File

@@ -2,36 +2,34 @@
#include <xrpl/protocol/KnownFormats.h> #include <xrpl/protocol/KnownFormats.h>
namespace xrpl { #include <map>
#include <string>
#include <vector>
namespace xrpl {
/** Identifiers for on-ledger objects. /** Identifiers for on-ledger objects.
Each ledger object requires a unique type identifier, which is stored Each ledger object requires a unique type identifier, which is stored within the object itself;
within the object itself; this makes it possible to iterate the entire this makes it possible to iterate the entire ledger and determine each object's type and verify
ledger and determine each object's type and verify that the object you that the object you retrieved from a given hash matches the expected type.
retrieved from a given hash matches the expected type.
@warning Since these values are stored inside objects stored on the ledger @warning Since these values are stored inside objects stored on the ledger they are part of the
they are part of the protocol. **Changing them should be avoided protocol.
because without special handling, this will result in a hard **Changing them should be avoided because without special handling, this will result in a hard
fork.** fork.**
@note Values outside this range may be used internally by the code for @note Values outside this range may be used internally by the code for various purposes, but
various purposes, but attempting to use such values to identify attempting to use such values to identify on-ledger objects will result in an invariant failure.
on-ledger objects will results in an invariant failure.
@note When retiring types, the specific values should not be removed but @note When retiring types, the specific values should not be removed but should be marked as
should be marked as [[deprecated]]. This is to avoid accidental [[deprecated]]. This is to avoid accidental reuse of identifiers.
reuse of identifiers.
@todo The C++ language does not enable checking for duplicate values @todo The C++ language does not enable checking for duplicate values here.
here. If it becomes possible then we should do this. If it becomes possible then we should do this.
@ingroup protocol @ingroup protocol
*/ */
// clang-format off enum LedgerEntryType : std::uint16_t {
enum LedgerEntryType : std::uint16_t
{
#pragma push_macro("LEDGER_ENTRY") #pragma push_macro("LEDGER_ENTRY")
#undef LEDGER_ENTRY #undef LEDGER_ENTRY
@@ -46,12 +44,10 @@ enum LedgerEntryType : std::uint16_t
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/** A special type, matching any ledger entry type. /** A special type, matching any ledger entry type.
The value does not represent a concrete type, but rather is used in The value does not represent a concrete type, but rather is used in contexts where the
contexts where the specific type of a ledger object is unimportant, specific type of a ledger object is unimportant, unknown or unavailable.
unknown or unavailable.
Objects with this special type cannot be created or stored on the Objects with this special type cannot be created or stored on the ledger.
ledger.
\sa keylet::unchecked \sa keylet::unchecked
*/ */
@@ -59,12 +55,11 @@ enum LedgerEntryType : std::uint16_t
/** A special type, matching any ledger type except directory nodes. /** A special type, matching any ledger type except directory nodes.
The value does not represent a concrete type, but rather is used in The value does not represent a concrete type, but rather is used in contexts where the
contexts where the ledger object must not be a directory node but ledger object must not be a directory node but its specific type is otherwise unimportant,
its specific type is otherwise unimportant, unknown or unavailable. unknown or unavailable.
Objects with this special type cannot be created or stored on the Objects with this special type cannot be created or stored on the ledger.
ledger.
\sa keylet::child \sa keylet::child
*/ */
@@ -93,104 +88,188 @@ enum LedgerEntryType : std::uint16_t
Support for this type of object was never implemented. Support for this type of object was never implemented.
No objects of this type were ever created. No objects of this type were ever created.
*/ */
ltGENERATOR_MAP [[deprecated("This object type is not supported and should not be used.")]] = 0x0067, ltGENERATOR_MAP [[deprecated("This object type is not supported and should not be used.")]] =
0x0067,
}; };
// clang-format off
/** /** Ledger object flags.
These flags are specified in ledger objects and modify their behavior.
@warning Ledger object flags form part of the protocol.
**Changing them should be avoided because without special handling, this will result in a hard
fork.**
@ingroup protocol @ingroup protocol
*/ */
enum LedgerSpecificFlags { #pragma push_macro("XMACRO")
// ltACCOUNT_ROOT #pragma push_macro("TO_VALUE")
lsfPasswordSpent = 0x00010000, // True, if password set fee is spent. #pragma push_macro("VALUE_TO_MAP")
lsfRequireDestTag = #pragma push_macro("NULL_NAME")
0x00020000, // True, to require a DestinationTag for payments. #pragma push_macro("TO_MAP")
lsfRequireAuth = #pragma push_macro("ALL_LEDGER_FLAGS")
0x00040000, // True, to require a authorization to hold IOUs.
lsfDisallowXRP = 0x00080000, // True, to disallow sending XRP.
lsfDisableMaster = 0x00100000, // True, force regular key
lsfNoFreeze = 0x00200000, // True, cannot freeze ripple states
lsfGlobalFreeze = 0x00400000, // True, all assets frozen
lsfDefaultRipple =
0x00800000, // True, incoming trust lines allow rippling by default
lsfDepositAuth = 0x01000000, // True, all deposits require authorization
/* // reserved for Hooks amendment
lsfTshCollect = 0x02000000, // True, allow TSH collect-calls to acc hooks
*/
lsfDisallowIncomingNFTokenOffer =
0x04000000, // True, reject new incoming NFT offers
lsfDisallowIncomingCheck =
0x08000000, // True, reject new checks
lsfDisallowIncomingPayChan =
0x10000000, // True, reject new paychans
lsfDisallowIncomingTrustline =
0x20000000, // True, reject new trustlines (only if no issued assets)
lsfAllowTrustLineLocking =
0x40000000, // True, enable trustline locking
lsfAllowTrustLineClawback =
0x80000000, // True, enable clawback
// ltOFFER #undef XMACRO
lsfPassive = 0x00010000, #undef TO_VALUE
lsfSell = 0x00020000, // True, offer was placed as a sell. #undef VALUE_TO_MAP
lsfHybrid = 0x00040000, // True, offer is hybrid. #undef NULL_NAME
#undef TO_MAP
// ltRIPPLE_STATE #undef ALL_LEDGER_FLAGS
lsfLowReserve = 0x00010000, // True, if entry counts toward reserve.
lsfHighReserve = 0x00020000,
lsfLowAuth = 0x00040000,
lsfHighAuth = 0x00080000,
lsfLowNoRipple = 0x00100000,
lsfHighNoRipple = 0x00200000,
lsfLowFreeze = 0x00400000, // True, low side has set freeze flag
lsfHighFreeze = 0x00800000, // True, high side has set freeze flag
lsfLowDeepFreeze = 0x02000000, // True, low side has set deep freeze flag
lsfHighDeepFreeze = 0x04000000, // True, high side has set deep freeze flag
lsfAMMNode = 0x01000000, // True, trust line to AMM. Used by client
// apps to identify payments via AMM.
// ltSIGNER_LIST // clang-format off
lsfOneOwnerCount = 0x00010000, // True, uses only one OwnerCount
// ltDIR_NODE #define XMACRO(LEDGER_OBJECT, LSF_FLAG, LSF_FLAG2) \
lsfNFTokenBuyOffers = 0x00000001, LEDGER_OBJECT(AccountRoot, \
lsfNFTokenSellOffers = 0x00000002, LSF_FLAG(lsfPasswordSpent, 0x00010000) /* True, if password set fee is spent. */ \
LSF_FLAG(lsfRequireDestTag, 0x00020000) /* True, to require a DestinationTag for payments. */ \
LSF_FLAG(lsfRequireAuth, 0x00040000) /* True, to require a authorization to hold IOUs. */ \
LSF_FLAG(lsfDisallowXRP, 0x00080000) /* True, to disallow sending XRP. */ \
LSF_FLAG(lsfDisableMaster, 0x00100000) /* True, force regular key */ \
LSF_FLAG(lsfNoFreeze, 0x00200000) /* True, cannot freeze ripple states */ \
LSF_FLAG(lsfGlobalFreeze, 0x00400000) /* True, all assets frozen */ \
LSF_FLAG(lsfDefaultRipple, 0x00800000) /* True, incoming trust lines allow rippling by default */ \
LSF_FLAG(lsfDepositAuth, 0x01000000) /* True, all deposits require authorization */ \
LSF_FLAG(lsfDisallowIncomingNFTokenOffer, 0x04000000) /* True, reject new incoming NFT offers */ \
LSF_FLAG(lsfDisallowIncomingCheck, 0x08000000) /* True, reject new checks */ \
LSF_FLAG(lsfDisallowIncomingPayChan, 0x10000000) /* True, reject new paychans */ \
LSF_FLAG(lsfDisallowIncomingTrustline, 0x20000000) /* True, reject new trustlines (only if no issued assets) */ \
LSF_FLAG(lsfAllowTrustLineLocking, 0x40000000) /* True, enable trustline locking */ \
LSF_FLAG(lsfAllowTrustLineClawback, 0x80000000)) /* True, enable clawback */ \
\
LEDGER_OBJECT(Offer, \
LSF_FLAG(lsfPassive, 0x00010000) \
LSF_FLAG(lsfSell, 0x00020000) /* True, offer was placed as a sell. */ \
LSF_FLAG(lsfHybrid, 0x00040000)) /* True, offer is hybrid. */ \
\
LEDGER_OBJECT(RippleState, \
LSF_FLAG(lsfLowReserve, 0x00010000) /* True, if entry counts toward reserve. */ \
LSF_FLAG(lsfHighReserve, 0x00020000) \
LSF_FLAG(lsfLowAuth, 0x00040000) \
LSF_FLAG(lsfHighAuth, 0x00080000) \
LSF_FLAG(lsfLowNoRipple, 0x00100000) \
LSF_FLAG(lsfHighNoRipple, 0x00200000) \
LSF_FLAG(lsfLowFreeze, 0x00400000) /* True, low side has set freeze flag */ \
LSF_FLAG(lsfHighFreeze, 0x00800000) /* True, high side has set freeze flag */ \
LSF_FLAG(lsfAMMNode, 0x01000000) /* True, trust line to AMM. */ \
/* Used by client apps to identify payments via AMM. */ \
LSF_FLAG(lsfLowDeepFreeze, 0x02000000) /* True, low side has set deep freeze flag */ \
LSF_FLAG(lsfHighDeepFreeze, 0x04000000)) /* True, high side has set deep freeze flag */ \
\
LEDGER_OBJECT(SignerList, \
LSF_FLAG(lsfOneOwnerCount, 0x00010000)) /* True, uses only one OwnerCount */ \
\
LEDGER_OBJECT(DirNode, \
LSF_FLAG(lsfNFTokenBuyOffers, 0x00000001) \
LSF_FLAG(lsfNFTokenSellOffers, 0x00000002)) \
\
LEDGER_OBJECT(NFTokenOffer, \
LSF_FLAG(lsfSellNFToken, 0x00000001)) \
\
LEDGER_OBJECT(MPTokenIssuance, \
LSF_FLAG(lsfMPTLocked, 0x00000001) /* Also used in ltMPTOKEN */ \
LSF_FLAG(lsfMPTCanLock, 0x00000002) \
LSF_FLAG(lsfMPTRequireAuth, 0x00000004) \
LSF_FLAG(lsfMPTCanEscrow, 0x00000008) \
LSF_FLAG(lsfMPTCanTrade, 0x00000010) \
LSF_FLAG(lsfMPTCanTransfer, 0x00000020) \
LSF_FLAG(lsfMPTCanClawback, 0x00000040)) \
\
LEDGER_OBJECT(MPTokenIssuanceMutable, \
LSF_FLAG(lsmfMPTCanMutateCanLock, 0x00000002) \
LSF_FLAG(lsmfMPTCanMutateRequireAuth, 0x00000004) \
LSF_FLAG(lsmfMPTCanMutateCanEscrow, 0x00000008) \
LSF_FLAG(lsmfMPTCanMutateCanTrade, 0x00000010) \
LSF_FLAG(lsmfMPTCanMutateCanTransfer, 0x00000020) \
LSF_FLAG(lsmfMPTCanMutateCanClawback, 0x00000040) \
LSF_FLAG(lsmfMPTCanMutateMetadata, 0x00010000) \
LSF_FLAG(lsmfMPTCanMutateTransferFee, 0x00020000)) \
\
LEDGER_OBJECT(MPToken, \
LSF_FLAG2(lsfMPTLocked, 0x00000001) \
LSF_FLAG(lsfMPTAuthorized, 0x00000002)) \
\
LEDGER_OBJECT(Credential, \
LSF_FLAG(lsfAccepted, 0x00010000)) \
\
LEDGER_OBJECT(Vault, \
LSF_FLAG(lsfVaultPrivate, 0x00010000)) \
\
LEDGER_OBJECT(Loan, \
LSF_FLAG(lsfLoanDefault, 0x00010000) \
LSF_FLAG(lsfLoanImpaired, 0x00020000) \
LSF_FLAG(lsfLoanOverpayment, 0x00040000)) /* True, loan allows overpayments */
// ltNFTOKEN_OFFER // clang-format on
lsfSellNFToken = 0x00000001,
// ltMPTOKEN_ISSUANCE // Create all the flag values as an enum.
lsfMPTLocked = 0x00000001, // Also used in ltMPTOKEN //
lsfMPTCanLock = 0x00000002, // example:
lsfMPTRequireAuth = 0x00000004, // enum LedgerSpecificFlags {
lsfMPTCanEscrow = 0x00000008, // lsfPasswordSpent = 0x00010000,
lsfMPTCanTrade = 0x00000010, // lsfRequireDestTag = 0x00020000,
lsfMPTCanTransfer = 0x00000020, // ...
lsfMPTCanClawback = 0x00000040, // };
#define TO_VALUE(name, value) name = value,
#define NULL_NAME(name, values) values
#define NULL_OUTPUT(name, value)
enum LedgerSpecificFlags : std::uint32_t { XMACRO(NULL_NAME, TO_VALUE, NULL_OUTPUT) };
lsmfMPTCanMutateCanLock = 0x00000002, // Create getter functions for each set of flags using Meyer's singleton pattern.
lsmfMPTCanMutateRequireAuth = 0x00000004, // This avoids static initialization order fiasco while still providing efficient access.
lsmfMPTCanMutateCanEscrow = 0x00000008, // This is used below in `getAllLedgerFlags()` to generate the server_definitions RPC output.
lsmfMPTCanMutateCanTrade = 0x00000010, //
lsmfMPTCanMutateCanTransfer = 0x00000020, // example:
lsmfMPTCanMutateCanClawback = 0x00000040, // inline LedgerFlagMap const& getAccountRootFlags() {
lsmfMPTCanMutateMetadata = 0x00010000, // static LedgerFlagMap const flags = {
lsmfMPTCanMutateTransferFee = 0x00020000, // {"lsfPasswordSpent", 0x00010000},
// {"lsfRequireDestTag", 0x00020000},
// ...};
// return flags;
// }
using LedgerFlagMap = std::map<std::string, std::uint32_t>;
#define VALUE_TO_MAP(name, value) {#name, value},
#define TO_MAP(name, values) \
inline LedgerFlagMap const& get##name##Flags() \
{ \
static LedgerFlagMap const flags = {values}; \
return flags; \
}
XMACRO(TO_MAP, VALUE_TO_MAP, VALUE_TO_MAP)
// ltMPTOKEN // Create a getter function for all ledger flag maps using Meyer's singleton pattern.
lsfMPTAuthorized = 0x00000002, // This is used to generate the server_definitions RPC output.
//
// example:
// inline std::vector<std::pair<std::string, LedgerFlagMap>> const& getAllLedgerFlags() {
// static std::vector<std::pair<std::string, LedgerFlagMap>> const flags = {
// {"AccountRoot", getAccountRootFlags()},
// ...};
// return flags;
// }
#define ALL_LEDGER_FLAGS(name, values) {#name, get##name##Flags()},
inline std::vector<std::pair<std::string, LedgerFlagMap>> const&
getAllLedgerFlags()
{
static std::vector<std::pair<std::string, LedgerFlagMap>> const flags = {
XMACRO(ALL_LEDGER_FLAGS, NULL_OUTPUT, NULL_OUTPUT)};
return flags;
}
// ltCREDENTIAL #undef XMACRO
lsfAccepted = 0x00010000, #undef TO_VALUE
#undef VALUE_TO_MAP
#undef NULL_NAME
#undef NULL_OUTPUT
#undef TO_MAP
#undef ALL_LEDGER_FLAGS
// ltVAULT #pragma pop_macro("XMACRO")
lsfVaultPrivate = 0x00010000, #pragma pop_macro("TO_VALUE")
#pragma pop_macro("VALUE_TO_MAP")
// ltLOAN #pragma pop_macro("NULL_NAME")
lsfLoanDefault = 0x00010000, #pragma pop_macro("TO_MAP")
lsfLoanImpaired = 0x00020000, #pragma pop_macro("ALL_LEDGER_FLAGS")
lsfLoanOverpayment = 0x00040000, // True, loan allows overpayments
};
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -207,6 +286,10 @@ private:
public: public:
static LedgerFormats const& static LedgerFormats const&
getInstance(); getInstance();
// Fields shared by all ledger entry formats:
static std::vector<SOElement> const&
getCommonFields();
}; };
} // namespace xrpl } // namespace xrpl

View File

@@ -6,6 +6,7 @@
#include <functional> #include <functional>
#include <initializer_list> #include <initializer_list>
#include <stdexcept> #include <stdexcept>
#include <vector>
namespace xrpl { namespace xrpl {
@@ -97,8 +98,12 @@ public:
operator=(SOTemplate&& other) = default; operator=(SOTemplate&& other) = default;
/** Create a template populated with all fields. /** Create a template populated with all fields.
After creating the template fields cannot be After creating the template fields cannot be added, modified, or removed.
added, modified, or removed. */
SOTemplate(std::vector<SOElement> uniqueFields, std::vector<SOElement> commonFields = {});
/** Create a template populated with all fields.
Note: Defers to the vector constructor above.
*/ */
SOTemplate( SOTemplate(
std::initializer_list<SOElement> uniqueFields, std::initializer_list<SOElement> uniqueFields,

View File

@@ -3,294 +3,444 @@
#include <xrpl/protocol/LedgerFormats.h> #include <xrpl/protocol/LedgerFormats.h>
#include <cstdint> #include <cstdint>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace xrpl { namespace xrpl {
/** Transaction flags. /** Transaction flags.
These flags are specified in a transaction's 'Flags' field and modify the These flags are specified in a transaction's 'Flags' field and modify
behavior of that transaction. the behavior of that transaction.
There are two types of flags: There are two types of flags:
(1) Universal flags: these are flags which apply to, and are interpreted (1) Universal flags: these are flags which apply to, and are interpreted the same way by,
the same way by, all transactions, except, perhaps, all transactions, except, perhaps, to special pseudo-transactions.
to special pseudo-transactions.
(2) Tx-Specific flags: these are flags which are interpreted according (2) Tx-Specific flags: these are flags which are interpreted according to the type of the
to the type of the transaction being executed. transaction being executed. That is, the same numerical flag value may have different
That is, the same numerical flag value may have effects, depending on the transaction being executed.
different effects, depending on the transaction
being executed.
@note The universal transaction flags occupy the high-order 8 bits. The @note The universal transaction flags occupy the high-order 8 bits.
tx-specific flags occupy the remaining 24 bits. The tx-specific flags occupy the remaining 24 bits.
@warning Transaction flags form part of the protocol. **Changing them @warning Transaction flags form part of the protocol.
should be avoided because without special handling, this will **Changing them should be avoided because without special handling, this will result in
result in a hard fork.** a hard fork.**
@ingroup protocol @ingroup protocol
*/ */
// Formatting equals sign aligned 4 spaces after longest prefix, except for using FlagValue = std::uint32_t;
// wrapped lines
// clang-format off
// Universal Transaction flags: // Universal Transaction flags:
constexpr std::uint32_t tfFullyCanonicalSig = 0x80000000; inline constexpr FlagValue tfFullyCanonicalSig = 0x80000000;
constexpr std::uint32_t tfInnerBatchTxn = 0x40000000; inline constexpr FlagValue tfInnerBatchTxn = 0x40000000;
constexpr std::uint32_t tfUniversal = tfFullyCanonicalSig | tfInnerBatchTxn; inline constexpr FlagValue tfUniversal = tfFullyCanonicalSig | tfInnerBatchTxn;
constexpr std::uint32_t tfUniversalMask = ~tfUniversal; inline constexpr FlagValue tfUniversalMask = ~tfUniversal;
// AccountSet flags: #pragma push_macro("XMACRO")
constexpr std::uint32_t tfRequireDestTag = 0x00010000; #pragma push_macro("TO_VALUE")
constexpr std::uint32_t tfOptionalDestTag = 0x00020000; #pragma push_macro("VALUE_TO_MAP")
constexpr std::uint32_t tfRequireAuth = 0x00040000; #pragma push_macro("NULL_NAME")
constexpr std::uint32_t tfOptionalAuth = 0x00080000; #pragma push_macro("NULL_OUTPUT")
constexpr std::uint32_t tfDisallowXRP = 0x00100000; #pragma push_macro("TO_MAP")
constexpr std::uint32_t tfAllowXRP = 0x00200000; #pragma push_macro("TO_MASK")
constexpr std::uint32_t tfAccountSetMask = #pragma push_macro("VALUE_TO_MASK")
~(tfUniversal | tfRequireDestTag | tfOptionalDestTag | tfRequireAuth | #pragma push_macro("ALL_TX_FLAGS")
tfOptionalAuth | tfDisallowXRP | tfAllowXRP); #pragma push_macro("NULL_MASK_ADJ")
#pragma push_macro("MASK_ADJ_TO_MASK")
// AccountSet SetFlag/ClearFlag values #undef XMACRO
constexpr std::uint32_t asfRequireDest = 1; #undef TO_VALUE
constexpr std::uint32_t asfRequireAuth = 2; #undef VALUE_TO_MAP
constexpr std::uint32_t asfDisallowXRP = 3; #undef NULL_NAME
constexpr std::uint32_t asfDisableMaster = 4; #undef NULL_OUTPUT
constexpr std::uint32_t asfAccountTxnID = 5; #undef TO_MAP
constexpr std::uint32_t asfNoFreeze = 6; #undef TO_MASK
constexpr std::uint32_t asfGlobalFreeze = 7; #undef VALUE_TO_MASK
constexpr std::uint32_t asfDefaultRipple = 8; #undef NULL_MASK_ADJ
constexpr std::uint32_t asfDepositAuth = 9; #undef MASK_ADJ_TO_MASK
constexpr std::uint32_t asfAuthorizedNFTokenMinter = 10;
/* // reserved for Hooks amendment
constexpr std::uint32_t asfTshCollect = 11;
*/
constexpr std::uint32_t asfDisallowIncomingNFTokenOffer = 12;
constexpr std::uint32_t asfDisallowIncomingCheck = 13;
constexpr std::uint32_t asfDisallowIncomingPayChan = 14;
constexpr std::uint32_t asfDisallowIncomingTrustline = 15;
constexpr std::uint32_t asfAllowTrustLineClawback = 16;
constexpr std::uint32_t asfAllowTrustLineLocking = 17;
// OfferCreate flags: // clang-format off
constexpr std::uint32_t tfPassive = 0x00010000; #undef ALL_TX_FLAGS
constexpr std::uint32_t tfImmediateOrCancel = 0x00020000;
constexpr std::uint32_t tfFillOrKill = 0x00040000;
constexpr std::uint32_t tfSell = 0x00080000;
constexpr std::uint32_t tfHybrid = 0x00100000;
constexpr std::uint32_t tfOfferCreateMask =
~(tfUniversal | tfPassive | tfImmediateOrCancel | tfFillOrKill | tfSell | tfHybrid);
// Payment flags: // XMACRO parameters:
constexpr std::uint32_t tfNoRippleDirect = 0x00010000; // - TRANSACTION: handles the transaction name, its flags, and mask adjustment
constexpr std::uint32_t tfPartialPayment = 0x00020000; // - TF_FLAG: defines a new flag constant
constexpr std::uint32_t tfLimitQuality = 0x00040000; // - TF_FLAG2: references an existing flag constant (no new definition)
constexpr std::uint32_t tfPaymentMask = // - MASK_ADJ: specifies flags to add back to the mask (making them invalid for this tx type)
~(tfUniversal | tfPartialPayment | tfLimitQuality | tfNoRippleDirect);
constexpr std::uint32_t tfMPTPaymentMask = ~(tfUniversal | tfPartialPayment);
// TrustSet flags:
constexpr std::uint32_t tfSetfAuth = 0x00010000;
constexpr std::uint32_t tfSetNoRipple = 0x00020000;
constexpr std::uint32_t tfClearNoRipple = 0x00040000;
constexpr std::uint32_t tfSetFreeze = 0x00100000;
constexpr std::uint32_t tfClearFreeze = 0x00200000;
constexpr std::uint32_t tfSetDeepFreeze = 0x00400000;
constexpr std::uint32_t tfClearDeepFreeze = 0x00800000;
constexpr std::uint32_t tfTrustSetMask =
~(tfUniversal | tfSetfAuth | tfSetNoRipple | tfClearNoRipple | tfSetFreeze |
tfClearFreeze | tfSetDeepFreeze | tfClearDeepFreeze);
constexpr std::uint32_t tfTrustSetPermissionMask = ~(tfUniversal | tfSetfAuth | tfSetFreeze | tfClearFreeze);
// EnableAmendment flags:
constexpr std::uint32_t tfGotMajority = 0x00010000;
constexpr std::uint32_t tfLostMajority = 0x00020000;
constexpr std::uint32_t tfChangeMask =
~( tfUniversal | tfGotMajority | tfLostMajority);
// PaymentChannelClaim flags:
constexpr std::uint32_t tfRenew = 0x00010000;
constexpr std::uint32_t tfClose = 0x00020000;
constexpr std::uint32_t tfPayChanClaimMask = ~(tfUniversal | tfRenew | tfClose);
// NFTokenMint flags:
constexpr std::uint32_t const tfBurnable = 0x00000001;
constexpr std::uint32_t const tfOnlyXRP = 0x00000002;
constexpr std::uint32_t const tfTrustLine = 0x00000004;
constexpr std::uint32_t const tfTransferable = 0x00000008;
constexpr std::uint32_t const tfMutable = 0x00000010;
// MPTokenIssuanceCreate flags:
// Note: tf/lsfMPTLocked is intentionally omitted, since this transaction
// is not allowed to modify it.
constexpr std::uint32_t const tfMPTCanLock = lsfMPTCanLock;
constexpr std::uint32_t const tfMPTRequireAuth = lsfMPTRequireAuth;
constexpr std::uint32_t const tfMPTCanEscrow = lsfMPTCanEscrow;
constexpr std::uint32_t const tfMPTCanTrade = lsfMPTCanTrade;
constexpr std::uint32_t const tfMPTCanTransfer = lsfMPTCanTransfer;
constexpr std::uint32_t const tfMPTCanClawback = lsfMPTCanClawback;
constexpr std::uint32_t const tfMPTokenIssuanceCreateMask =
~(tfUniversal | tfMPTCanLock | tfMPTRequireAuth | tfMPTCanEscrow | tfMPTCanTrade | tfMPTCanTransfer | tfMPTCanClawback);
// MPTokenIssuanceCreate MutableFlags:
// Indicating specific fields or flags may be changed after issuance.
constexpr std::uint32_t const tmfMPTCanMutateCanLock = lsmfMPTCanMutateCanLock;
constexpr std::uint32_t const tmfMPTCanMutateRequireAuth = lsmfMPTCanMutateRequireAuth;
constexpr std::uint32_t const tmfMPTCanMutateCanEscrow = lsmfMPTCanMutateCanEscrow;
constexpr std::uint32_t const tmfMPTCanMutateCanTrade = lsmfMPTCanMutateCanTrade;
constexpr std::uint32_t const tmfMPTCanMutateCanTransfer = lsmfMPTCanMutateCanTransfer;
constexpr std::uint32_t const tmfMPTCanMutateCanClawback = lsmfMPTCanMutateCanClawback;
constexpr std::uint32_t const tmfMPTCanMutateMetadata = lsmfMPTCanMutateMetadata;
constexpr std::uint32_t const tmfMPTCanMutateTransferFee = lsmfMPTCanMutateTransferFee;
constexpr std::uint32_t const tmfMPTokenIssuanceCreateMutableMask =
~(tmfMPTCanMutateCanLock | tmfMPTCanMutateRequireAuth | tmfMPTCanMutateCanEscrow | tmfMPTCanMutateCanTrade
| tmfMPTCanMutateCanTransfer | tmfMPTCanMutateCanClawback | tmfMPTCanMutateMetadata | tmfMPTCanMutateTransferFee);
// MPTokenAuthorize flags:
constexpr std::uint32_t const tfMPTUnauthorize = 0x00000001;
constexpr std::uint32_t const tfMPTokenAuthorizeMask = ~(tfUniversal | tfMPTUnauthorize);
// MPTokenIssuanceSet flags:
constexpr std::uint32_t const tfMPTLock = 0x00000001;
constexpr std::uint32_t const tfMPTUnlock = 0x00000002;
constexpr std::uint32_t const tfMPTokenIssuanceSetMask = ~(tfUniversal | tfMPTLock | tfMPTUnlock);
constexpr std::uint32_t const tfMPTokenIssuanceSetPermissionMask = ~(tfUniversal | tfMPTLock | tfMPTUnlock);
// MPTokenIssuanceSet MutableFlags:
// Set or Clear flags.
constexpr std::uint32_t const tmfMPTSetCanLock = 0x00000001;
constexpr std::uint32_t const tmfMPTClearCanLock = 0x00000002;
constexpr std::uint32_t const tmfMPTSetRequireAuth = 0x00000004;
constexpr std::uint32_t const tmfMPTClearRequireAuth = 0x00000008;
constexpr std::uint32_t const tmfMPTSetCanEscrow = 0x00000010;
constexpr std::uint32_t const tmfMPTClearCanEscrow = 0x00000020;
constexpr std::uint32_t const tmfMPTSetCanTrade = 0x00000040;
constexpr std::uint32_t const tmfMPTClearCanTrade = 0x00000080;
constexpr std::uint32_t const tmfMPTSetCanTransfer = 0x00000100;
constexpr std::uint32_t const tmfMPTClearCanTransfer = 0x00000200;
constexpr std::uint32_t const tmfMPTSetCanClawback = 0x00000400;
constexpr std::uint32_t const tmfMPTClearCanClawback = 0x00000800;
constexpr std::uint32_t const tmfMPTokenIssuanceSetMutableMask = ~(tmfMPTSetCanLock | tmfMPTClearCanLock |
tmfMPTSetRequireAuth | tmfMPTClearRequireAuth | tmfMPTSetCanEscrow | tmfMPTClearCanEscrow |
tmfMPTSetCanTrade | tmfMPTClearCanTrade | tmfMPTSetCanTransfer | tmfMPTClearCanTransfer |
tmfMPTSetCanClawback | tmfMPTClearCanClawback);
// MPTokenIssuanceDestroy flags:
constexpr std::uint32_t const tfMPTokenIssuanceDestroyMask = ~tfUniversal;
// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between
// accounts allowed a TrustLine to be added to the issuer of that token
// without explicit permission from that issuer. This was enabled by
// minting the NFToken with the tfTrustLine flag set.
// //
// That capability could be used to attack the NFToken issuer. It // Note: MASK_ADJ is used when a universal flag should be invalid for a specific transaction.
// would be possible for two accounts to trade the NFToken back and forth // For example, Batch uses MASK_ADJ(tfInnerBatchTxn) because the outer Batch transaction
// building up any number of TrustLines on the issuer, increasing the // must not have tfInnerBatchTxn set (only inner transactions should have it).
// issuer's reserve without bound.
// //
// The fixRemoveNFTokenAutoTrustLine amendment disables minting with the // TODO: Consider rewriting this using reflection in C++26 or later. Alternatively this could be a DSL processed by a script at build time.
// tfTrustLine flag as a way to prevent the attack. But until the #define XMACRO(TRANSACTION, TF_FLAG, TF_FLAG2, MASK_ADJ) \
// amendment passes we still need to keep the old behavior available. TRANSACTION(AccountSet, \
constexpr std::uint32_t const tfNFTokenMintMask = TF_FLAG(tfRequireDestTag, 0x00010000) \
~(tfUniversal | tfBurnable | tfOnlyXRP | tfTransferable); TF_FLAG(tfOptionalDestTag, 0x00020000) \
TF_FLAG(tfRequireAuth, 0x00040000) \
constexpr std::uint32_t const tfNFTokenMintOldMask = TF_FLAG(tfOptionalAuth, 0x00080000) \
~( ~tfNFTokenMintMask | tfTrustLine); TF_FLAG(tfDisallowXRP, 0x00100000) \
TF_FLAG(tfAllowXRP, 0x00200000), \
// if featureDynamicNFT enabled then new flag allowing mutable URI available. MASK_ADJ(0)) \
constexpr std::uint32_t const tfNFTokenMintOldMaskWithMutable = \
~( ~tfNFTokenMintOldMask | tfMutable); TRANSACTION(OfferCreate, \
TF_FLAG(tfPassive, 0x00010000) \
constexpr std::uint32_t const tfNFTokenMintMaskWithMutable = TF_FLAG(tfImmediateOrCancel, 0x00020000) \
~( ~tfNFTokenMintMask | tfMutable); TF_FLAG(tfFillOrKill, 0x00040000) \
TF_FLAG(tfSell, 0x00080000) \
// NFTokenCreateOffer flags: TF_FLAG(tfHybrid, 0x00100000), \
constexpr std::uint32_t const tfSellNFToken = 0x00000001; MASK_ADJ(0)) \
constexpr std::uint32_t const tfNFTokenCreateOfferMask = \
~(tfUniversal | tfSellNFToken); TRANSACTION(Payment, \
TF_FLAG(tfNoRippleDirect, 0x00010000) \
// NFTokenCancelOffer flags: TF_FLAG(tfPartialPayment, 0x00020000) \
constexpr std::uint32_t const tfNFTokenCancelOfferMask = ~tfUniversal; TF_FLAG(tfLimitQuality, 0x00040000), \
MASK_ADJ(0)) \
// NFTokenAcceptOffer flags: \
constexpr std::uint32_t const tfNFTokenAcceptOfferMask = ~tfUniversal; TRANSACTION(TrustSet, \
TF_FLAG(tfSetfAuth, 0x00010000) \
// Clawback flags: TF_FLAG(tfSetNoRipple, 0x00020000) \
constexpr std::uint32_t const tfClawbackMask = ~tfUniversal; TF_FLAG(tfClearNoRipple, 0x00040000) \
TF_FLAG(tfSetFreeze, 0x00100000) \
// AMM Flags: TF_FLAG(tfClearFreeze, 0x00200000) \
constexpr std::uint32_t tfLPToken = 0x00010000; TF_FLAG(tfSetDeepFreeze, 0x00400000) \
constexpr std::uint32_t tfWithdrawAll = 0x00020000; TF_FLAG(tfClearDeepFreeze, 0x00800000), \
constexpr std::uint32_t tfOneAssetWithdrawAll = 0x00040000; MASK_ADJ(0)) \
constexpr std::uint32_t tfSingleAsset = 0x00080000; \
constexpr std::uint32_t tfTwoAsset = 0x00100000; TRANSACTION(EnableAmendment, \
constexpr std::uint32_t tfOneAssetLPToken = 0x00200000; TF_FLAG(tfGotMajority, 0x00010000) \
constexpr std::uint32_t tfLimitLPToken = 0x00400000; TF_FLAG(tfLostMajority, 0x00020000), \
constexpr std::uint32_t tfTwoAssetIfEmpty = 0x00800000; MASK_ADJ(0)) \
constexpr std::uint32_t tfWithdrawSubTx = \
tfLPToken | tfSingleAsset | tfTwoAsset | tfOneAssetLPToken | TRANSACTION(PaymentChannelClaim, \
tfLimitLPToken | tfWithdrawAll | tfOneAssetWithdrawAll; TF_FLAG(tfRenew, 0x00010000) \
constexpr std::uint32_t tfDepositSubTx = TF_FLAG(tfClose, 0x00020000), \
tfLPToken | tfSingleAsset | tfTwoAsset | tfOneAssetLPToken | MASK_ADJ(0)) \
tfLimitLPToken | tfTwoAssetIfEmpty; \
constexpr std::uint32_t tfWithdrawMask = ~(tfUniversal | tfWithdrawSubTx); TRANSACTION(NFTokenMint, \
constexpr std::uint32_t tfDepositMask = ~(tfUniversal | tfDepositSubTx); TF_FLAG(tfBurnable, 0x00000001) \
TF_FLAG(tfOnlyXRP, 0x00000002) \
// AMMClawback flags: /* deprecated TF_FLAG(tfTrustLine, 0x00000004) */ \
constexpr std::uint32_t tfClawTwoAssets = 0x00000001; TF_FLAG(tfTransferable, 0x00000008) \
constexpr std::uint32_t tfAMMClawbackMask = ~(tfUniversal | tfClawTwoAssets); TF_FLAG(tfMutable, 0x00000010), \
MASK_ADJ(0)) \
// BridgeModify flags: \
constexpr std::uint32_t tfClearAccountCreateAmount = 0x00010000; TRANSACTION(MPTokenIssuanceCreate, \
constexpr std::uint32_t tfBridgeModifyMask = ~(tfUniversal | tfClearAccountCreateAmount); /* Note: tf/lsfMPTLocked is intentionally omitted since this transaction is not allowed to modify it. */ \
TF_FLAG(tfMPTCanLock, lsfMPTCanLock) \
// VaultCreate flags: TF_FLAG(tfMPTRequireAuth, lsfMPTRequireAuth) \
constexpr std::uint32_t const tfVaultPrivate = 0x00010000; TF_FLAG(tfMPTCanEscrow, lsfMPTCanEscrow) \
static_assert(tfVaultPrivate == lsfVaultPrivate); TF_FLAG(tfMPTCanTrade, lsfMPTCanTrade) \
constexpr std::uint32_t const tfVaultShareNonTransferable = 0x00020000; TF_FLAG(tfMPTCanTransfer, lsfMPTCanTransfer) \
constexpr std::uint32_t const tfVaultCreateMask = ~(tfUniversal | tfVaultPrivate | tfVaultShareNonTransferable); TF_FLAG(tfMPTCanClawback, lsfMPTCanClawback), \
MASK_ADJ(0)) \
// Batch Flags: \
constexpr std::uint32_t tfAllOrNothing = 0x00010000; TRANSACTION(MPTokenAuthorize, \
constexpr std::uint32_t tfOnlyOne = 0x00020000; TF_FLAG(tfMPTUnauthorize, 0x00000001), \
constexpr std::uint32_t tfUntilFailure = 0x00040000; MASK_ADJ(0)) \
constexpr std::uint32_t tfIndependent = 0x00080000; \
/** TRANSACTION(MPTokenIssuanceSet, \
* @note If nested Batch transactions are supported in the future, the tfInnerBatchTxn flag TF_FLAG(tfMPTLock, 0x00000001) \
* will need to be removed from this mask to allow Batch transaction to be inside TF_FLAG(tfMPTUnlock, 0x00000002), \
* the sfRawTransactions array. MASK_ADJ(0)) \
*/ \
constexpr std::uint32_t const tfBatchMask = TRANSACTION(NFTokenCreateOffer, \
~(tfUniversal | tfAllOrNothing | tfOnlyOne | tfUntilFailure | tfIndependent) | tfInnerBatchTxn; TF_FLAG(tfSellNFToken, 0x00000001), \
MASK_ADJ(0)) \
// LoanSet and LoanPay flags: \
// LoanSet: True, indicates the loan supports overpayments TRANSACTION(AMMDeposit, \
// LoanPay: True, indicates any excess in this payment can be used TF_FLAG(tfLPToken, 0x00010000) \
// as an overpayment. False, no overpayments will be taken. TF_FLAG(tfSingleAsset, 0x00080000) \
constexpr std::uint32_t const tfLoanOverpayment = 0x00010000; TF_FLAG(tfTwoAsset, 0x00100000) \
// LoanPay exclusive flags: TF_FLAG(tfOneAssetLPToken, 0x00200000) \
// tfLoanFullPayment: True, indicates that the payment is an early TF_FLAG(tfLimitLPToken, 0x00400000) \
// full payment. It must pay the entire loan including close TF_FLAG(tfTwoAssetIfEmpty, 0x00800000), \
// interest and fees, or it will fail. False: Not a full payment. MASK_ADJ(0)) \
constexpr std::uint32_t const tfLoanFullPayment = 0x00020000; \
// tfLoanLatePayment: True, indicates that the payment is late, TRANSACTION(AMMWithdraw, \
// and includes late interest and fees. If the loan is not late, TF_FLAG2(tfLPToken, 0x00010000) \
// it will fail. False: not a late payment. If the current payment TF_FLAG(tfWithdrawAll, 0x00020000) \
// is overdue, the transaction will fail. TF_FLAG(tfOneAssetWithdrawAll, 0x00040000) \
constexpr std::uint32_t const tfLoanLatePayment = 0x00040000; TF_FLAG2(tfSingleAsset, 0x00080000) \
constexpr std::uint32_t const tfLoanSetMask = ~(tfUniversal | TF_FLAG2(tfTwoAsset, 0x00100000) \
tfLoanOverpayment); TF_FLAG2(tfOneAssetLPToken, 0x00200000) \
constexpr std::uint32_t const tfLoanPayMask = ~(tfUniversal | TF_FLAG2(tfLimitLPToken, 0x00400000), \
tfLoanOverpayment | tfLoanFullPayment | tfLoanLatePayment); MASK_ADJ(0)) \
\
// LoanManage flags: TRANSACTION(AMMClawback, \
constexpr std::uint32_t const tfLoanDefault = 0x00010000; TF_FLAG(tfClawTwoAssets, 0x00000001), \
constexpr std::uint32_t const tfLoanImpair = 0x00020000; MASK_ADJ(0)) \
constexpr std::uint32_t const tfLoanUnimpair = 0x00040000; \
constexpr std::uint32_t const tfLoanManageMask = ~(tfUniversal | tfLoanDefault | tfLoanImpair | tfLoanUnimpair); TRANSACTION(XChainModifyBridge, \
TF_FLAG(tfClearAccountCreateAmount, 0x00010000), \
MASK_ADJ(0)) \
\
TRANSACTION(VaultCreate, \
TF_FLAG(tfVaultPrivate, lsfVaultPrivate) \
TF_FLAG(tfVaultShareNonTransferable, 0x00020000), \
MASK_ADJ(0)) \
\
TRANSACTION(Batch, \
TF_FLAG(tfAllOrNothing, 0x00010000) \
TF_FLAG(tfOnlyOne, 0x00020000) \
TF_FLAG(tfUntilFailure, 0x00040000) \
TF_FLAG(tfIndependent, 0x00080000), \
MASK_ADJ(tfInnerBatchTxn)) /* Batch must reject tfInnerBatchTxn - only inner transactions should have this flag */ \
\
TRANSACTION(LoanSet, /* True indicates the loan supports overpayments */ \
TF_FLAG(tfLoanOverpayment, 0x00010000), \
MASK_ADJ(0)) \
\
TRANSACTION(LoanPay, /* True indicates any excess in this payment can be used as an overpayment. */ \
/* False: no overpayments will be taken. */ \
TF_FLAG2(tfLoanOverpayment, 0x00010000) \
TF_FLAG(tfLoanFullPayment, 0x00020000) /* True indicates that the payment is an early full payment. */ \
/* It must pay the entire loan including close interest and fees, or it will fail. */ \
/* False: Not a full payment. */ \
TF_FLAG(tfLoanLatePayment, 0x00040000), /* True indicates that the payment is late, and includes late interest and fees. */ \
/* If the loan is not late, it will fail. */ \
/* False: not a late payment. If the current payment is overdue, the transaction will fail.*/ \
MASK_ADJ(0)) \
\
TRANSACTION(LoanManage, \
TF_FLAG(tfLoanDefault, 0x00010000) \
TF_FLAG(tfLoanImpair, 0x00020000) \
TF_FLAG(tfLoanUnimpair, 0x00040000), \
MASK_ADJ(0))
// clang-format on // clang-format on
// Create all the flag values.
//
// example:
// inline constexpr FlagValue tfAccountSetRequireDestTag = 0x00010000;
#define TO_VALUE(name, value) inline constexpr FlagValue name = value;
#define NULL_NAME(name, values, maskAdj) values
#define NULL_OUTPUT(name, value)
#define NULL_MASK_ADJ(value)
XMACRO(NULL_NAME, TO_VALUE, NULL_OUTPUT, NULL_MASK_ADJ)
// Create masks for each transaction type that has flags.
//
// example:
// inline constexpr FlagValue tfAccountSetMask = ~(tfUniversal | tfRequireDestTag |
// tfOptionalDestTag | tfRequireAuth | tfOptionalAuth | tfDisallowXRP | tfAllowXRP);
//
// The mask adjustment (maskAdj) allows adding flags back to the mask, making them invalid.
// For example, Batch uses MASK_ADJ(tfInnerBatchTxn) to reject tfInnerBatchTxn on outer Batch.
#define TO_MASK(name, values, maskAdj) \
inline constexpr FlagValue tf##name##Mask = ~(tfUniversal values) | maskAdj;
#define VALUE_TO_MASK(name, value) | name
#define MASK_ADJ_TO_MASK(value) value
XMACRO(TO_MASK, VALUE_TO_MASK, VALUE_TO_MASK, MASK_ADJ_TO_MASK)
// Verify that tfBatchMask correctly rejects tfInnerBatchTxn.
// The outer Batch transaction must NOT have tfInnerBatchTxn set; only inner transactions should
// have it.
static_assert(
(tfBatchMask & tfInnerBatchTxn) == tfInnerBatchTxn,
"tfBatchMask must include tfInnerBatchTxn to reject it on outer Batch");
// Verify that other transaction masks correctly allow tfInnerBatchTxn.
// Inner transactions need tfInnerBatchTxn to be valid, so these masks must not reject it.
static_assert(
(tfPaymentMask & tfInnerBatchTxn) == 0,
"tfPaymentMask must not reject tfInnerBatchTxn");
static_assert(
(tfAccountSetMask & tfInnerBatchTxn) == 0,
"tfAccountSetMask must not reject tfInnerBatchTxn");
// Create getter functions for each set of flags using Meyer's singleton pattern.
// This avoids static initialization order fiasco while still providing efficient access.
// This is used below in `getAllTxFlags()` to generate the server_definitions RPC
// output.
//
// example:
// inline FlagMap const& getAccountSetFlags() {
// static FlagMap const flags = {
// {"tfRequireDestTag", 0x00010000},
// {"tfOptionalDestTag", 0x00020000},
// ...};
// return flags;
// }
using FlagMap = std::map<std::string, FlagValue>;
#define VALUE_TO_MAP(name, value) {#name, value},
#define TO_MAP(name, values, maskAdj) \
inline FlagMap const& get##name##Flags() \
{ \
static FlagMap const flags = {values}; \
return flags; \
}
XMACRO(TO_MAP, VALUE_TO_MAP, VALUE_TO_MAP, NULL_MASK_ADJ)
inline FlagMap const&
getUniversalFlags()
{
static FlagMap const flags = {
{"tfFullyCanonicalSig", tfFullyCanonicalSig}, {"tfInnerBatchTxn", tfInnerBatchTxn}};
return flags;
}
// Create a getter function for all transaction flag maps using Meyer's singleton pattern.
// This is used to generate the server_definitions RPC output.
//
// example:
// inline FlagMapPairList const& getAllTxFlags() {
// static FlagMapPairList const flags = {
// {"AccountSet", getAccountSetFlags()},
// ...};
// return flags;
// }
using FlagMapPairList = std::vector<std::pair<std::string, FlagMap>>;
#define ALL_TX_FLAGS(name, values, maskAdj) {#name, get##name##Flags()},
inline FlagMapPairList const&
getAllTxFlags()
{
static FlagMapPairList const flags = {
{"universal", getUniversalFlags()},
XMACRO(ALL_TX_FLAGS, NULL_OUTPUT, NULL_OUTPUT, NULL_MASK_ADJ)};
return flags;
}
#undef XMACRO
#undef TO_VALUE
#undef VALUE_TO_MAP
#undef NULL_NAME
#undef NULL_OUTPUT
#undef TO_MAP
#undef TO_MASK
#undef VALUE_TO_MASK
#undef ALL_TX_FLAGS
#undef NULL_MASK_ADJ
#undef MASK_ADJ_TO_MASK
#pragma pop_macro("XMACRO")
#pragma pop_macro("TO_VALUE")
#pragma pop_macro("VALUE_TO_MAP")
#pragma pop_macro("NULL_NAME")
#pragma pop_macro("NULL_OUTPUT")
#pragma pop_macro("TO_MAP")
#pragma pop_macro("TO_MASK")
#pragma pop_macro("VALUE_TO_MASK")
#pragma pop_macro("ALL_TX_FLAGS")
#pragma pop_macro("NULL_MASK_ADJ")
#pragma pop_macro("MASK_ADJ_TO_MASK")
// Additional transaction masks and combos
inline constexpr FlagValue tfMPTPaymentMask = ~(tfUniversal | tfPartialPayment);
inline constexpr FlagValue tfTrustSetPermissionMask =
~(tfUniversal | tfSetfAuth | tfSetFreeze | tfClearFreeze);
// MPTokenIssuanceCreate MutableFlags:
// Indicating specific fields or flags may be changed after issuance.
inline constexpr FlagValue tmfMPTCanMutateCanLock = lsmfMPTCanMutateCanLock;
inline constexpr FlagValue tmfMPTCanMutateRequireAuth = lsmfMPTCanMutateRequireAuth;
inline constexpr FlagValue tmfMPTCanMutateCanEscrow = lsmfMPTCanMutateCanEscrow;
inline constexpr FlagValue tmfMPTCanMutateCanTrade = lsmfMPTCanMutateCanTrade;
inline constexpr FlagValue tmfMPTCanMutateCanTransfer = lsmfMPTCanMutateCanTransfer;
inline constexpr FlagValue tmfMPTCanMutateCanClawback = lsmfMPTCanMutateCanClawback;
inline constexpr FlagValue tmfMPTCanMutateMetadata = lsmfMPTCanMutateMetadata;
inline constexpr FlagValue tmfMPTCanMutateTransferFee = lsmfMPTCanMutateTransferFee;
inline constexpr FlagValue tmfMPTokenIssuanceCreateMutableMask =
~(tmfMPTCanMutateCanLock | tmfMPTCanMutateRequireAuth | tmfMPTCanMutateCanEscrow |
tmfMPTCanMutateCanTrade | tmfMPTCanMutateCanTransfer | tmfMPTCanMutateCanClawback |
tmfMPTCanMutateMetadata | tmfMPTCanMutateTransferFee);
// MPTokenIssuanceSet MutableFlags:
// Set or Clear flags.
inline constexpr FlagValue tmfMPTSetCanLock = 0x00000001;
inline constexpr FlagValue tmfMPTClearCanLock = 0x00000002;
inline constexpr FlagValue tmfMPTSetRequireAuth = 0x00000004;
inline constexpr FlagValue tmfMPTClearRequireAuth = 0x00000008;
inline constexpr FlagValue tmfMPTSetCanEscrow = 0x00000010;
inline constexpr FlagValue tmfMPTClearCanEscrow = 0x00000020;
inline constexpr FlagValue tmfMPTSetCanTrade = 0x00000040;
inline constexpr FlagValue tmfMPTClearCanTrade = 0x00000080;
inline constexpr FlagValue tmfMPTSetCanTransfer = 0x00000100;
inline constexpr FlagValue tmfMPTClearCanTransfer = 0x00000200;
inline constexpr FlagValue tmfMPTSetCanClawback = 0x00000400;
inline constexpr FlagValue tmfMPTClearCanClawback = 0x00000800;
inline constexpr FlagValue tmfMPTokenIssuanceSetMutableMask = ~(
tmfMPTSetCanLock | tmfMPTClearCanLock | tmfMPTSetRequireAuth | tmfMPTClearRequireAuth |
tmfMPTSetCanEscrow | tmfMPTClearCanEscrow | tmfMPTSetCanTrade | tmfMPTClearCanTrade |
tmfMPTSetCanTransfer | tmfMPTClearCanTransfer | tmfMPTSetCanClawback | tmfMPTClearCanClawback);
// Prior to fixRemoveNFTokenAutoTrustLine, transfer of an NFToken between accounts allowed a
// TrustLine to be added to the issuer of that token without explicit permission from that issuer.
// This was enabled by minting the NFToken with the tfTrustLine flag set.
//
// That capability could be used to attack the NFToken issuer.
// It would be possible for two accounts to trade the NFToken back and forth building up any number
// of TrustLines on the issuer, increasing the issuer's reserve without bound.
//
// The fixRemoveNFTokenAutoTrustLine amendment disables minting with the tfTrustLine flag as a way
// to prevent the attack. But until the amendment passes we still need to keep the old behavior
// available.
inline constexpr FlagValue tfTrustLine = 0x00000004; // needed for backwards compatibility
inline constexpr FlagValue tfNFTokenMintMaskWithoutMutable =
~(tfUniversal | tfBurnable | tfOnlyXRP | tfTransferable);
inline constexpr FlagValue tfNFTokenMintOldMask = ~(~tfNFTokenMintMaskWithoutMutable | tfTrustLine);
// if featureDynamicNFT enabled then new flag allowing mutable URI available.
inline constexpr FlagValue tfNFTokenMintOldMaskWithMutable = ~(~tfNFTokenMintOldMask | tfMutable);
inline constexpr FlagValue tfWithdrawSubTx = tfLPToken | tfSingleAsset | tfTwoAsset |
tfOneAssetLPToken | tfLimitLPToken | tfWithdrawAll | tfOneAssetWithdrawAll;
inline constexpr FlagValue tfDepositSubTx =
tfLPToken | tfSingleAsset | tfTwoAsset | tfOneAssetLPToken | tfLimitLPToken | tfTwoAssetIfEmpty;
#pragma push_macro("ACCOUNTSET_FLAGS")
#pragma push_macro("ACCOUNTSET_FLAG_TO_VALUE")
#pragma push_macro("ACCOUNTSET_FLAG_TO_MAP")
// AccountSet SetFlag/ClearFlag values
#define ACCOUNTSET_FLAGS(ASF_FLAG) \
ASF_FLAG(asfRequireDest, 1) \
ASF_FLAG(asfRequireAuth, 2) \
ASF_FLAG(asfDisallowXRP, 3) \
ASF_FLAG(asfDisableMaster, 4) \
ASF_FLAG(asfAccountTxnID, 5) \
ASF_FLAG(asfNoFreeze, 6) \
ASF_FLAG(asfGlobalFreeze, 7) \
ASF_FLAG(asfDefaultRipple, 8) \
ASF_FLAG(asfDepositAuth, 9) \
ASF_FLAG(asfAuthorizedNFTokenMinter, 10) \
/* 11 is reserved for Hooks amendment */ \
/* ASF_FLAG(asfTshCollect, 11) */ \
ASF_FLAG(asfDisallowIncomingNFTokenOffer, 12) \
ASF_FLAG(asfDisallowIncomingCheck, 13) \
ASF_FLAG(asfDisallowIncomingPayChan, 14) \
ASF_FLAG(asfDisallowIncomingTrustline, 15) \
ASF_FLAG(asfAllowTrustLineClawback, 16) \
ASF_FLAG(asfAllowTrustLineLocking, 17)
#define ACCOUNTSET_FLAG_TO_VALUE(name, value) inline constexpr FlagValue name = value;
#define ACCOUNTSET_FLAG_TO_MAP(name, value) {#name, value},
ACCOUNTSET_FLAGS(ACCOUNTSET_FLAG_TO_VALUE)
inline std::map<std::string, FlagValue> const&
getAsfFlagMap()
{
static std::map<std::string, FlagValue> const flags = {
ACCOUNTSET_FLAGS(ACCOUNTSET_FLAG_TO_MAP)};
return flags;
}
#undef ACCOUNTSET_FLAG_TO_VALUE
#undef ACCOUNTSET_FLAG_TO_MAP
#undef ACCOUNTSET_FLAGS
#pragma pop_macro("ACCOUNTSET_FLAG_TO_VALUE")
#pragma pop_macro("ACCOUNTSET_FLAG_TO_MAP")
#pragma pop_macro("ACCOUNTSET_FLAGS")
} // namespace xrpl } // namespace xrpl

View File

@@ -2,6 +2,8 @@
#include <xrpl/protocol/KnownFormats.h> #include <xrpl/protocol/KnownFormats.h>
#include <vector>
namespace xrpl { namespace xrpl {
/** Transaction type identifiers. /** Transaction type identifiers.
@@ -73,6 +75,9 @@ private:
public: public:
static TxFormats const& static TxFormats const&
getInstance(); getInstance();
static std::vector<SOElement> const&
getCommonFields();
}; };
} // namespace xrpl } // namespace xrpl

View File

@@ -22,7 +22,7 @@
/** This transaction type executes a payment. */ /** This transaction type executes a payment. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Payment.h> # include <xrpl/tx/transactors/payment/Payment.h>
#endif #endif
TRANSACTION(ttPAYMENT, 0, Payment, TRANSACTION(ttPAYMENT, 0, Payment,
Delegation::delegable, Delegation::delegable,
@@ -42,7 +42,7 @@ TRANSACTION(ttPAYMENT, 0, Payment,
/** This transaction type creates an escrow object. */ /** This transaction type creates an escrow object. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Escrow.h> # include <xrpl/tx/transactors/escrow/Escrow.h>
#endif #endif
TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate,
Delegation::delegable, Delegation::delegable,
@@ -73,7 +73,7 @@ TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish,
/** This transaction type adjusts various account settings. */ /** This transaction type adjusts various account settings. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/SetAccount.h> # include <xrpl/tx/transactors/account/SetAccount.h>
#endif #endif
TRANSACTION(ttACCOUNT_SET, 3, AccountSet, TRANSACTION(ttACCOUNT_SET, 3, AccountSet,
Delegation::notDelegable, Delegation::notDelegable,
@@ -94,7 +94,7 @@ TRANSACTION(ttACCOUNT_SET, 3, AccountSet,
/** This transaction type cancels an existing escrow. */ /** This transaction type cancels an existing escrow. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Escrow.h> # include <xrpl/tx/transactors/escrow/Escrow.h>
#endif #endif
TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel, TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel,
Delegation::delegable, Delegation::delegable,
@@ -107,7 +107,7 @@ TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel,
/** This transaction type sets or clears an account's "regular key". */ /** This transaction type sets or clears an account's "regular key". */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/SetRegularKey.h> # include <xrpl/tx/transactors/account/SetRegularKey.h>
#endif #endif
TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey, TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey,
Delegation::notDelegable, Delegation::notDelegable,
@@ -121,7 +121,7 @@ TRANSACTION(ttREGULAR_KEY_SET, 5, SetRegularKey,
/** This transaction type creates an offer to trade one asset for another. */ /** This transaction type creates an offer to trade one asset for another. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Offer/CreateOffer.h> # include <xrpl/tx/transactors/dex/CreateOffer.h>
#endif #endif
TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, TRANSACTION(ttOFFER_CREATE, 7, OfferCreate,
Delegation::delegable, Delegation::delegable,
@@ -137,7 +137,7 @@ TRANSACTION(ttOFFER_CREATE, 7, OfferCreate,
/** This transaction type cancels existing offers to trade one asset for another. */ /** This transaction type cancels existing offers to trade one asset for another. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Offer/CancelOffer.h> # include <xrpl/tx/transactors/dex/CancelOffer.h>
#endif #endif
TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel,
Delegation::delegable, Delegation::delegable,
@@ -151,7 +151,7 @@ TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel,
/** This transaction type creates a new set of tickets. */ /** This transaction type creates a new set of tickets. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/CreateTicket.h> # include <xrpl/tx/transactors/system/CreateTicket.h>
#endif #endif
TRANSACTION(ttTICKET_CREATE, 10, TicketCreate, TRANSACTION(ttTICKET_CREATE, 10, TicketCreate,
Delegation::delegable, Delegation::delegable,
@@ -167,7 +167,7 @@ TRANSACTION(ttTICKET_CREATE, 10, TicketCreate,
// The SignerEntries are optional because a SignerList is deleted by // The SignerEntries are optional because a SignerList is deleted by
// setting the SignerQuorum to zero and omitting SignerEntries. // setting the SignerQuorum to zero and omitting SignerEntries.
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/SetSignerList.h> # include <xrpl/tx/transactors/account/SetSignerList.h>
#endif #endif
TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet, TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet,
Delegation::notDelegable, Delegation::notDelegable,
@@ -180,7 +180,7 @@ TRANSACTION(ttSIGNER_LIST_SET, 12, SignerListSet,
/** This transaction type creates a new unidirectional XRP payment channel. */ /** This transaction type creates a new unidirectional XRP payment channel. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/PayChan.h> # include <xrpl/tx/transactors/payment_channel/PayChan.h>
#endif #endif
TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate, TRANSACTION(ttPAYCHAN_CREATE, 13, PaymentChannelCreate,
Delegation::delegable, Delegation::delegable,
@@ -222,7 +222,7 @@ TRANSACTION(ttPAYCHAN_CLAIM, 15, PaymentChannelClaim,
/** This transaction type creates a new check. */ /** This transaction type creates a new check. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Check/CreateCheck.h> # include <xrpl/tx/transactors/check/CreateCheck.h>
#endif #endif
TRANSACTION(ttCHECK_CREATE, 16, CheckCreate, TRANSACTION(ttCHECK_CREATE, 16, CheckCreate,
Delegation::delegable, Delegation::delegable,
@@ -238,7 +238,7 @@ TRANSACTION(ttCHECK_CREATE, 16, CheckCreate,
/** This transaction type cashes an existing check. */ /** This transaction type cashes an existing check. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Check/CashCheck.h> # include <xrpl/tx/transactors/check/CashCheck.h>
#endif #endif
TRANSACTION(ttCHECK_CASH, 17, CheckCash, TRANSACTION(ttCHECK_CASH, 17, CheckCash,
Delegation::delegable, Delegation::delegable,
@@ -252,7 +252,7 @@ TRANSACTION(ttCHECK_CASH, 17, CheckCash,
/** This transaction type cancels an existing check. */ /** This transaction type cancels an existing check. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Check/CancelCheck.h> # include <xrpl/tx/transactors/check/CancelCheck.h>
#endif #endif
TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel, TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel,
Delegation::delegable, Delegation::delegable,
@@ -264,7 +264,7 @@ TRANSACTION(ttCHECK_CANCEL, 18, CheckCancel,
/** This transaction type grants or revokes authorization to transfer funds. */ /** This transaction type grants or revokes authorization to transfer funds. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/DepositPreauth.h> # include <xrpl/tx/transactors/payment/DepositPreauth.h>
#endif #endif
TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth, TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth,
Delegation::delegable, Delegation::delegable,
@@ -279,7 +279,7 @@ TRANSACTION(ttDEPOSIT_PREAUTH, 19, DepositPreauth,
/** This transaction type modifies a trustline between two accounts. */ /** This transaction type modifies a trustline between two accounts. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/SetTrust.h> # include <xrpl/tx/transactors/token/SetTrust.h>
#endif #endif
TRANSACTION(ttTRUST_SET, 20, TrustSet, TRANSACTION(ttTRUST_SET, 20, TrustSet,
Delegation::delegable, Delegation::delegable,
@@ -293,7 +293,7 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet,
/** This transaction type deletes an existing account. */ /** This transaction type deletes an existing account. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/DeleteAccount.h> # include <xrpl/tx/transactors/account/DeleteAccount.h>
#endif #endif
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
Delegation::notDelegable, Delegation::notDelegable,
@@ -309,7 +309,7 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
/** This transaction mints a new NFT. */ /** This transaction mints a new NFT. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/NFT/NFTokenMint.h> # include <xrpl/tx/transactors/nft/NFTokenMint.h>
#endif #endif
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint, TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
Delegation::delegable, Delegation::delegable,
@@ -327,7 +327,7 @@ TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint,
/** This transaction burns (i.e. destroys) an existing NFT. */ /** This transaction burns (i.e. destroys) an existing NFT. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/NFT/NFTokenBurn.h> # include <xrpl/tx/transactors/nft/NFTokenBurn.h>
#endif #endif
TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn, TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn,
Delegation::delegable, Delegation::delegable,
@@ -340,7 +340,7 @@ TRANSACTION(ttNFTOKEN_BURN, 26, NFTokenBurn,
/** This transaction creates a new offer to buy or sell an NFT. */ /** This transaction creates a new offer to buy or sell an NFT. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/NFT/NFTokenCreateOffer.h> # include <xrpl/tx/transactors/nft/NFTokenCreateOffer.h>
#endif #endif
TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer, TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
Delegation::delegable, Delegation::delegable,
@@ -356,7 +356,7 @@ TRANSACTION(ttNFTOKEN_CREATE_OFFER, 27, NFTokenCreateOffer,
/** This transaction cancels an existing offer to buy or sell an existing NFT. */ /** This transaction cancels an existing offer to buy or sell an existing NFT. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/NFT/NFTokenCancelOffer.h> # include <xrpl/tx/transactors/nft/NFTokenCancelOffer.h>
#endif #endif
TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer, TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer,
Delegation::delegable, Delegation::delegable,
@@ -368,7 +368,7 @@ TRANSACTION(ttNFTOKEN_CANCEL_OFFER, 28, NFTokenCancelOffer,
/** This transaction accepts an existing offer to buy or sell an existing NFT. */ /** This transaction accepts an existing offer to buy or sell an existing NFT. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/NFT/NFTokenAcceptOffer.h> # include <xrpl/tx/transactors/nft/NFTokenAcceptOffer.h>
#endif #endif
TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer, TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer,
Delegation::delegable, Delegation::delegable,
@@ -382,7 +382,7 @@ TRANSACTION(ttNFTOKEN_ACCEPT_OFFER, 29, NFTokenAcceptOffer,
/** This transaction claws back issued tokens. */ /** This transaction claws back issued tokens. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Clawback.h> # include <xrpl/tx/transactors/token/Clawback.h>
#endif #endif
TRANSACTION(ttCLAWBACK, 30, Clawback, TRANSACTION(ttCLAWBACK, 30, Clawback,
Delegation::delegable, Delegation::delegable,
@@ -395,7 +395,7 @@ TRANSACTION(ttCLAWBACK, 30, Clawback,
/** This transaction claws back tokens from an AMM pool. */ /** This transaction claws back tokens from an AMM pool. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/AMM/AMMClawback.h> # include <xrpl/tx/transactors/dex/AMMClawback.h>
#endif #endif
TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback, TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
Delegation::delegable, Delegation::delegable,
@@ -410,7 +410,7 @@ TRANSACTION(ttAMM_CLAWBACK, 31, AMMClawback,
/** This transaction type creates an AMM instance */ /** This transaction type creates an AMM instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/AMM/AMMCreate.h> # include <xrpl/tx/transactors/dex/AMMCreate.h>
#endif #endif
TRANSACTION(ttAMM_CREATE, 35, AMMCreate, TRANSACTION(ttAMM_CREATE, 35, AMMCreate,
Delegation::delegable, Delegation::delegable,
@@ -424,7 +424,7 @@ TRANSACTION(ttAMM_CREATE, 35, AMMCreate,
/** This transaction type deposits into an AMM instance */ /** This transaction type deposits into an AMM instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/AMM/AMMDeposit.h> # include <xrpl/tx/transactors/dex/AMMDeposit.h>
#endif #endif
TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit, TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit,
Delegation::delegable, Delegation::delegable,
@@ -442,7 +442,7 @@ TRANSACTION(ttAMM_DEPOSIT, 36, AMMDeposit,
/** This transaction type withdraws from an AMM instance */ /** This transaction type withdraws from an AMM instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/AMM/AMMWithdraw.h> # include <xrpl/tx/transactors/dex/AMMWithdraw.h>
#endif #endif
TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw, TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw,
Delegation::delegable, Delegation::delegable,
@@ -459,7 +459,7 @@ TRANSACTION(ttAMM_WITHDRAW, 37, AMMWithdraw,
/** This transaction type votes for the trading fee */ /** This transaction type votes for the trading fee */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/AMM/AMMVote.h> # include <xrpl/tx/transactors/dex/AMMVote.h>
#endif #endif
TRANSACTION(ttAMM_VOTE, 38, AMMVote, TRANSACTION(ttAMM_VOTE, 38, AMMVote,
Delegation::delegable, Delegation::delegable,
@@ -473,7 +473,7 @@ TRANSACTION(ttAMM_VOTE, 38, AMMVote,
/** This transaction type bids for the auction slot */ /** This transaction type bids for the auction slot */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/AMM/AMMBid.h> # include <xrpl/tx/transactors/dex/AMMBid.h>
#endif #endif
TRANSACTION(ttAMM_BID, 39, AMMBid, TRANSACTION(ttAMM_BID, 39, AMMBid,
Delegation::delegable, Delegation::delegable,
@@ -489,7 +489,7 @@ TRANSACTION(ttAMM_BID, 39, AMMBid,
/** This transaction type deletes AMM in the empty state */ /** This transaction type deletes AMM in the empty state */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/AMM/AMMDelete.h> # include <xrpl/tx/transactors/dex/AMMDelete.h>
#endif #endif
TRANSACTION(ttAMM_DELETE, 40, AMMDelete, TRANSACTION(ttAMM_DELETE, 40, AMMDelete,
Delegation::delegable, Delegation::delegable,
@@ -502,7 +502,7 @@ TRANSACTION(ttAMM_DELETE, 40, AMMDelete,
/** This transactions creates a crosschain sequence number */ /** This transactions creates a crosschain sequence number */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/XChainBridge.h> # include <xrpl/tx/transactors/bridge/XChainBridge.h>
#endif #endif
TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID, TRANSACTION(ttXCHAIN_CREATE_CLAIM_ID, 41, XChainCreateClaimID,
Delegation::delegable, Delegation::delegable,
@@ -617,7 +617,7 @@ TRANSACTION(ttXCHAIN_CREATE_BRIDGE, 48, XChainCreateBridge,
/** This transaction type creates or updates a DID */ /** This transaction type creates or updates a DID */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/DID.h> # include <xrpl/tx/transactors/did/DID.h>
#endif #endif
TRANSACTION(ttDID_SET, 49, DIDSet, TRANSACTION(ttDID_SET, 49, DIDSet,
Delegation::delegable, Delegation::delegable,
@@ -638,7 +638,7 @@ TRANSACTION(ttDID_DELETE, 50, DIDDelete,
/** This transaction type creates an Oracle instance */ /** This transaction type creates an Oracle instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/SetOracle.h> # include <xrpl/tx/transactors/oracle/SetOracle.h>
#endif #endif
TRANSACTION(ttORACLE_SET, 51, OracleSet, TRANSACTION(ttORACLE_SET, 51, OracleSet,
Delegation::delegable, Delegation::delegable,
@@ -655,7 +655,7 @@ TRANSACTION(ttORACLE_SET, 51, OracleSet,
/** This transaction type deletes an Oracle instance */ /** This transaction type deletes an Oracle instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/DeleteOracle.h> # include <xrpl/tx/transactors/oracle/DeleteOracle.h>
#endif #endif
TRANSACTION(ttORACLE_DELETE, 52, OracleDelete, TRANSACTION(ttORACLE_DELETE, 52, OracleDelete,
Delegation::delegable, Delegation::delegable,
@@ -667,7 +667,7 @@ TRANSACTION(ttORACLE_DELETE, 52, OracleDelete,
/** This transaction type fixes a problem in the ledger state */ /** This transaction type fixes a problem in the ledger state */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/LedgerStateFix.h> # include <xrpl/tx/transactors/system/LedgerStateFix.h>
#endif #endif
TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix, TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix,
Delegation::delegable, Delegation::delegable,
@@ -680,7 +680,7 @@ TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix,
/** This transaction type creates a MPTokensIssuance instance */ /** This transaction type creates a MPTokensIssuance instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/MPT/MPTokenIssuanceCreate.h> # include <xrpl/tx/transactors/token/MPTokenIssuanceCreate.h>
#endif #endif
TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate, TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate,
Delegation::delegable, Delegation::delegable,
@@ -697,7 +697,7 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_CREATE, 54, MPTokenIssuanceCreate,
/** This transaction type destroys a MPTokensIssuance instance */ /** This transaction type destroys a MPTokensIssuance instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/MPT/MPTokenIssuanceDestroy.h> # include <xrpl/tx/transactors/token/MPTokenIssuanceDestroy.h>
#endif #endif
TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy, TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy,
Delegation::delegable, Delegation::delegable,
@@ -709,7 +709,7 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_DESTROY, 55, MPTokenIssuanceDestroy,
/** This transaction type sets flags on a MPTokensIssuance or MPToken instance */ /** This transaction type sets flags on a MPTokensIssuance or MPToken instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/MPT/MPTokenIssuanceSet.h> # include <xrpl/tx/transactors/token/MPTokenIssuanceSet.h>
#endif #endif
TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet, TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet,
Delegation::delegable, Delegation::delegable,
@@ -726,7 +726,7 @@ TRANSACTION(ttMPTOKEN_ISSUANCE_SET, 56, MPTokenIssuanceSet,
/** This transaction type authorizes a MPToken instance */ /** This transaction type authorizes a MPToken instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/MPT/MPTokenAuthorize.h> # include <xrpl/tx/transactors/token/MPTokenAuthorize.h>
#endif #endif
TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize, TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize,
Delegation::delegable, Delegation::delegable,
@@ -739,7 +739,7 @@ TRANSACTION(ttMPTOKEN_AUTHORIZE, 57, MPTokenAuthorize,
/** This transaction type create an Credential instance */ /** This transaction type create an Credential instance */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Credentials.h> # include <xrpl/tx/transactors/credentials/Credentials.h>
#endif #endif
TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate, TRANSACTION(ttCREDENTIAL_CREATE, 58, CredentialCreate,
Delegation::delegable, Delegation::delegable,
@@ -775,7 +775,7 @@ TRANSACTION(ttCREDENTIAL_DELETE, 60, CredentialDelete,
/** This transaction type modify a NFToken */ /** This transaction type modify a NFToken */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/NFT/NFTokenModify.h> # include <xrpl/tx/transactors/nft/NFTokenModify.h>
#endif #endif
TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify, TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify,
Delegation::delegable, Delegation::delegable,
@@ -789,7 +789,7 @@ TRANSACTION(ttNFTOKEN_MODIFY, 61, NFTokenModify,
/** This transaction type creates or modifies a Permissioned Domain */ /** This transaction type creates or modifies a Permissioned Domain */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/PermissionedDomain/PermissionedDomainSet.h> # include <xrpl/tx/transactors/permissioned_domain/PermissionedDomainSet.h>
#endif #endif
TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet, TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet,
Delegation::delegable, Delegation::delegable,
@@ -802,7 +802,7 @@ TRANSACTION(ttPERMISSIONED_DOMAIN_SET, 62, PermissionedDomainSet,
/** This transaction type deletes a Permissioned Domain */ /** This transaction type deletes a Permissioned Domain */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/PermissionedDomain/PermissionedDomainDelete.h> # include <xrpl/tx/transactors/permissioned_domain/PermissionedDomainDelete.h>
#endif #endif
TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete, TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete,
Delegation::delegable, Delegation::delegable,
@@ -814,7 +814,7 @@ TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete,
/** This transaction type delegates authorized account specified permissions */ /** This transaction type delegates authorized account specified permissions */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Delegate/DelegateSet.h> # include <xrpl/tx/transactors/delegate/DelegateSet.h>
#endif #endif
TRANSACTION(ttDELEGATE_SET, 64, DelegateSet, TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
Delegation::notDelegable, Delegation::notDelegable,
@@ -827,7 +827,7 @@ TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
/** This transaction creates a single asset vault. */ /** This transaction creates a single asset vault. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Vault/VaultCreate.h> # include <xrpl/tx/transactors/vault/VaultCreate.h>
#endif #endif
TRANSACTION(ttVAULT_CREATE, 65, VaultCreate, TRANSACTION(ttVAULT_CREATE, 65, VaultCreate,
Delegation::delegable, Delegation::delegable,
@@ -845,7 +845,7 @@ TRANSACTION(ttVAULT_CREATE, 65, VaultCreate,
/** This transaction updates a single asset vault. */ /** This transaction updates a single asset vault. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Vault/VaultSet.h> # include <xrpl/tx/transactors/vault/VaultSet.h>
#endif #endif
TRANSACTION(ttVAULT_SET, 66, VaultSet, TRANSACTION(ttVAULT_SET, 66, VaultSet,
Delegation::delegable, Delegation::delegable,
@@ -860,7 +860,7 @@ TRANSACTION(ttVAULT_SET, 66, VaultSet,
/** This transaction deletes a single asset vault. */ /** This transaction deletes a single asset vault. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Vault/VaultDelete.h> # include <xrpl/tx/transactors/vault/VaultDelete.h>
#endif #endif
TRANSACTION(ttVAULT_DELETE, 67, VaultDelete, TRANSACTION(ttVAULT_DELETE, 67, VaultDelete,
Delegation::delegable, Delegation::delegable,
@@ -872,7 +872,7 @@ TRANSACTION(ttVAULT_DELETE, 67, VaultDelete,
/** This transaction trades assets for shares with a vault. */ /** This transaction trades assets for shares with a vault. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Vault/VaultDeposit.h> # include <xrpl/tx/transactors/vault/VaultDeposit.h>
#endif #endif
TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit, TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit,
Delegation::delegable, Delegation::delegable,
@@ -885,7 +885,7 @@ TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit,
/** This transaction trades shares for assets with a vault. */ /** This transaction trades shares for assets with a vault. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Vault/VaultWithdraw.h> # include <xrpl/tx/transactors/vault/VaultWithdraw.h>
#endif #endif
TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw, TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
Delegation::delegable, Delegation::delegable,
@@ -900,7 +900,7 @@ TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
/** This transaction claws back tokens from a vault. */ /** This transaction claws back tokens from a vault. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Vault/VaultClawback.h> # include <xrpl/tx/transactors/vault/VaultClawback.h>
#endif #endif
TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback, TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback,
Delegation::delegable, Delegation::delegable,
@@ -914,7 +914,7 @@ TRANSACTION(ttVAULT_CLAWBACK, 70, VaultClawback,
/** This transaction type batches together transactions. */ /** This transaction type batches together transactions. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Batch.h> # include <xrpl/tx/transactors/system/Batch.h>
#endif #endif
TRANSACTION(ttBATCH, 71, Batch, TRANSACTION(ttBATCH, 71, Batch,
Delegation::notDelegable, Delegation::notDelegable,
@@ -929,7 +929,7 @@ TRANSACTION(ttBATCH, 71, Batch,
/** This transaction creates and updates a Loan Broker */ /** This transaction creates and updates a Loan Broker */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanBrokerSet.h> # include <xrpl/tx/transactors/lending/LoanBrokerSet.h>
#endif #endif
TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet, TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
Delegation::delegable, Delegation::delegable,
@@ -946,7 +946,7 @@ TRANSACTION(ttLOAN_BROKER_SET, 74, LoanBrokerSet,
/** This transaction deletes a Loan Broker */ /** This transaction deletes a Loan Broker */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanBrokerDelete.h> # include <xrpl/tx/transactors/lending/LoanBrokerDelete.h>
#endif #endif
TRANSACTION(ttLOAN_BROKER_DELETE, 75, LoanBrokerDelete, TRANSACTION(ttLOAN_BROKER_DELETE, 75, LoanBrokerDelete,
Delegation::delegable, Delegation::delegable,
@@ -957,7 +957,7 @@ TRANSACTION(ttLOAN_BROKER_DELETE, 75, LoanBrokerDelete,
/** This transaction deposits First Loss Capital into a Loan Broker */ /** This transaction deposits First Loss Capital into a Loan Broker */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanBrokerCoverDeposit.h> # include <xrpl/tx/transactors/lending/LoanBrokerCoverDeposit.h>
#endif #endif
TRANSACTION(ttLOAN_BROKER_COVER_DEPOSIT, 76, LoanBrokerCoverDeposit, TRANSACTION(ttLOAN_BROKER_COVER_DEPOSIT, 76, LoanBrokerCoverDeposit,
Delegation::delegable, Delegation::delegable,
@@ -969,7 +969,7 @@ TRANSACTION(ttLOAN_BROKER_COVER_DEPOSIT, 76, LoanBrokerCoverDeposit,
/** This transaction withdraws First Loss Capital from a Loan Broker */ /** This transaction withdraws First Loss Capital from a Loan Broker */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanBrokerCoverWithdraw.h> # include <xrpl/tx/transactors/lending/LoanBrokerCoverWithdraw.h>
#endif #endif
TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 77, LoanBrokerCoverWithdraw, TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 77, LoanBrokerCoverWithdraw,
Delegation::delegable, Delegation::delegable,
@@ -984,7 +984,7 @@ TRANSACTION(ttLOAN_BROKER_COVER_WITHDRAW, 77, LoanBrokerCoverWithdraw,
/** This transaction claws back First Loss Capital from a Loan Broker to /** This transaction claws back First Loss Capital from a Loan Broker to
the issuer of the capital */ the issuer of the capital */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanBrokerCoverClawback.h> # include <xrpl/tx/transactors/lending/LoanBrokerCoverClawback.h>
#endif #endif
TRANSACTION(ttLOAN_BROKER_COVER_CLAWBACK, 78, LoanBrokerCoverClawback, TRANSACTION(ttLOAN_BROKER_COVER_CLAWBACK, 78, LoanBrokerCoverClawback,
Delegation::delegable, Delegation::delegable,
@@ -996,7 +996,7 @@ TRANSACTION(ttLOAN_BROKER_COVER_CLAWBACK, 78, LoanBrokerCoverClawback,
/** This transaction creates a Loan */ /** This transaction creates a Loan */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanSet.h> # include <xrpl/tx/transactors/lending/LoanSet.h>
#endif #endif
TRANSACTION(ttLOAN_SET, 80, LoanSet, TRANSACTION(ttLOAN_SET, 80, LoanSet,
Delegation::delegable, Delegation::delegable,
@@ -1023,7 +1023,7 @@ TRANSACTION(ttLOAN_SET, 80, LoanSet,
/** This transaction deletes an existing Loan */ /** This transaction deletes an existing Loan */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanDelete.h> # include <xrpl/tx/transactors/lending/LoanDelete.h>
#endif #endif
TRANSACTION(ttLOAN_DELETE, 81, LoanDelete, TRANSACTION(ttLOAN_DELETE, 81, LoanDelete,
Delegation::delegable, Delegation::delegable,
@@ -1034,7 +1034,7 @@ TRANSACTION(ttLOAN_DELETE, 81, LoanDelete,
/** This transaction is used to change the delinquency status of an existing Loan */ /** This transaction is used to change the delinquency status of an existing Loan */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanManage.h> # include <xrpl/tx/transactors/lending/LoanManage.h>
#endif #endif
TRANSACTION(ttLOAN_MANAGE, 82, LoanManage, TRANSACTION(ttLOAN_MANAGE, 82, LoanManage,
Delegation::delegable, Delegation::delegable,
@@ -1048,7 +1048,7 @@ TRANSACTION(ttLOAN_MANAGE, 82, LoanManage,
/** The Borrower uses this transaction to make a Payment on the Loan. */ /** The Borrower uses this transaction to make a Payment on the Loan. */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Lending/LoanPay.h> # include <xrpl/tx/transactors/lending/LoanPay.h>
#endif #endif
TRANSACTION(ttLOAN_PAY, 84, LoanPay, TRANSACTION(ttLOAN_PAY, 84, LoanPay,
Delegation::delegable, Delegation::delegable,
@@ -1063,7 +1063,7 @@ TRANSACTION(ttLOAN_PAY, 84, LoanPay,
For details, see: https://xrpl.org/amendments.html For details, see: https://xrpl.org/amendments.html
*/ */
#if TRANSACTION_INCLUDE #if TRANSACTION_INCLUDE
# include <xrpl/tx/transactors/Change.h> # include <xrpl/tx/transactors/system/Change.h>
#endif #endif
TRANSACTION(ttAMENDMENT, 100, EnableAmendment, TRANSACTION(ttAMENDMENT, 100, EnableAmendment,
Delegation::notDelegable, Delegation::notDelegable,

View File

@@ -25,6 +25,7 @@ namespace jss {
JSS(AL_size); // out: GetCounts JSS(AL_size); // out: GetCounts
JSS(AL_hit_rate); // out: GetCounts JSS(AL_hit_rate); // out: GetCounts
JSS(AcceptedCredentials); // out: AccountObjects JSS(AcceptedCredentials); // out: AccountObjects
JSS(ACCOUNT_SET_FLAGS); // out: RPC server_definitions
JSS(Account); // in: TransactionSign; field. JSS(Account); // in: TransactionSign; field.
JSS(AMMID); // field JSS(AMMID); // field
JSS(Amount); // in: TransactionSign; field. JSS(Amount); // in: TransactionSign; field.
@@ -187,6 +188,7 @@ JSS(closed_ledger); // out: NetworkOPs
JSS(cluster); // out: PeerImp JSS(cluster); // out: PeerImp
JSS(code); // out: errors JSS(code); // out: errors
JSS(command); // in: RPCHandler JSS(command); // in: RPCHandler
JSS(common); // out: RPC server_definitions
JSS(complete); // out: NetworkOPs, InboundLedger JSS(complete); // out: NetworkOPs, InboundLedger
JSS(complete_ledgers); // out: NetworkOPs, PeerImp JSS(complete_ledgers); // out: NetworkOPs, PeerImp
JSS(consensus); // out: NetworkOPs, LedgerConsensus JSS(consensus); // out: NetworkOPs, LedgerConsensus
@@ -356,6 +358,8 @@ JSS(ledger_min); // in, out: AccountTx*
JSS(ledger_time); // out: NetworkOPs JSS(ledger_time); // out: NetworkOPs
JSS(LEDGER_ENTRY_TYPES); // out: RPC server_definitions JSS(LEDGER_ENTRY_TYPES); // out: RPC server_definitions
// matches definitions.json format // matches definitions.json format
JSS(LEDGER_ENTRY_FLAGS); // out: RPC server_definitions
JSS(LEDGER_ENTRY_FORMATS); // out: RPC server_definitions
JSS(levels); // LogLevels JSS(levels); // LogLevels
JSS(limit); // in/out: AccountTx*, AccountOffers, JSS(limit); // in/out: AccountTx*, AccountOffers,
// AccountLines, AccountObjects // AccountLines, AccountObjects
@@ -457,6 +461,7 @@ JSS(open); // out: handlers/Ledger
JSS(open_ledger_cost); // out: SubmitTransaction JSS(open_ledger_cost); // out: SubmitTransaction
JSS(open_ledger_fee); // out: TxQ JSS(open_ledger_fee); // out: TxQ
JSS(open_ledger_level); // out: TxQ JSS(open_ledger_level); // out: TxQ
JSS(optionality); // out: server_definitions
JSS(oracles); // in: get_aggregate_price JSS(oracles); // in: get_aggregate_price
JSS(oracle_document_id); // in: get_aggregate_price JSS(oracle_document_id); // in: get_aggregate_price
JSS(owner); // in: LedgerEntry, out: NetworkOPs JSS(owner); // in: LedgerEntry, out: NetworkOPs
@@ -616,6 +621,8 @@ JSS(TRANSACTION_RESULTS); // out: RPC server_definitions
// matches definitions.json format // matches definitions.json format
JSS(TRANSACTION_TYPES); // out: RPC server_definitions JSS(TRANSACTION_TYPES); // out: RPC server_definitions
// matches definitions.json format // matches definitions.json format
JSS(TRANSACTION_FLAGS); // out: RPC server_definitions
JSS(TRANSACTION_FORMATS); // out: RPC server_definitions
JSS(TYPES); // out: RPC server_definitions JSS(TYPES); // out: RPC server_definitions
// matches definitions.json format // matches definitions.json format
JSS(transfer_rate); // out: nft_info (clio) JSS(transfer_rate); // out: nft_info (clio)

View File

@@ -10,8 +10,8 @@
#include <xrpl/tx/paths/detail/FlatSets.h> #include <xrpl/tx/paths/detail/FlatSets.h>
#include <xrpl/tx/paths/detail/FlowDebugInfo.h> #include <xrpl/tx/paths/detail/FlowDebugInfo.h>
#include <xrpl/tx/paths/detail/Steps.h> #include <xrpl/tx/paths/detail/Steps.h>
#include <xrpl/tx/transactors/AMM/AMMContext.h> #include <xrpl/tx/transactors/dex/AMMContext.h>
#include <xrpl/tx/transactors/AMM/AMMHelpers.h> #include <xrpl/tx/transactors/dex/AMMHelpers.h>
#include <boost/container/flat_set.hpp> #include <boost/container/flat_set.hpp>

View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <xrpl/tx/Transactor.h> #include <xrpl/tx/Transactor.h>
#include <xrpl/tx/transactors/Lending/LendingHelpers.h> #include <xrpl/tx/transactors/lending/LendingHelpers.h>
namespace xrpl { namespace xrpl {

View File

@@ -26,9 +26,6 @@ public:
{ {
} }
static std::uint32_t
getFlagsMask(PreflightContext const& ctx);
static NotTEC static NotTEC
preflight(PreflightContext const& ctx); preflight(PreflightContext const& ctx);

View File

@@ -13,9 +13,6 @@ public:
{ {
} }
static std::uint32_t
getFlagsMask(PreflightContext const& ctx);
static NotTEC static NotTEC
preflight(PreflightContext const& ctx); preflight(PreflightContext const& ctx);

View File

@@ -2,7 +2,7 @@
#include <xrpl/protocol/nft.h> #include <xrpl/protocol/nft.h>
#include <xrpl/tx/Transactor.h> #include <xrpl/tx/Transactor.h>
#include <xrpl/tx/transactors/NFT/NFTokenUtils.h> #include <xrpl/tx/transactors/nft/NFTokenUtils.h>
namespace xrpl { namespace xrpl {

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