name: CI on: push: branches: [master, dev] pull_request: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: build: if: github.repository == 'FairRootGroup/FairMQ' name: ${{ matrix.env }}-gcc-${{ matrix.gcc }} runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: gcc: ['12', '13', '14', '15'] env: ['latest'] include: - gcc: '15' env: 'boost187' steps: - uses: actions/checkout@v6 with: submodules: true fetch-tags: true fetch-depth: 0 - name: Setup spack environment uses: ./.github/actions/setup-deps with: gcc: ${{ matrix.gcc }} env: ${{ matrix.env }} - name: ccache uses: hendrikmuhs/ccache-action@v1 with: key: ${{ github.job }}-${{ matrix.env }}-gcc${{ matrix.gcc }} max-size: 500M - name: Configure and Build uses: threeal/cmake-action@v2 with: generator: Ninja options: | CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_INSTALL_PREFIX=${{ github.workspace }}/install BUILD_TESTING=ON CMAKE_C_COMPILER_LAUNCHER=ccache CMAKE_CXX_COMPILER_LAUNCHER=ccache - name: Test run: | # Region/segment tests mlock() shared memory; raise the locked-memory # limit so it does not hit RLIMIT_MEMLOCK on the runner. sudo prlimit --pid $$ --memlock=unlimited:unlimited ulimit -l ctest --test-dir build --output-on-failure --no-tests=error - name: Install run: cmake --install build sanitizers: if: github.repository == 'FairRootGroup/FairMQ' name: ${{ matrix.sanitizer.name }} runs-on: ubuntu-24.04 env: TSAN_OPTIONS: suppressions=${{ github.workspace }}/test/thread_sanitizer_suppressions.txt strategy: fail-fast: false matrix: sanitizer: - name: asan+lsan+ubsan gcc: '14' env: latest options: | ENABLE_SANITIZER_ADDRESS=ON ENABLE_SANITIZER_LEAK=ON ENABLE_SANITIZER_UNDEFINED_BEHAVIOUR=ON cxx-flags: -O1 -fno-omit-frame-pointer - name: tsan gcc: '15' env: tsan options: ENABLE_SANITIZER_THREAD=ON cxx-flags: -fno-omit-frame-pointer steps: - uses: actions/checkout@v6 with: submodules: true fetch-tags: true fetch-depth: 0 - name: Setup spack environment uses: ./.github/actions/setup-deps with: gcc: ${{ matrix.sanitizer.gcc }} env: ${{ matrix.sanitizer.env }} - name: ccache uses: hendrikmuhs/ccache-action@v1 with: key: ${{ github.job }}-${{ matrix.sanitizer.name }} max-size: 500M - name: Locate instrumented libstdc++ if: matrix.sanitizer.name == 'tsan' shell: spack-bash {0} # The test processes must load the tsan-instrumented libstdc++ # instead of the compiler's own (same soname, LD_LIBRARY_PATH beats # the RUNPATH). Set per test via ctest, not at the job level: like # any shared library built with gcc -fsanitize=thread it has # unresolved __tsan_* symbols, so loading it into uninstrumented # tools (cmake, ctest, ninja) would break them. run: | prefix=$(spack -e fairmq location -i libstdcxx-tsan) echo "test_library_path=$prefix/lib" >> $GITHUB_ENV - name: Configure and Build uses: threeal/cmake-action@v2 with: generator: Ninja cxx-flags: ${{ matrix.sanitizer.cxx-flags }} options: | CMAKE_BUILD_TYPE=Debug BUILD_TESTING=ON CMAKE_C_COMPILER_LAUNCHER=ccache CMAKE_CXX_COMPILER_LAUNCHER=ccache FAIRMQ_TEST_LD_LIBRARY_PATH=${{ env.test_library_path }} ${{ matrix.sanitizer.options }} - name: Verify tsan instrumentation wiring if: matrix.sanitizer.name == 'tsan' shell: spack-bash {0} run: | set -x # the test environment must resolve libstdc++ to the instrumented copy LD_LIBRARY_PATH=$test_library_path ldd build/test/testsuite_Channel \ | grep 'libstdc++' | tee /dev/stderr | grep -q libstdcxx-tsan # libzmq must be instrumented nm -D --undefined-only "$(spack -e fairmq location -i libzmq)/lib/libzmq.so" \ | grep -q __tsan_ # the instrumented libstdc++ must match the compiler release exactly, # or binaries may reference GLIBCXX versions the runtime lacks # (--color=never: the CI config forces SPACK_COLOR=always, which # would wrap the version in ANSI escapes) test "$(spack --color=never -e fairmq find --format '{version}' libstdcxx-tsan)" \ = "$(g++ -dumpfullversion)" # the LD_LIBRARY_PATH prepend must reach the registered tests # (via a file: grep -q quits on first match, and SIGPIPE on the # large json output would fail the step under pipefail) ctest --test-dir build --show-only=json-v1 > ctest-show-only.json grep -q libstdcxx-tsan ctest-show-only.json - name: Test run: | # Region/segment tests mlock() shared memory; raise the locked-memory # limit so it does not hit RLIMIT_MEMLOCK on the runner. sudo prlimit --pid $$ --memlock=unlimited:unlimited ulimit -l ctest --test-dir build --output-on-failure --no-tests=error static-analysis: if: github.repository == 'FairRootGroup/FairMQ' name: static-analysis runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 with: submodules: true fetch-tags: true fetch-depth: 0 - name: Setup spack environment uses: ./.github/actions/setup-deps with: gcc: '14' - name: ccache uses: hendrikmuhs/ccache-action@v1 with: key: ${{ github.job }} max-size: 500M - name: Configure run: | cmake -S . -B build -G Ninja \ -DCMAKE_BUILD_TYPE=Debug \ -DBUILD_TESTING=ON \ -DRUN_STATIC_ANALYSIS=ON \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - name: Build run: | set -o pipefail cmake --build build 2>&1 | tee build.log - name: Check for warnings run: | test -f build.log || { echo "::error::build.log was not produced"; exit 1; } if grep -q "warning:" build.log; then echo "::error::Static analysis found warnings" grep "warning:" build.log exit 1 fi