mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-03 00:36:48 +00:00
Moved to entirely cmake workflow
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
This commit is contained in:
133
.github/scripts/strategy-matrix/generate.py
vendored
133
.github/scripts/strategy-matrix/generate.py
vendored
@@ -209,7 +209,6 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
):
|
||||
continue
|
||||
|
||||
cxx_flags = ""
|
||||
# Enable code coverage for Debian Bookworm using GCC 14 in Debug and no
|
||||
# Unity on linux/amd64
|
||||
if (
|
||||
@@ -218,8 +217,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
and "-Dunity=OFF" in cmake_args
|
||||
and architecture["platform"] == "linux/amd64"
|
||||
):
|
||||
cmake_args = f"-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 {cmake_args}"
|
||||
cxx_flags = f"-O0 {cxx_flags}"
|
||||
cmake_args = f"-Dcoverage=ON -Dcoverage_format=xml -DCODE_COVERAGE_VERBOSE=ON -DCMAKE_C_FLAGS=-O0 -DCMAKE_CXX_FLAGS=-O0 {cmake_args}"
|
||||
|
||||
# Generate a unique name for the configuration, e.g. macos-arm64-debug
|
||||
# or debian-bookworm-gcc-12-amd64-release-unity.
|
||||
@@ -247,25 +245,26 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
"gcc-15",
|
||||
"clang-20",
|
||||
}:
|
||||
configs = addSanitizerConfigs(architecture, os, cmake_args, cxx_flags)
|
||||
if "asan_ubsan" in configs:
|
||||
configurations.append(
|
||||
{
|
||||
"config_name": config_name + "-asan-ubsan",
|
||||
"cmake_args": configs["asan_ubsan"],
|
||||
"cmake_target": cmake_target,
|
||||
"build_only": build_only,
|
||||
"build_type": build_type,
|
||||
"os": os,
|
||||
"architecture": architecture,
|
||||
"sanitizers": "Address,UndefinedBehavior",
|
||||
}
|
||||
)
|
||||
if "tsan_ubsan" in configs:
|
||||
# Add ASAN + UBSAN configuration.
|
||||
configurations.append(
|
||||
{
|
||||
"config_name": config_name + "-asan-ubsan",
|
||||
"cmake_args": cmake_args,
|
||||
"cmake_target": cmake_target,
|
||||
"build_only": build_only,
|
||||
"build_type": build_type,
|
||||
"os": os,
|
||||
"architecture": architecture,
|
||||
"sanitizers": "Address,UndefinedBehavior",
|
||||
}
|
||||
)
|
||||
# TSAN is deactivated due to seg faults with latest compilers.
|
||||
activateTSAN = False
|
||||
if activateTSAN:
|
||||
configurations.append(
|
||||
{
|
||||
"config_name": config_name + "-tsan-ubsan",
|
||||
"cmake_args": configs["tsan_ubsan"],
|
||||
"cmake_args": cmake_args,
|
||||
"cmake_target": cmake_target,
|
||||
"build_only": build_only,
|
||||
"build_type": build_type,
|
||||
@@ -290,102 +289,6 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
|
||||
return configurations
|
||||
|
||||
|
||||
def addSanitizerConfigs(
|
||||
architecture: dict,
|
||||
os: dict,
|
||||
cmake_args: str,
|
||||
cxx_flags: str,
|
||||
) -> dict:
|
||||
extra_warning_flags = ""
|
||||
linker_relocation_flags = ""
|
||||
linker_flags = ""
|
||||
|
||||
cxx_flags += " -fno-omit-frame-pointer"
|
||||
|
||||
# Use large code model to avoid relocation errors with large binaries
|
||||
# Only for x86-64 (amd64) - ARM64 doesn't support -mcmodel=large
|
||||
if architecture["platform"] == "linux/amd64" and os["compiler_name"] == "gcc":
|
||||
# Add -mcmodel=large to both compiler AND linker flags
|
||||
# This is needed because sanitizers create very large binaries and
|
||||
# large model removes the 2GB limitation that medium model has
|
||||
cxx_flags += " -mcmodel=large"
|
||||
linker_relocation_flags += " -mcmodel=large"
|
||||
|
||||
# Create default sanitizer flags
|
||||
sanitizers_flags = "undefined,float-divide-by-zero"
|
||||
|
||||
# There are some differences between GCC and Clang support for sanitizers.
|
||||
# Hence we must use diff. falg combinations for each compiler.
|
||||
# These combination of flags were tested to work with GCC 15 and Clang 20.
|
||||
# If the versions are changed, the flags might need to be updated.
|
||||
|
||||
if os["compiler_name"] == "gcc":
|
||||
# Suppress false positive warnings in GCC with stringop-overflow
|
||||
extra_warning_flags += " -Wno-stringop-overflow"
|
||||
# Disable mold, gold and lld linkers.
|
||||
# Use default linker (bfd/ld) which is more lenient with mixed code models
|
||||
cmake_args += " -Duse_mold=OFF -Duse_gold=OFF -Duse_lld=OFF"
|
||||
# Add linker flags for Sanitizers
|
||||
linker_flags += f" -DCMAKE_EXE_LINKER_FLAGS='{linker_relocation_flags} -fsanitize=address,{sanitizers_flags}'"
|
||||
linker_flags += f" -DCMAKE_SHARED_LINKER_FLAGS='{linker_relocation_flags} -fsanitize=address,{sanitizers_flags}'"
|
||||
elif os["compiler_name"] == "clang":
|
||||
# Note: We use $GITHUB_WORKSPACE environment variable which will be expanded by the shell
|
||||
# before CMake processes it. This ensures the compiler receives an absolute path.
|
||||
# CMAKE_SOURCE_DIR won't work here because it's inside CMAKE_CXX_FLAGS string.
|
||||
# GCC doesn't support ignorelist.
|
||||
cxx_flags += " -fsanitize-ignorelist=${GITHUB_WORKSPACE}/sanitizers/suppressions/sanitizer-ignorelist.txt"
|
||||
sanitizers_flags = f"{sanitizers_flags},unsigned-integer-overflow"
|
||||
linker_flags += (
|
||||
f" -DCMAKE_EXE_LINKER_FLAGS='-fsanitize=address,{sanitizers_flags}'"
|
||||
)
|
||||
linker_flags += (
|
||||
f" -DCMAKE_SHARED_LINKER_FLAGS='-fsanitize=address,{sanitizers_flags}'"
|
||||
)
|
||||
|
||||
# Sanitizers recommend minimum of -O1 for reasonable performance
|
||||
cxx_flags += " -O1"
|
||||
|
||||
# First create config for asan
|
||||
cmake_args_flags = f'{cmake_args} -DCMAKE_CXX_FLAGS="-fsanitize=address,{sanitizers_flags} {cxx_flags} {extra_warning_flags}" {linker_flags}'
|
||||
|
||||
# Add config with asan+ubsan
|
||||
configs = {}
|
||||
configs["asan_ubsan"] = cmake_args_flags
|
||||
|
||||
# Since TSAN runs are crashing with seg faults(could be compatibility issues with latest compilers)
|
||||
# We deactivate it for now. But I would keep the code, since it took some effort to find the correct set of config needed to run this.
|
||||
# This will be useful when we decide to activate it again in future.
|
||||
activateTSAN = False
|
||||
if activateTSAN:
|
||||
linker_flags = ""
|
||||
# Update configs for tsan
|
||||
# gcc doesn't supports atomic_thread_fence with tsan. Suppress warnings.
|
||||
# Also tsan doesn't work well with mcmode=large and bfd linker
|
||||
if os["compiler_name"] == "gcc":
|
||||
extra_warning_flags += " -Wno-tsan"
|
||||
cxx_flags = cxx_flags.replace("-mcmodel=large", "-mcmodel=medium")
|
||||
linker_relocation_flags = linker_relocation_flags.replace(
|
||||
"-mcmodel=large", "-mcmodel=medium"
|
||||
)
|
||||
# Add linker flags for Sanitizers
|
||||
linker_flags += f" -DCMAKE_EXE_LINKER_FLAGS='{linker_relocation_flags} -fsanitize=thread,{sanitizers_flags}'"
|
||||
linker_flags += f" -DCMAKE_SHARED_LINKER_FLAGS='{linker_relocation_flags} -fsanitize=thread,{sanitizers_flags}'"
|
||||
elif os["compiler_name"] == "clang":
|
||||
linker_flags += (
|
||||
f" -DCMAKE_EXE_LINKER_FLAGS='-fsanitize=thread,{sanitizers_flags}'"
|
||||
)
|
||||
linker_flags += (
|
||||
f" -DCMAKE_SHARED_LINKER_FLAGS='-fsanitize=thread,{sanitizers_flags}'"
|
||||
)
|
||||
|
||||
cmake_args_flags = f"{cmake_args} -DCMAKE_CXX_FLAGS='-fsanitize=thread,{sanitizers_flags} {cxx_flags} {extra_warning_flags}' {linker_flags}"
|
||||
|
||||
# Add config with tsan+ubsan
|
||||
configs["tsan_ubsan"] = cmake_args_flags
|
||||
|
||||
return configs
|
||||
|
||||
|
||||
def read_config(file: Path) -> Config:
|
||||
config = json.loads(file.read_text())
|
||||
if (
|
||||
|
||||
@@ -51,7 +51,7 @@ on:
|
||||
default: 2
|
||||
|
||||
sanitizers:
|
||||
description: "The sanitizers to enable ('Address+UndefinedBehavior' or 'Thread+UndefinedBehavior')."
|
||||
description: "The sanitizers to enable ('Address,UndefinedBehavior' or 'Thread,UndefinedBehavior')."
|
||||
required: false
|
||||
type: string
|
||||
default: ""
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
env:
|
||||
ENABLED_VOIDSTAR: ${{ contains(inputs.cmake_args, '-Dvoidstar=ON') }}
|
||||
ENABLED_COVERAGE: ${{ contains(inputs.cmake_args, '-Dcoverage=ON') }}
|
||||
ENABLED_SANITIZERS: ${{ contains(inputs.cmake_args, '-fsanitize') }}
|
||||
ENABLED_SANITIZERS: ${{ inputs.sanitizers != '' }}
|
||||
steps:
|
||||
- name: Cleanup workspace (macOS and Windows)
|
||||
if: ${{ runner.os == 'macOS' || runner.os == 'Windows' }}
|
||||
@@ -115,6 +115,7 @@ jobs:
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
env:
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
SANITIZER: ${{ inputs.sanitizers }}
|
||||
run: |
|
||||
cmake \
|
||||
-G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
|
||||
|
||||
@@ -74,6 +74,7 @@ if (packages_only)
|
||||
return ()
|
||||
endif ()
|
||||
include(XrplCompiler)
|
||||
include(XrplSanitizers)
|
||||
include(XrplInterface)
|
||||
|
||||
option(only_docs "Include only the docs target?" FALSE)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# This file is included by Conan's toolchain file.
|
||||
# We set the required CMake variable as a CACHE variable to ensure
|
||||
# it takes effect during the configure step.
|
||||
|
||||
set(ABSL_ENABLE_CONSTANT_INIT_V2 "OFF" CACHE BOOL "Disable Abseil's V2 constant init logic to fix compiler errors.")
|
||||
158
cmake/XrplSanitizers.cmake
Normal file
158
cmake/XrplSanitizers.cmake
Normal file
@@ -0,0 +1,158 @@
|
||||
#[===================================================================[
|
||||
Configure sanitizers based on environment variables.
|
||||
|
||||
This module reads the following environment variables:
|
||||
- SANITIZER: The sanitizers to enable. Possible values:
|
||||
- "Address"
|
||||
- "Address,UndefinedBehavior"
|
||||
- "Thread"
|
||||
- "Thread,UndefinedBehavior"
|
||||
|
||||
The compiler type and platform are detected automatically by CMake.
|
||||
The sanitizer compile options are applied to the 'common' interface library
|
||||
which is linked to all targets in the project.
|
||||
#]===================================================================]
|
||||
|
||||
# Read environment variable
|
||||
set(SANITIZER $ENV{SANITIZER})
|
||||
|
||||
if(SANITIZER)
|
||||
message(STATUS "Configuring sanitizers: ${SANITIZER}")
|
||||
|
||||
# Parse SANITIZER value to determine which sanitizers to enable
|
||||
set(ENABLE_ASAN FALSE)
|
||||
set(ENABLE_TSAN FALSE)
|
||||
set(ENABLE_UBSAN FALSE)
|
||||
|
||||
if(SANITIZER MATCHES "Address")
|
||||
set(ENABLE_ASAN TRUE)
|
||||
endif()
|
||||
if(SANITIZER MATCHES "Thread")
|
||||
set(ENABLE_TSAN TRUE)
|
||||
endif()
|
||||
if(SANITIZER MATCHES "UndefinedBehavior")
|
||||
set(ENABLE_UBSAN TRUE)
|
||||
endif()
|
||||
|
||||
# Detect compiler type
|
||||
set(IS_GCC FALSE)
|
||||
set(IS_CLANG FALSE)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
set(IS_GCC TRUE)
|
||||
message(STATUS " Compiler: GCC ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
set(IS_CLANG TRUE)
|
||||
message(STATUS " Compiler: Clang ${CMAKE_CXX_COMPILER_VERSION}")
|
||||
endif()
|
||||
|
||||
# Detect platform (amd64/x86_64 vs arm64/aarch64)
|
||||
set(IS_AMD64 FALSE)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
|
||||
set(IS_AMD64 TRUE)
|
||||
message(STATUS " Platform: amd64")
|
||||
else()
|
||||
message(STATUS " Platform: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
# Frame pointer is required for meaningful stack traces
|
||||
set(SANITIZER_COMPILE_FLAGS "-fno-omit-frame-pointer")
|
||||
|
||||
# Sanitizers recommend minimum of -O1 for reasonable performance
|
||||
set(SANITIZER_COMPILE_FLAGS "${SANITIZER_COMPILE_FLAGS} -O1")
|
||||
|
||||
# Build the sanitizer flags string
|
||||
set(SANITIZER_FLAGS "")
|
||||
|
||||
if(ENABLE_ASAN)
|
||||
set(SANITIZER_FLAGS "address")
|
||||
elseif(ENABLE_TSAN)
|
||||
set(SANITIZER_FLAGS "thread")
|
||||
endif()
|
||||
|
||||
if(ENABLE_UBSAN)
|
||||
# UB sanitizer flags
|
||||
if(IS_CLANG)
|
||||
# Clang supports additional UB checks
|
||||
set(UBSAN_FLAGS "undefined,float-divide-by-zero,unsigned-integer-overflow")
|
||||
else()
|
||||
set(UBSAN_FLAGS "undefined,float-divide-by-zero")
|
||||
endif()
|
||||
|
||||
if(SANITIZER_FLAGS)
|
||||
set(SANITIZER_FLAGS "${SANITIZER_FLAGS},${UBSAN_FLAGS}")
|
||||
else()
|
||||
set(SANITIZER_FLAGS "${UBSAN_FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# 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)
|
||||
set(SANITIZER_RELOCATION_FLAGS "")
|
||||
if(IS_GCC AND IS_AMD64)
|
||||
if(ENABLE_ASAN)
|
||||
message(STATUS " Using large code model (-mcmodel=large)")
|
||||
set(SANITIZER_COMPILE_FLAGS "${SANITIZER_COMPILE_FLAGS} -mcmodel=large")
|
||||
set(SANITIZER_RELOCATION_FLAGS "-mcmodel=large")
|
||||
elseif(ENABLE_TSAN)
|
||||
message(STATUS " Using medium code model (-mcmodel=medium)")
|
||||
set(SANITIZER_COMPILE_FLAGS "${SANITIZER_COMPILE_FLAGS} -mcmodel=medium")
|
||||
set(SANITIZER_RELOCATION_FLAGS "-mcmodel=medium")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Compiler-specific configuration
|
||||
if(IS_GCC)
|
||||
# Disable mold, gold and lld linkers for GCC with sanitizers
|
||||
# Use default linker (bfd/ld) which is more lenient with mixed code models
|
||||
set(use_mold OFF CACHE BOOL "Use mold linker" FORCE)
|
||||
set(use_gold OFF CACHE BOOL "Use gold linker" FORCE)
|
||||
set(use_lld OFF CACHE BOOL "Use lld linker" FORCE)
|
||||
message(STATUS " Disabled mold, gold, and lld linkers for GCC with sanitizers")
|
||||
|
||||
# Suppress false positive warnings in GCC with stringop-overflow
|
||||
set(SANITIZER_COMPILE_FLAGS "${SANITIZER_COMPILE_FLAGS} -Wno-stringop-overflow")
|
||||
|
||||
if(ENABLE_TSAN)
|
||||
# GCC doesn't support atomic_thread_fence with tsan. Suppress warnings.
|
||||
set(SANITIZER_COMPILE_FLAGS "${SANITIZER_COMPILE_FLAGS} -Wno-tsan")
|
||||
endif()
|
||||
|
||||
# Add sanitizer to compile and link flags
|
||||
set(SANITIZER_COMPILE_FLAGS "${SANITIZER_COMPILE_FLAGS} -fsanitize=${SANITIZER_FLAGS}")
|
||||
set(SANITIZER_LINK_FLAGS "${SANITIZER_RELOCATION_FLAGS} -fsanitize=${SANITIZER_FLAGS}")
|
||||
|
||||
elseif(IS_CLANG)
|
||||
# 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")
|
||||
if(EXISTS "${IGNORELIST_PATH}")
|
||||
set(SANITIZER_COMPILE_FLAGS "${SANITIZER_COMPILE_FLAGS} -fsanitize-ignorelist=${IGNORELIST_PATH}")
|
||||
message(STATUS " Using sanitizer ignorelist: ${IGNORELIST_PATH}")
|
||||
else()
|
||||
message(WARNING "Sanitizer ignorelist not found: ${IGNORELIST_PATH}")
|
||||
endif()
|
||||
|
||||
# Add sanitizer to compile and link flags
|
||||
set(SANITIZER_COMPILE_FLAGS "${SANITIZER_COMPILE_FLAGS} -fsanitize=${SANITIZER_FLAGS}")
|
||||
set(SANITIZER_LINK_FLAGS "-fsanitize=${SANITIZER_FLAGS}")
|
||||
endif()
|
||||
|
||||
message(STATUS " Compile flags: ${SANITIZER_COMPILE_FLAGS}")
|
||||
message(STATUS " Link flags: ${SANITIZER_LINK_FLAGS}")
|
||||
|
||||
# Convert space-separated strings to lists for CMake
|
||||
separate_arguments(SANITIZER_COMPILE_FLAGS_LIST NATIVE_COMMAND "${SANITIZER_COMPILE_FLAGS}")
|
||||
separate_arguments(SANITIZER_LINK_FLAGS_LIST NATIVE_COMMAND "${SANITIZER_LINK_FLAGS}")
|
||||
|
||||
# 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>:${SANITIZER_COMPILE_FLAGS_LIST}>
|
||||
$<$<COMPILE_LANGUAGE:C>:${SANITIZER_COMPILE_FLAGS_LIST}>
|
||||
)
|
||||
|
||||
# Apply linker flags
|
||||
target_link_options(common INTERFACE ${SANITIZER_LINK_FLAGS_LIST})
|
||||
|
||||
endif()
|
||||
@@ -92,33 +92,6 @@ option(local_protobuf
|
||||
option(local_grpc
|
||||
"Force a local build of gRPC instead of looking for an installed version." OFF)
|
||||
|
||||
# this one is a string and therefore can't be an option
|
||||
set(san "" CACHE STRING "On gcc & clang, add sanitizer instrumentation")
|
||||
set_property(CACHE san PROPERTY STRINGS ";undefined;memory;address;thread")
|
||||
if(san)
|
||||
string(TOLOWER ${san} san)
|
||||
set(SAN_FLAG "-fsanitize=${san}")
|
||||
set(SAN_LIB "")
|
||||
if(is_gcc)
|
||||
if(san STREQUAL "address")
|
||||
set(SAN_LIB "asan")
|
||||
elseif(san STREQUAL "thread")
|
||||
set(SAN_LIB "tsan")
|
||||
elseif(san STREQUAL "memory")
|
||||
set(SAN_LIB "msan")
|
||||
elseif(san STREQUAL "undefined")
|
||||
set(SAN_LIB "ubsan")
|
||||
endif()
|
||||
endif()
|
||||
set(_saved_CRL ${CMAKE_REQUIRED_LIBRARIES})
|
||||
set(CMAKE_REQUIRED_LIBRARIES "${SAN_FLAG};${SAN_LIB}")
|
||||
check_cxx_compiler_flag(${SAN_FLAG} COMPILER_SUPPORTS_SAN)
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${_saved_CRL})
|
||||
if(NOT COMPILER_SUPPORTS_SAN)
|
||||
message(FATAL_ERROR "${san} sanitizer does not seem to be supported by your compiler")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# the remaining options are obscure and rarely used
|
||||
option(beast_no_unit_test_inline
|
||||
"Prevents unit test definitions from being inserted into global table"
|
||||
|
||||
Reference in New Issue
Block a user