diff --git a/.github/actions/build-deps/action.yml b/.github/actions/build-deps/action.yml index f20eb3a595..5bfa9a21bf 100644 --- a/.github/actions/build-deps/action.yml +++ b/.github/actions/build-deps/action.yml @@ -21,6 +21,11 @@ inputs: description: "The logging verbosity." required: false default: "verbose" + sanitizers: + description: "The sanitizers to enable ('None', 'Address', 'Thread')." + required: true + type: string + default: "None" runs: using: composite @@ -33,11 +38,13 @@ runs: BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }} BUILD_TYPE: ${{ inputs.build_type }} LOG_VERBOSITY: ${{ inputs.log_verbosity }} + CMAKE_SANITIZERS: ${{ inputs.sanitizers }} run: | echo 'Installing dependencies.' mkdir -p "${BUILD_DIR}" cd "${BUILD_DIR}" conan install \ + --profile ci \ --output-folder . \ --build="${BUILD_OPTION}" \ --options:host='&:tests=True' \ diff --git a/.github/actions/setup-conan/action.yml b/.github/actions/setup-conan/action.yml index 1184cfd3d9..dedf53f109 100644 --- a/.github/actions/setup-conan/action.yml +++ b/.github/actions/setup-conan/action.yml @@ -28,7 +28,7 @@ runs: shell: bash run: | echo 'Installing profile.' - conan config install conan/profiles/default -tf $(conan config home)/profiles/ + conan config install conan/profiles/ -tf $(conan config home)/profiles/ echo 'Conan profile:' conan profile show diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py index 025d553b5e..f51ff27be6 100755 --- a/.github/scripts/strategy-matrix/generate.py +++ b/.github/scripts/strategy-matrix/generate.py @@ -30,7 +30,7 @@ We will further set additional CMake arguments as follows: ''' def generate_strategy_matrix(all: bool, config: Config) -> list: configurations = [] - for architecture, os, build_type, cmake_args in itertools.product(config.architecture, config.os, config.build_type, config.cmake_args): + for architecture, os, build_type, cmake_args, sanitizers in itertools.product(config.architecture, config.os, config.build_type, config.cmake_args, config.sanitizers): # The default CMake target is 'all' for Linux and MacOS and 'install' # for Windows, but it can get overridden for certain configurations. cmake_target = 'install' if os["distro_name"] == 'windows' else 'all' @@ -125,6 +125,11 @@ def generate_strategy_matrix(all: bool, config: Config) -> list: if build_type == 'Release': cmake_args = f'{cmake_args} -Dassert=ON' + if sanitizers == 'Address': + cmake_args = f'{cmake_args} -fsanitize=address,undefined,float-divide-by-zero,unsigned-integer-overflow' + elif sanitizers == 'Thread': + cmake_args = f'{cmake_args} -fsanitize=thread,undefined,float-divide-by-zero,unsigned-integer-overflow' + # We skip all RHEL on arm64 due to a build failure that needs further # investigation. if os['distro_name'] == 'rhel' and architecture['platform'] == 'linux/arm64': @@ -166,6 +171,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list: 'build_type': build_type, 'os': os, 'architecture': architecture, + 'sanitizers': sanitizers }) return configurations diff --git a/.github/scripts/strategy-matrix/linux.json b/.github/scripts/strategy-matrix/linux.json index 85a78c96dc..d9e7d439f3 100644 --- a/.github/scripts/strategy-matrix/linux.json +++ b/.github/scripts/strategy-matrix/linux.json @@ -180,5 +180,6 @@ } ], "build_type": ["Debug", "Release"], - "cmake_args": ["-Dunity=OFF", "-Dunity=ON"] + "cmake_args": ["-Dunity=OFF", "-Dunity=ON"], + "sanitizers": ["None", "Address", "Thread"] } diff --git a/.github/scripts/strategy-matrix/macos.json b/.github/scripts/strategy-matrix/macos.json index 14b6089620..46ce66bd0e 100644 --- a/.github/scripts/strategy-matrix/macos.json +++ b/.github/scripts/strategy-matrix/macos.json @@ -18,5 +18,6 @@ "cmake_args": [ "-Dunity=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5", "-Dunity=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5" - ] + ], + "sanitizers": ["None", "Address", "Thread"] } diff --git a/.github/scripts/strategy-matrix/windows.json b/.github/scripts/strategy-matrix/windows.json index 8637b31012..7176f4fc35 100644 --- a/.github/scripts/strategy-matrix/windows.json +++ b/.github/scripts/strategy-matrix/windows.json @@ -15,5 +15,6 @@ } ], "build_type": ["Debug", "Release"], - "cmake_args": ["-Dunity=OFF", "-Dunity=ON"] + "cmake_args": ["-Dunity=OFF", "-Dunity=ON"], + "sanitizers": ["None", "Address", "Thread"] } diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index a59dbda71b..e2ba6f8641 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -24,6 +24,11 @@ on: description: "The CMake target to build." type: string required: true + sanitizers: + description: "The sanitizers to enable ('None', 'Address', 'Thread')." + required: true + type: string + default: "None" runs_on: description: Runner to run the job on as a JSON string @@ -61,6 +66,7 @@ jobs: runs_on: ${{ inputs.runs_on }} image: ${{ inputs.image }} config_name: ${{ inputs.config_name }} + sanitizers: ${{ inputs.sanitizers }} nproc_subtract: ${{ inputs.nproc_subtract }} secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/reusable-build-test.yml b/.github/workflows/reusable-build-test.yml index c6e991df79..5bd4cf2a60 100644 --- a/.github/workflows/reusable-build-test.yml +++ b/.github/workflows/reusable-build-test.yml @@ -23,6 +23,11 @@ on: required: false type: string default: "minimal" + sanitizers: + description: "The sanitizers to enable ('None', 'Address', 'Thread')." + required: true + type: string + default: "None" secrets: CODECOV_TOKEN: description: "The Codecov token to use for uploading coverage reports." @@ -54,5 +59,6 @@ jobs: runs_on: ${{ toJSON(matrix.architecture.runner) }} image: ${{ contains(matrix.architecture.platform, 'linux') && format('ghcr.io/xrplf/ci/{0}-{1}:{2}-{3}-sha-{4}', matrix.os.distro_name, matrix.os.distro_version, matrix.os.compiler_name, matrix.os.compiler_version, matrix.os.image_sha) || '' }} config_name: ${{ matrix.config_name }} + sanitizers: ${{ inputs.sanitizers }} secrets: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index a9d5fd7f7c..b3d3fd7f46 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -19,6 +19,11 @@ on: description: "The CMake target to build." required: true type: string + sanitizers: + description: "The sanitizers to enable ('None', 'Address', 'Thread')." + required: true + type: string + default: "None" runs_on: description: Runner to run the job on as a JSON string @@ -85,6 +90,7 @@ jobs: build_dir: ${{ inputs.build_dir }} build_nproc: ${{ steps.nproc.outputs.nproc }} build_type: ${{ inputs.build_type }} + sanitizers: ${{ inputs.sanitizers }} # Set the verbosity to "quiet" for Windows to avoid an excessive # amount of logs. For other OSes, the "verbose" logs are more useful. log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }} diff --git a/conan/profiles/ci b/conan/profiles/ci new file mode 100644 index 0000000000..a335f267de --- /dev/null +++ b/conan/profiles/ci @@ -0,0 +1,11 @@ +include(./default) + +[settings] +{% set sanitizers = os.getenv("CMAKE_SANITIZERS") %} + +[conf] +{% if sanitizers == "Address" %} +tools.build:cxxflags+=['-fsanitize=address,undefined,float-divide-by-zero,unsigned-integer-overflow'] +{% elif sanitizers == "Thread" %} +tools.build:cxxflags+=['-fsanitize=thread,undefined,float-divide-by-zero,unsigned-integer-overflow'] +{% endif %} \ No newline at end of file