Feature: stacktrace support #750
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: build & test | |
on: | |
push: | |
branches: [ main, development ] | |
pull_request: | |
branches: [ main, development ] | |
jobs: | |
############ | |
# | |
# Defines the compiler configurations for the other jobs. | |
# | |
##### | |
generate-base-matrix: | |
runs-on: ubuntu-latest | |
outputs: | |
architectures: ${{ steps.output-options.outputs.architectures }} | |
build_modes: ${{ steps.output-options.outputs.build_modes }} | |
cxx_versions: ${{ steps.output-options.outputs.cxx_versions }} | |
steps: | |
# enables debug-mode, c++20 and 64bit for all cases | |
- name: Enable base matrix | |
shell: bash | |
run: | | |
echo "ARCHITECTURES=\"64bit\"" >> $GITHUB_ENV | |
echo "BUILD_MODES=\"Debug\"" >> $GITHUB_ENV | |
echo "CXX_VERSIONS=20, 23" >> $GITHUB_ENV | |
# if it's a PR from development or the main branch in general, add release-mode, c++23 and 32bit | |
- name: Enable extended matrix | |
if: ${{ | |
(github.event_name == 'pull_request' && github.head_ref == 'development') | |
|| github.ref_name == 'main' | |
}} | |
shell: bash | |
run: | | |
echo "ARCHITECTURES=$(echo ${ARCHITECTURES}, \"32bit\")" >> $GITHUB_ENV | |
echo "BUILD_MODES=$(echo ${BUILD_MODES}, \"Release\")" >> $GITHUB_ENV | |
echo "CXX_VERSIONS=$(echo ${CXX_VERSIONS}, 23)" >> $GITHUB_ENV | |
- name: Output architectures, build-modes and c++-versions | |
id: output-options | |
shell: bash | |
run: | | |
echo "architectures=$(echo [ ${ARCHITECTURES} ])" >> "$GITHUB_OUTPUT" | |
echo "build_modes=$(echo [ ${BUILD_MODES} ])" >> "$GITHUB_OUTPUT" | |
echo "cxx_versions=$(echo [ ${CXX_VERSIONS} ])" >> "$GITHUB_OUTPUT" | |
build-and-test: | |
needs: generate-base-matrix | |
runs-on: ${{ matrix.config.os }} | |
container: ${{ matrix.config.container.image }} | |
name: | | |
${{ matrix.config.prefix }} | |
${{ matrix.config.compiler_name }}-${{ matrix.config.compiler_version }} | |
${{ matrix.config.suffix }} | |
(C++${{ matrix.cxx_standard }}, ${{ matrix.build_mode }}, ${{ matrix.architecture }}) | |
strategy: | |
fail-fast: false | |
matrix: | |
architecture: ${{ fromJSON(needs.generate-base-matrix.outputs.architectures) }} | |
build_mode: ${{ fromJSON(needs.generate-base-matrix.outputs.build_modes) }} | |
cxx_standard: ${{ fromJSON(needs.generate-base-matrix.outputs.cxx_versions) }} | |
config: | |
# clang | |
- prefix: "Linux" | |
suffix: "/libc++" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/clang:19" | |
compiler_name: "clang" | |
compiler_version: "19" | |
libcxx: true | |
asan: true | |
- prefix: "Linux" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/clang:19" | |
compiler_name: "clang" | |
compiler_version: "19" | |
libcxx: false | |
asan: true | |
- prefix: "Linux" | |
suffix: "/libc++" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/clang:18" | |
compiler_name: "clang" | |
compiler_version: "18" | |
libcxx: true | |
asan: true | |
- prefix: "Linux" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/clang:18" | |
compiler_name: "clang" | |
compiler_version: "18" | |
libcxx: false | |
asan: true | |
- prefix: "Linux" | |
suffix: "/libc++" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/clang:17" | |
compiler_name: "clang" | |
compiler_version: "17" | |
libcxx: true | |
asan: true | |
- prefix: "Linux" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/clang:17" | |
compiler_name: "clang" | |
compiler_version: "17" | |
libcxx: false | |
asan: true | |
- prefix: "Linux" | |
suffix: "/libc++" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/clang:16" | |
compiler_name: "clang" | |
compiler_version: "16" | |
only_fmt: true | |
libcxx: true | |
asan: true | |
- prefix: "Linux" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/clang:16" | |
compiler_name: "clang" | |
compiler_version: "16" | |
only_fmt: true | |
libcxx: false | |
asan: true | |
# gcc | |
- prefix: "Linux" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/gcc:14" | |
compiler_name: "gcc" | |
compiler_version: "14" | |
libcxx: false | |
asan: true | |
- prefix: "Linux" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/gcc:13" | |
compiler_name: "gcc" | |
compiler_version: "13" | |
libcxx: false | |
asan: true | |
- prefix: "Linux" | |
os: "ubuntu-latest" | |
container: | |
image: "ghcr.io/dnkpp/gcc:12" | |
compiler_name: "gcc" | |
compiler_version: "12" | |
only_fmt: true | |
libcxx: false | |
asan: true | |
# msvc | |
- prefix: "Windows 2022" | |
os: "windows-2022" | |
compiler_name: "msvc" | |
compiler_version: "v143" | |
cmake_generator: "Visual Studio 17 2022" | |
- prefix: "Windows 2022" | |
suffix: "/Gv" | |
os: "windows-2022" | |
compiler_name: "msvc" | |
compiler_version: "v143" | |
cmake_generator: "Visual Studio 17 2022" | |
default_call_convention: "vectorcall" | |
- prefix: "Windows 2022" | |
os: "windows-2022" | |
compiler_name: "msvc" | |
compiler_version: "ClangCl" | |
cmake_generator: "Visual Studio 17 2022" | |
# macOs | |
- prefix: "macOS" | |
os: "macos-latest" | |
compiler_name: "AppleClang" | |
compiler_version: "18" | |
ldflags_workaround: "-L/opt/homebrew/opt/llvm/lib/c++ -L/opt/homebrew/opt/llvm/lib/unwind -lunwind" | |
asan: true | |
- prefix: "macOS" | |
os: "macos-latest" | |
compiler_name: "AppleClang" | |
compiler_version: "17" | |
ldflags_workaround: "-L/opt/homebrew/opt/llvm@17/lib/c++ -Wl,-rpath,/opt/homebrew/opt/llvm@17/lib/c++" | |
asan: true | |
- prefix: "macOS" | |
os: "macos-latest" | |
compiler_name: "AppleClang" | |
compiler_version: "16" | |
only_fmt: true | |
ldflags_workaround: "-L/opt/homebrew/opt/llvm@16/lib/c++ -Wl,-rpath,/opt/homebrew/opt/llvm@16/lib/c++" | |
asan: true | |
exclude: | |
# This combination results in a compile error in ranges header. | |
- cxx_standard: 23 | |
config: | |
compiler_name: "clang" | |
compiler_version: "16" | |
libcxx: false | |
# seems like macOS doesn't support 32bit builds | |
- architecture: "32bit" | |
config: | |
prefix: "macOS" | |
steps: | |
- name: Checkout code | |
uses: actions/checkout@v4 | |
- name: Setup base cmake options | |
shell: bash | |
# sets up common options, used by all cmake configure steps. | |
# explicitly disable all optional features here | |
run: | | |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} \ | |
--log-level=DEBUG \ | |
-D CMAKE_VERBOSE_MAKEFILE=YES \ | |
-D MIMICPP_FORCED_CXX_STANDARD="${{ matrix.cxx_standard }}" \ | |
-D MIMICPP_ENABLE_ADAPTER_TESTS=OFF \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_CATCH2_MATCHER_INTEGRATION=OFF \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_UNICODE_STR_MATCHER=OFF \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_STACKTRACE=OFF \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_USE_CPPTRACE=OFF \ | |
)" >> $GITHUB_ENV | |
- name: Setup macOS | |
if: startsWith(matrix.config.os, 'macOS') | |
shell: bash | |
run: | | |
env brew install ninja llvm | |
LLVM_NAME=llvm@${{ matrix.config.compiler_version }} | |
env brew install $LLVM_NAME | |
LLVM_PATH="$(brew --prefix $LLVM_NAME)" | |
echo "CC=$(echo $LLVM_PATH/bin/clang)" >> $GITHUB_ENV | |
echo "CXX=$(echo $LLVM_PATH/bin/clang++)" >> $GITHUB_ENV | |
# solves this issue: https://github.com/Homebrew/homebrew-core/issues/178435 | |
echo "LDFLAGS=$(echo $LDFLAGS ${{ matrix.config.ldflags_workaround }})" >> $GITHUB_ENV | |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} -DCMAKE_BUILD_TYPE=${{ matrix.build_mode }})" >> $GITHUB_ENV | |
- name: Setup linux | |
if: ${{ matrix.config.prefix == 'Linux' }} | |
shell: bash | |
run: | | |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} -DCMAKE_BUILD_TYPE=${{ matrix.build_mode }})" >> $GITHUB_ENV | |
- name: Setup msvc | |
if: ${{ matrix.config.compiler_name == 'msvc' }} | |
shell: bash | |
run: | | |
# translate architecture to appropriate platform config | |
if [[ "${{ matrix.architecture }}" == "64bit" ]]; then | |
PLATFORM="x64" | |
elif [[ "${{ matrix.architecture }}" == "32bit" ]]; then | |
PLATFORM="Win32" | |
fi | |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} \ | |
-G\"${{ matrix.config.cmake_generator }}\" \ | |
-T\"${{ matrix.config.compiler_version }}\" \ | |
-A\"${PLATFORM}\" \ | |
)" >> $GITHUB_ENV | |
echo "CMAKE_BUILD_EXTRA=$(echo ${CMAKE_BUILD_EXTRA} --config ${{ matrix.build_mode }})" >> $GITHUB_ENV | |
- name: Clang libc++ setup | |
if: ${{ matrix.config.compiler_name == 'clang' && matrix.config.libcxx == true }} | |
shell: bash | |
run: | | |
echo "CXXFLAGS=$(echo ${CXXFLAGS} -stdlib=libc++)" >> $GITHUB_ENV | |
echo "LDFLAGS=$(echo ${LDFLAGS} -lc++abi)" >> $GITHUB_ENV | |
- name: Setup 32bit on Linux | |
if: ${{ matrix.architecture == '32bit' && matrix.config.prefix == 'Linux' }} | |
shell: bash | |
run: | | |
echo "CXXFLAGS=$(echo ${CXXFLAGS} -m32)" >> $GITHUB_ENV | |
echo "CFLAGS=$(echo ${CFLAGS} -m32)" >> $GITHUB_ENV | |
echo "LDFLAGS=$(echo ${LDFLAGS} -m32)" >> $GITHUB_ENV | |
- name: Setup 32bit libc++ on Linux | |
if: ${{ | |
matrix.architecture == '32bit' | |
&& matrix.config.prefix == 'Linux' | |
&& matrix.config.libcxx == true | |
}} | |
shell: bash | |
# remove 64bit binaries and install 32bit versions. | |
# I don't know, how to install them side by side. | |
run: | | |
apt-get remove -y \ | |
libc++-${{ matrix.config.compiler_version }}-dev \ | |
libc++abi-${{ matrix.config.compiler_version }}-dev | |
apt-get autoremove -y | |
dpkg --add-architecture i386 | |
apt-get update -y | |
apt-get install -y \ | |
libc++-${{ matrix.config.compiler_version }}-dev:i386 \ | |
libc++abi-${{ matrix.config.compiler_version }}-dev:i386 | |
- name: Setup __vectorcall as default call-convention on msvc | |
if: ${{ matrix.config.compiler_name == 'msvc' && matrix.config.default_call_convention == 'vectorcall' }} | |
shell: bash | |
# Do NOT remove the double /, as this will cause trouble during cmake configuration (it somehow expands to C:/Program Files/Git/Gv ???!) | |
# But, we will probably run into another issue, when CXXFLAGS happens to be not empty... | |
run: | | |
echo "CXXFLAGS=$(echo ${CXXFLAGS} //Gv)" >> $GITHUB_ENV | |
- name: Enable Address and Undefined Sanitizer | |
if: ${{ matrix.config.asan == true }} | |
shell: bash | |
run: | | |
echo "CMAKE_BASE_OPTIONS=$(echo ${CMAKE_BASE_OPTIONS} -DSANITIZE_ADDRESS=YES -DSANITIZE_UNDEFINED=YES)" >> $GITHUB_ENV | |
# ASan has some serious trouble with libc++ exception mechanism | |
# see: https://github.com/llvm/llvm-project/issues/59432 | |
- name: Disable alloc_dealloc_mismatch detection with libc++ | |
if: ${{ matrix.config.asan == true && matrix.config.libcxx == true}} | |
shell: bash | |
run: | | |
echo "ASAN_OPTIONS=$(echo ${ASAN_OPTIONS}:alloc_dealloc_mismatch=0)" >> $GITHUB_ENV | |
################################# | |
# Without optional features | |
- name: Configure Basic Framework | |
id: config-basic | |
if: ${{ matrix.config.only_fmt != true }} | |
shell: bash | |
run: | | |
cmake \ | |
-S . \ | |
-B build \ | |
${{ env.CMAKE_BASE_OPTIONS }} | |
- name: Build Basic Framework | |
if: ${{ steps.config-basic.outcome == 'success' }} | |
shell: bash | |
run: | | |
cmake --build build \ | |
-j5 \ | |
${{ env.CMAKE_BUILD_EXTRA }} | |
- name: Run Basic Framework tests | |
if: ${{ steps.config-basic.outcome == 'success' }} | |
shell: bash | |
env: | |
CTEST_OUTPUT_ON_FAILURE: 1 | |
run: | | |
ctest --test-dir build \ | |
-C ${{ matrix.build_mode }} \ | |
-j5 | |
# | |
################################# | |
################################# | |
# Feature: fmt formatting-backend | |
- name: Configure with fmt formatting-backend | |
shell: bash | |
run: | | |
cmake \ | |
-S . \ | |
-B build \ | |
${{ env.CMAKE_BASE_OPTIONS }} \ | |
-D MIMICPP_CONFIG_USE_FMT=YES | |
- name: Build with fmt formatting-backend | |
shell: bash | |
run: | | |
cmake --build build \ | |
-j5 \ | |
${{ env.CMAKE_BUILD_EXTRA }} | |
- name: Run tests with fmt formatting-backend | |
shell: bash | |
env: | |
CTEST_OUTPUT_ON_FAILURE: 1 | |
run: | | |
ctest --test-dir build \ | |
-C ${{ matrix.build_mode }} \ | |
-j5 | |
# | |
################################# | |
################################# | |
# Feature: Unicode string-matchers | |
- name: Configure with unicode string-matchers | |
shell: bash | |
run: | | |
cmake \ | |
-S . \ | |
-B build \ | |
${{ env.CMAKE_BASE_OPTIONS }} \ | |
-D MIMICPP_CONFIG_USE_FMT=YES \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_UNICODE_STR_MATCHER=YES | |
- name: Build with unicode string-matchers | |
shell: bash | |
run: | | |
cmake --build build \ | |
-j5 \ | |
${{ env.CMAKE_BUILD_EXTRA }} | |
- name: Run tests unicode string-matchers | |
shell: bash | |
env: | |
CTEST_OUTPUT_ON_FAILURE: 1 | |
run: | | |
ctest --test-dir build \ | |
-C ${{ matrix.build_mode }} \ | |
-j5 | |
# | |
################################# | |
################################# | |
# Feature: stacktrace | |
- name: Configure with std::stacktrace backend | |
id: config-cxx23-stacktrace | |
if: ${{ matrix.cxx_standard >= 23 }} | |
shell: bash | |
run: | | |
cmake \ | |
-S . \ | |
-B build \ | |
${{ env.CMAKE_BASE_OPTIONS }} \ | |
-D MIMICPP_CONFIG_USE_FMT=YES \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_STACKTRACE=YES | |
- name: Build with std::stacktrace backend | |
if: ${{ steps.config-cxx23-stacktrace.outcome == 'success' }} | |
shell: bash | |
run: | | |
cmake --build build \ | |
-j5 \ | |
${{ env.CMAKE_BUILD_EXTRA }} | |
- name: Run tests with std::stacktrace backend | |
if: ${{ steps.config-cxx23-stacktrace.outcome == 'success' }} | |
shell: bash | |
env: | |
CTEST_OUTPUT_ON_FAILURE: 1 | |
run: | | |
ctest --test-dir build \ | |
-C ${{ matrix.build_mode }} \ | |
-j5 | |
# cpptrace | |
# cpptrace doesn't support alternative default call conventions | |
# see: https://github.com/jeremy-rifkin/cpptrace/issues/197 | |
- name: Configure with cpptrace backend | |
id: config-cpptrace-backend | |
if: ${{matrix.config.default_call_convention == '' }} | |
shell: bash | |
run: | | |
cmake \ | |
-S . \ | |
-B build \ | |
${{ env.CMAKE_BASE_OPTIONS }} \ | |
-D MIMICPP_CONFIG_USE_FMT=YES \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_STACKTRACE=YES \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_USE_CPPTRACE=YES | |
- name: Build with cpptrace backend | |
if: ${{ steps.config-cpptrace-backend.outcome == 'success' }} | |
shell: bash | |
run: | | |
cmake --build build \ | |
-j5 \ | |
${{ env.CMAKE_BUILD_EXTRA }} | |
- name: Run tests with cpptrace backend | |
if: ${{ steps.config-cpptrace-backend.outcome == 'success' }} | |
shell: bash | |
env: | |
CTEST_OUTPUT_ON_FAILURE: 1 | |
run: | | |
ctest --test-dir build \ | |
-C ${{ matrix.build_mode }} \ | |
-j5 | |
# | |
################################# | |
################################# | |
# Adapter Tests | |
# Workflow is skipped, when an alternative default call-convention is applied. | |
- name: Configure adapter tests | |
id: config-adapter-test | |
if: ${{ matrix.config.default_call_convention == '' }} | |
shell: bash | |
run: | | |
cmake \ | |
-S . \ | |
-B build \ | |
${{ env.CMAKE_BASE_OPTIONS }} \ | |
-D MIMICPP_CONFIG_USE_FMT=YES \ | |
-D MIMICPP_ENABLE_ADAPTER_TESTS=YES \ | |
-D MIMICPP_CONFIG_EXPERIMENTAL_CATCH2_MATCHER_INTEGRATION=YES | |
- name: Build adapter tests | |
if: ${{ steps.config-adapter-test.outcome == 'success' }} | |
shell: bash | |
run: | | |
cmake --build build \ | |
-j5 \ | |
${{ env.CMAKE_BUILD_EXTRA }} | |
- name: Run adapter tests | |
if: ${{ steps.config-adapter-test.outcome == 'success' }} | |
shell: bash | |
env: | |
CTEST_OUTPUT_ON_FAILURE: 1 | |
run: | | |
ctest --test-dir build/test/adapter-tests \ | |
-C ${{ matrix.build_mode }} \ | |
-j5 | |
# | |
################################# |