diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 00000000..1e1121e1 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,42 @@ +name: Coverage + +on: [pull_request, push] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + coverage: + name: "Coverage" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # TODO: Remove this once clang 15 is default; clang 14 had a stdlib bug + - name: Install clang 15 + run: | + sudo apt-get update -q + sudo apt-get install llvm-15-dev libc++-15-dev + sudo update-alternatives --install \ + /usr/bin/clang clang /usr/bin/clang-15 200 + sudo update-alternatives --install \ + /usr/bin/clang++ clang++ /usr/bin/clang++-15 200 + sudo update-alternatives --install \ + /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-15 200 + sudo update-alternatives --install \ + /usr/bin/llvm-profdata llvm-profdata /usr/bin/llvm-profdata-15 200 + + - run: ./tools/coverage-generate.sh SleipnirTest + + - uses: actions/upload-artifact@v4 + with: + name: Coverage report + path: ./build-coverage/coverage-line-by-line-SleipnirTest.html + + - name: Write to job summary + run: | + echo '```bash' >> $GITHUB_STEP_SUMMARY + cat ./build-coverage/coverage-report-SleipnirTest.txt >> $GITHUB_STEP_SUMMARY + echo '' >> $GITHUB_STEP_SUMMARY + echo '```' >> $GITHUB_STEP_SUMMARY diff --git a/cmake/modules/SleipnirBuildTypes.cmake b/cmake/modules/SleipnirBuildTypes.cmake index 4fca9bf4..5d119d42 100644 --- a/cmake/modules/SleipnirBuildTypes.cmake +++ b/cmake/modules/SleipnirBuildTypes.cmake @@ -99,5 +99,14 @@ if(NOT MSVC) "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}" ) + sleipnir_add_build_type( + allowedBuildTypes + "Coverage" + "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fprofile-instr-generate -fcoverage-mapping" + "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fprofile-instr-generate -fcoverage-mapping" + "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}" + "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}" + ) + sleipnir_check_build_type(allowedBuildTypes) endif() diff --git a/tools/coverage-generate.sh b/tools/coverage-generate.sh new file mode 100755 index 00000000..cf7e7638 --- /dev/null +++ b/tools/coverage-generate.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -e + +if [ $# -eq 0 ]; then + echo -e "Usage: coverage-generate.sh CMAKE_TARGET\nGenerates coverage of CMake target executable with llvm-cov." + exit 1 +fi + +# Build executable +cmake -B build-coverage -S . -DCMAKE_BUILD_TYPE=Coverage -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ +cmake --build build-coverage --target $1 + +# Run executable and generate reports +pushd build-coverage +./$1 +llvm-profdata merge -sparse default.profraw -o default.profdata +llvm-cov show -ignore-filename-regex=_deps/ ./$1 -instr-profile=default.profdata -format=html > coverage-line-by-line-$1.html +llvm-cov report -ignore-filename-regex=_deps/ ./$1 -instr-profile=default.profdata > coverage-report-$1.txt +popd