feat: Implement clang build analyzer (#2072)

Fix: https://github.com/XRPLF/clio/issues/936
This commit is contained in:
Ayaz Salikhov
2025-05-02 12:49:51 +01:00
committed by GitHub
parent c774a40a59
commit f2384a47f1
9 changed files with 112 additions and 27 deletions

View File

@@ -34,6 +34,10 @@ inputs:
- "tsan" - "tsan"
- "asan" - "asan"
- "ubsan" - "ubsan"
time_trace:
description: Whether to enable compiler trace reports
required: true
default: "false"
runs: runs:
using: composite using: composite
@@ -49,6 +53,7 @@ runs:
CODE_COVERAGE: "${{ inputs.code_coverage == 'true' && 'True' || 'False' }}" CODE_COVERAGE: "${{ inputs.code_coverage == 'true' && 'True' || 'False' }}"
STATIC_OPTION: "${{ inputs.static == 'true' && 'True' || 'False' }}" STATIC_OPTION: "${{ inputs.static == 'true' && 'True' || 'False' }}"
INTEGRATION_TESTS_OPTION: "${{ inputs.build_integration_tests == 'true' && 'True' || 'False' }}" INTEGRATION_TESTS_OPTION: "${{ inputs.build_integration_tests == 'true' && 'True' || 'False' }}"
TIME_TRACE: "${{ inputs.time_trace == 'true' && 'True' || 'False' }}"
run: | run: |
cd build cd build
conan \ conan \
@@ -61,6 +66,7 @@ runs:
-o clio:integration_tests="${INTEGRATION_TESTS_OPTION}" \ -o clio:integration_tests="${INTEGRATION_TESTS_OPTION}" \
-o clio:lint=False \ -o clio:lint=False \
-o clio:coverage="${CODE_COVERAGE}" \ -o clio:coverage="${CODE_COVERAGE}" \
-o clio:time_trace="${TIME_TRACE}" \
--profile ${{ inputs.conan_profile }} --profile ${{ inputs.conan_profile }}
- name: Run cmake - name: Run cmake

View File

@@ -13,7 +13,17 @@ runs:
if: ${{ runner.os == 'macOS' }} if: ${{ runner.os == 'macOS' }}
shell: bash shell: bash
run: | run: |
brew install llvm@14 pkg-config ninja bison ccache jq gh conan@1 ca-certificates brew install \
bison \
ca-certificates \
ccache \
clang-build-analyzer \
conan@1 \
gh \
jq \
llvm@14 \
ninja \
pkg-config
echo "/opt/homebrew/opt/conan@1/bin" >> $GITHUB_PATH echo "/opt/homebrew/opt/conan@1/bin" >> $GITHUB_PATH
- name: Install CMake 3.31.6 on mac - name: Install CMake 3.31.6 on mac

View File

@@ -23,21 +23,13 @@ jobs:
conan_profile: [gcc, clang] conan_profile: [gcc, clang]
build_type: [Release, Debug] build_type: [Release, Debug]
container: ['{ "image": "ghcr.io/xrplf/clio-ci:latest" }'] container: ['{ "image": "ghcr.io/xrplf/clio-ci:latest" }']
code_coverage: [false]
static: [true] static: [true]
include: include:
- os: heavy
conan_profile: gcc
build_type: Debug
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
code_coverage: true
static: true
- os: macos15 - os: macos15
conan_profile: default_apple_clang conan_profile: default_apple_clang
build_type: Release build_type: Release
container: "" container: ""
code_coverage: false
static: false static: false
uses: ./.github/workflows/build_and_test.yml uses: ./.github/workflows/build_and_test.yml
@@ -46,12 +38,60 @@ jobs:
container: ${{ matrix.container }} container: ${{ matrix.container }}
conan_profile: ${{ matrix.conan_profile }} conan_profile: ${{ matrix.conan_profile }}
build_type: ${{ matrix.build_type }} build_type: ${{ matrix.build_type }}
code_coverage: ${{ matrix.code_coverage }}
static: ${{ matrix.static }} static: ${{ matrix.static }}
run_unit_tests: true run_unit_tests: true
run_integration_tests: false run_integration_tests: false
upload_clio_server: true upload_clio_server: true
code_coverage:
name: Run Code Coverage
uses: ./.github/workflows/build_impl.yml
with:
runs_on: heavy
container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
conan_profile: gcc
build_type: Debug
disable_cache: false
code_coverage: true
static: true
upload_clio_server: false
targets: all
sanitizer: "false"
analyze_build_time: false
analyze_build_time:
name: Analyze Build Time
strategy:
fail-fast: false
matrix:
include:
# TODO: Enable when we have at least ubuntu 22.04
# as ClangBuildAnalyzer requires relatively modern glibc
#
# - os: heavy
# conan_profile: clang
# container: '{ "image": "ghcr.io/xrplf/clio-ci:latest" }'
# static: true
- os: macos15
conan_profile: default_apple_clang
container: ""
static: false
uses: ./.github/workflows/build_impl.yml
with:
runs_on: ${{ matrix.os }}
container: ${{ matrix.container }}
conan_profile: ${{ matrix.conan_profile }}
build_type: Release
disable_cache: true
code_coverage: false
static: ${{ matrix.static }}
upload_clio_server: false
targets: all
sanitizer: "false"
analyze_build_time: true
check_config: check_config:
name: Check Config Description name: Check Config Description
needs: build-and-test needs: build-and-test

View File

@@ -29,12 +29,6 @@ on:
type: boolean type: boolean
default: false default: false
code_coverage:
description: Whether to enable code coverage
required: true
type: boolean
default: false
static: static:
description: Whether to build static binaries description: Whether to build static binaries
required: true required: true
@@ -78,16 +72,15 @@ jobs:
conan_profile: ${{ inputs.conan_profile }} conan_profile: ${{ inputs.conan_profile }}
build_type: ${{ inputs.build_type }} build_type: ${{ inputs.build_type }}
disable_cache: ${{ inputs.disable_cache }} disable_cache: ${{ inputs.disable_cache }}
code_coverage: ${{ inputs.code_coverage }} code_coverage: false
static: ${{ inputs.static }} static: ${{ inputs.static }}
upload_clio_server: ${{ inputs.upload_clio_server }} upload_clio_server: ${{ inputs.upload_clio_server }}
targets: ${{ inputs.targets }} targets: ${{ inputs.targets }}
sanitizer: ${{ inputs.sanitizer }} sanitizer: ${{ inputs.sanitizer }}
analyze_build_time: false
test: test:
needs: build needs: build
# We don't upload tests if code coverage is enabled
if: ${{ !inputs.code_coverage }}
uses: ./.github/workflows/test_impl.yml uses: ./.github/workflows/test_impl.yml
with: with:
runs_on: ${{ inputs.runs_on }} runs_on: ${{ inputs.runs_on }}

View File

@@ -45,14 +45,19 @@ on:
targets: targets:
description: Space-separated build target names description: Space-separated build target names
required: false required: true
type: string type: string
sanitizer: sanitizer:
description: Sanitizer to use description: Sanitizer to use
required: false required: true
type: string type: string
analyze_build_time:
description: Whether to enable build time analysis
required: true
type: boolean
jobs: jobs:
build: build:
name: Build ${{ inputs.container != '' && 'in container' || 'natively' }} name: Build ${{ inputs.container != '' && 'in container' || 'natively' }}
@@ -98,12 +103,29 @@ jobs:
code_coverage: ${{ inputs.code_coverage }} code_coverage: ${{ inputs.code_coverage }}
static: ${{ inputs.static }} static: ${{ inputs.static }}
sanitizer: ${{ inputs.sanitizer }} sanitizer: ${{ inputs.sanitizer }}
time_trace: ${{ inputs.analyze_build_time }}
- name: Build Clio - name: Build Clio
uses: ./.github/actions/build_clio uses: ./.github/actions/build_clio
with: with:
targets: ${{ inputs.targets }} targets: ${{ inputs.targets }}
- name: Show build time analyze report
if: ${{ inputs.analyze_build_time }}
run: |
ClangBuildAnalyzer --all build/ build_time_report.bin
ClangBuildAnalyzer --analyze build_time_report.bin > build_time_report.txt
# Running again to have colorized output
ClangBuildAnalyzer --analyze build_time_report.bin
shell: bash
- name: Upload build time analyze report
if: ${{ inputs.analyze_build_time }}
uses: actions/upload-artifact@v4
with:
name: build_time_report_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
path: build_time_report.txt
- name: Show ccache's statistics - name: Show ccache's statistics
if: ${{ !inputs.disable_cache }} if: ${{ !inputs.disable_cache }}
shell: bash shell: bash
@@ -115,29 +137,29 @@ jobs:
cat /tmp/ccache.stats cat /tmp/ccache.stats
- name: Strip unit_tests - name: Strip unit_tests
if: inputs.sanitizer == 'false' && !inputs.code_coverage if: inputs.sanitizer == 'false' && !inputs.code_coverage && !inputs.analyze_build_time
run: strip build/clio_tests run: strip build/clio_tests
- name: Strip integration_tests - name: Strip integration_tests
if: inputs.sanitizer == 'false' && !inputs.code_coverage if: inputs.sanitizer == 'false' && !inputs.code_coverage && !inputs.analyze_build_time
run: strip build/clio_integration_tests run: strip build/clio_integration_tests
- name: Upload clio_server - name: Upload clio_server
if: inputs.upload_clio_server && !inputs.code_coverage if: inputs.upload_clio_server && !inputs.code_coverage && !inputs.analyze_build_time
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: clio_server_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: clio_server_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
path: build/clio_server path: build/clio_server
- name: Upload clio_tests - name: Upload clio_tests
if: ${{ !inputs.code_coverage }} if: ${{ !inputs.code_coverage && !inputs.analyze_build_time }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: clio_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}
path: build/clio_tests path: build/clio_tests
- name: Upload clio_integration_tests - name: Upload clio_integration_tests
if: ${{ !inputs.code_coverage }} if: ${{ !inputs.code_coverage && !inputs.analyze_build_time }}
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }} name: clio_integration_tests_${{ runner.os }}_${{ inputs.build_type }}_${{ inputs.conan_profile }}

View File

@@ -35,7 +35,7 @@ on:
sanitizer: sanitizer:
description: Sanitizer to use description: Sanitizer to use
required: false required: true
type: string type: string
jobs: jobs:

View File

@@ -17,6 +17,7 @@ option(packaging "Create distribution packages" FALSE)
option(lint "Run clang-tidy checks during compilation" FALSE) option(lint "Run clang-tidy checks during compilation" FALSE)
option(static "Statically linked Clio" FALSE) option(static "Statically linked Clio" FALSE)
option(snapshot "Build snapshot tool" FALSE) option(snapshot "Build snapshot tool" FALSE)
option(time_trace "Build using -ftime-trace to create compiler trace reports" FALSE)
# ========================================================================== # # ========================================================================== #
set(san "" CACHE STRING "Add sanitizer instrumentation") set(san "" CACHE STRING "Add sanitizer instrumentation")

View File

@@ -70,4 +70,12 @@ endif ()
# See https://github.com/cpp-best-practices/cppbestpractices/blob/master/02-Use_the_Tools_Available.md#gcc--clang for # See https://github.com/cpp-best-practices/cppbestpractices/blob/master/02-Use_the_Tools_Available.md#gcc--clang for
# the flags description # the flags description
if (time_trace)
if (is_clang OR is_appleclang)
list(APPEND COMPILER_FLAGS -ftime-trace)
else ()
message(FATAL_ERROR "Clang or AppleClang is required to use `-ftime-trace`")
endif ()
endif ()
target_compile_options(clio_options INTERFACE ${COMPILER_FLAGS}) target_compile_options(clio_options INTERFACE ${COMPILER_FLAGS})

View File

@@ -1,6 +1,7 @@
from conan import ConanFile from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
class Clio(ConanFile): class Clio(ConanFile):
name = 'clio' name = 'clio'
license = 'ISC' license = 'ISC'
@@ -20,6 +21,7 @@ class Clio(ConanFile):
'coverage': [True, False], # build for test coverage report; create custom target `clio_tests-ccov` 'coverage': [True, False], # build for test coverage report; create custom target `clio_tests-ccov`
'lint': [True, False], # run clang-tidy checks during compilation 'lint': [True, False], # run clang-tidy checks during compilation
'snapshot': [True, False], # build export/import snapshot tool 'snapshot': [True, False], # build export/import snapshot tool
'time_trace': [True, False] # build using -ftime-trace to create compiler trace reports
} }
requires = [ requires = [
@@ -46,6 +48,7 @@ class Clio(ConanFile):
'lint': False, 'lint': False,
'docs': False, 'docs': False,
'snapshot': False, 'snapshot': False,
'time_trace': False,
'xrpl/*:tests': False, 'xrpl/*:tests': False,
'xrpl/*:rocksdb': False, 'xrpl/*:rocksdb': False,
@@ -83,6 +86,7 @@ class Clio(ConanFile):
self.folders.generators = 'build/generators' self.folders.generators = 'build/generators'
generators = 'CMakeDeps' generators = 'CMakeDeps'
def generate(self): def generate(self):
tc = CMakeToolchain(self) tc = CMakeToolchain(self)
tc.variables['verbose'] = self.options.verbose tc.variables['verbose'] = self.options.verbose
@@ -95,6 +99,7 @@ class Clio(ConanFile):
tc.variables['packaging'] = self.options.packaging tc.variables['packaging'] = self.options.packaging
tc.variables['benchmark'] = self.options.benchmark tc.variables['benchmark'] = self.options.benchmark
tc.variables['snapshot'] = self.options.snapshot tc.variables['snapshot'] = self.options.snapshot
tc.variables['time_trace'] = self.options.time_trace
tc.generate() tc.generate()
def build(self): def build(self):