Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9e7c854
re-order fetching dependencies
daantimmer Sep 11, 2026
55c6ef4
update code after cucumber module changes
daantimmer Sep 11, 2026
616a237
Update to include pretty-formatter formatters
daantimmer Sep 12, 2026
cad4313
update dependencies
daantimmer Sep 18, 2026
325cccd
add cucumber/cucumber_expressions
daantimmer Sep 19, 2026
d4cc87c
update pretty printer
daantimmer Sep 19, 2026
9a7f0db
update cucumber-expressions
daantimmer Sep 19, 2026
73ac57b
update cucumber-expressions
daantimmer Sep 19, 2026
3140d6b
fix bats test
daantimmer Sep 19, 2026
3b4f1e3
resolve sonar warnings
daantimmer Sep 19, 2026
bc186ac
remove testdata
daantimmer Sep 19, 2026
ecc4921
de-duplicate some common code
daantimmer Sep 19, 2026
8c754b2
add test-system configuration to test building using system packages
daantimmer Sep 20, 2026
6775e64
fix repositories
daantimmer Sep 20, 2026
6a01a4b
add cli11 and pugixml to system packages test
daantimmer Sep 20, 2026
a70e765
update required dependency versions
daantimmer Sep 20, 2026
a83bd8b
remove re2 find_package, this is handled in cucumber::cucumber_expres…
daantimmer Sep 20, 2026
7ea3405
update cucumber-expressions
daantimmer Sep 20, 2026
8136728
update fmt includes
daantimmer Sep 20, 2026
e4cd6eb
add missing fmt include and update cucumber-expressions includes
daantimmer Sep 20, 2026
d793465
fix clang-21/22 chrono issue with fmt10
daantimmer Sep 20, 2026
3eba73a
fix clang-cl
daantimmer Sep 20, 2026
c2da18b
try manually calculating ISO timestamp
daantimmer Sep 20, 2026
5a03aab
revert timestamp change and solve CLI11's ODR violation
daantimmer Sep 20, 2026
a00d20e
update cmake options
daantimmer Sep 20, 2026
ee6f258
restrict sanitizers to GNU compiler and add coverage warning
daantimmer Sep 20, 2026
90a6666
check first if any external dependencies are already added through ot…
daantimmer Sep 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Checks: '
-misc-non-private-member-variables-in-classes,
modernize*,
-modernize-use-trailing-return-type,
-modernize-use-designated-initializers,
performance*,
-performance-no-int-to-ptr,
readability*,
Expand Down
222 changes: 222 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,18 @@ concurrency:
env:
GTEST_COLOR: 1
CPM_SOURCE_CACHE: ${{ github.workspace }}/.cpm
# renovate: datasource=git-refs depName=cucumber/messages packageName=https://github.com/cucumber/messages currentValue=main
MESSAGES_REF: main
# renovate: datasource=git-refs depName=cucumber/gherkin packageName=https://github.com/cucumber/gherkin currentValue=main
GHERKIN_REF: main
# renovate: datasource=git-refs depName=cucumber/query packageName=https://github.com/cucumber/query currentValue=feature/cpp
QUERY_REF: feature/cpp
# renovate: datasource=git-refs depName=cucumber/tag-expressions packageName=https://github.com/cucumber/tag-expressions currentValue=feature/cpp
TAG_EXPRESSIONS_REF: feature/cpp
# renovate: datasource=git-refs depName=cucumber/pretty-formatter packageName=https://github.com/cucumber/pretty-formatter currentValue=feature/cpp
PRETTY_FORMATTER_REF: feature/cpp
# renovate: datasource=git-refs depName=cucumber/cucumber-expressions packageName=https://github.com/cucumber/cucumber-expressions currentValue=feature/cpp
CUCUMBER_EXPRESSIONS_REF: feature/cpp

jobs:
build-in-devcontainer:
Expand Down Expand Up @@ -120,3 +132,213 @@ jobs:
with:
name: test-logs
path: .build/${{ matrix.os }}-Debug-${{ matrix.type }}${{ matrix.preset_suffix }}/Testing/Temporary/

test-cpp-system-packages-linux:
runs-on: ${{ matrix.config.os }}
strategy:
fail-fast: false
matrix:
config:
- { os: ubuntu-24.04, cxx: g++, version: 12 }
- { os: ubuntu-24.04, cxx: g++, version: 13 }
- { os: ubuntu-24.04, cxx: clang++, version: 16 }
- { os: ubuntu-24.04, cxx: clang++, version: 17 }
- { os: ubuntu-26.04, cxx: g++, version: 14 }
- { os: ubuntu-26.04, cxx: g++, version: 15 }
- { os: ubuntu-26.04, cxx: clang++, version: 21 }
- { os: ubuntu-26.04, cxx: clang++, version: 22 }
env:
CXX: ${{ matrix.config.cxx }}-${{ matrix.config.version }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
submodules: true

- name: ccache
uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23
with:
key: ${{ github.job }}-${{ matrix.config.os }}-${{ matrix.config.cxx }}-${{ matrix.config.version }}-${{ github.ref }}
append-timestamp: false
save: ${{ github.ref == 'refs/heads/main' }}

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y nlohmann-json3-dev libgtest-dev libgmock-dev libabsl-dev libre2-dev libcli11-dev libpugixml-dev

# Ubuntu 24.04 ships fmt 9; newer runners provide fmt 10+ via apt.
- name: Install libfmt (apt)
if: matrix.config.os != 'ubuntu-24.04'
run: sudo apt-get install -y libfmt-dev

- name: Checkout libfmt
if: matrix.config.os == 'ubuntu-24.04'
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: fmtlib/fmt
ref: 10.2.1
path: fmt-src
persist-credentials: false

- name: Install libfmt (from source)
if: matrix.config.os == 'ubuntu-24.04'
run: |
cmake -S fmt-src -B fmt-src/build \
-DCMAKE_BUILD_TYPE=Release \
-DFMT_TEST=OFF -DFMT_DOC=OFF \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
cmake --build fmt-src/build
sudo cmake --install fmt-src/build

- name: Install cucumber/tag-expressions
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/tag-expressions
ref: ${{ env.TAG_EXPRESSIONS_REF }}

- name: Install cucumber/cucumber-expressions
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/cucumber-expressions
ref: ${{ env.CUCUMBER_EXPRESSIONS_REF }}

- name: Install cucumber/messages
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/messages
ref: ${{ env.MESSAGES_REF }}

- name: Install cucumber/gherkin
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/gherkin
ref: ${{ env.GHERKIN_REF }}

- name: Install cucumber/query
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/query
ref: ${{ env.QUERY_REF }}

- name: Install cucumber/pretty-formatter
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/pretty-formatter
ref: ${{ env.PRETTY_FORMATTER_REF }}

- name: Build and unit test
run: cmake --workflow --preset test-system

test-cpp-system-packages-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
submodules: true

- name: ccache
uses: hendrikmuhs/ccache-action@d62db5f07c26379fc4b4e0916f098a92573c3b03 # v1.2.23
with:
key: ${{ github.job }}-${{ github.ref }}
append-timestamp: false
save: ${{ github.ref == 'refs/heads/main' }}

- name: Install dependencies
run: brew install googletest nlohmann-json fmt abseil re2 cli11 pugixml

- name: Install cucumber/tag-expressions
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/tag-expressions
ref: ${{ env.TAG_EXPRESSIONS_REF }}

- name: Install cucumber/cucumber-expressions
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/cucumber-expressions
ref: ${{ env.CUCUMBER_EXPRESSIONS_REF }}

- name: Install cucumber/messages
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/messages
ref: ${{ env.MESSAGES_REF }}

- name: Install cucumber/gherkin
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/gherkin
ref: ${{ env.GHERKIN_REF }}

- name: Install cucumber/query
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/query
ref: ${{ env.QUERY_REF }}

- name: Install cucumber/pretty-formatter
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/pretty-formatter
ref: ${{ env.PRETTY_FORMATTER_REF }}

- name: Build and unit test
run: cmake --workflow --preset test-system

test-cpp-system-packages-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
submodules: true

- name: Install build tools
uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0

- name: Install dependencies
shell: pwsh
run: |
vcpkg install gtest nlohmann-json fmt abseil re2 cli11 pugixml --triplet x64-windows
# Expose the vcpkg toolchain so find_package() locates the packages.
echo "CMAKE_TOOLCHAIN_FILE=$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" >> $env:GITHUB_ENV

- name: Install cucumber/tag-expressions
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/tag-expressions
ref: ${{ env.TAG_EXPRESSIONS_REF }}

- name: Install cucumber/cucumber-expressions
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/cucumber-expressions
ref: ${{ env.CUCUMBER_EXPRESSIONS_REF }}

- name: Install cucumber/messages
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/messages
ref: ${{ env.MESSAGES_REF }}

- name: Install cucumber/gherkin
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/gherkin
ref: ${{ env.GHERKIN_REF }}

- name: Install cucumber/query
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/query
ref: ${{ env.QUERY_REF }}

- name: Install cucumber/pretty-formatter
uses: cucumber/ci-actions/install-cpp-dep@9ba4a623ec838b1358e18683a85a0914f3779363
with:
repository: cucumber/pretty-formatter
ref: ${{ env.PRETTY_FORMATTER_REF }}
- name: Build and unit test
run: cmake --workflow --preset test-system
63 changes: 19 additions & 44 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,23 @@ endif()

option(CCR_FETCH_DEPS "Fetch dependencies via FetchContent." ${CCR_DEFAULTOPT} )
option(CCR_BUILD_TESTS "Enable build of the tests" ${CCR_DEFAULTOPT})
option(CCR_USE_RE2 "Use the RE2 regex engine (fetched when CCR_FETCH_DEPS is set, otherwise auto-detected)" ${CCR_DEFAULTOPT})

option(CCR_ENABLE_COVERAGE "Enable compiler flags for code coverage measurements" Off)
option(CCR_ENABLE_SANITIZERS "Enable compiler flags for the address and undefined behaviour sanitizers" Off)
option(CCR_ENABLE_TIME_PROFILE "Enable compiler flags for time profiling measurements" Off)

option(CCR_USE_RE2 "Use the RE2 regex engine (fetched when CCR_FETCH_DEPS is set, otherwise auto-detected)" ${CCR_DEFAULTOPT})

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if(CCR_ENABLE_SANITIZERS AND CCR_ENABLE_COVERAGE)
message(FATAL_ERROR "CCR_ENABLE_SANITIZERS and CCR_ENABLE_COVERAGE are mutually exclusive.")
endif()

if(CCR_ENABLE_COVERAGE AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
message(WARNING "Code coverage is only enabled with the GNU compiler.")
endif()

if (CCR_BUILD_TESTS)
ccr_enable_testing()
endif()
Expand Down Expand Up @@ -80,64 +91,28 @@ include(FetchContent)
include(GNUInstallDirs)
include(CTest)

# Enable sanitizers globally, before any dependency is added, so every target
# (including fetched third-party libraries) is instrumented. Consistent
# instrumentation keeps libc++ container annotations coherent across module
# boundaries; mixing instrumented and uninstrumented code produces false-positive
# container-overflow reports.
if (PROJECT_IS_TOP_LEVEL AND NOT CCR_ENABLE_COVERAGE
AND NOT (CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR CMAKE_CXX_SIMULATE_ID MATCHES "MSVC"))
set(CCR_ENABLE_SANITIZERS On)
endif()
include(cmake/dependencies.cpm.cmake)
add_subdirectory(external)

if (CCR_ENABLE_SANITIZERS)
add_compile_options(-fsanitize=address -fsanitize=undefined)
add_link_options(-fsanitize=address -fsanitize=undefined)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-fsanitize=address -fsanitize=undefined)
add_link_options(-fsanitize=address -fsanitize=undefined)
endif()
Comment on lines +98 to +101
endif()
Comment thread
daantimmer marked this conversation as resolved.

include(cmake/dependencies.cpm.cmake)
add_subdirectory(external)

if (TARGET re2::re2)
set(CCR_HAS_RE2 On)
else()
set(CCR_HAS_RE2 Off)
endif()

# Opt specific dependencies out of sanitizer instrumentation because of known
# limitations: abseil's constexpr function-pointer comparisons are not compatible
# with GCC's ASan/UBSan instrumentation, which causes build failures. Later target
# options override the globally inherited flags.
if (CCR_ENABLE_SANITIZERS)
function(ccr_disable_sanitizers dir)
get_property(targets DIRECTORY "${dir}" PROPERTY BUILDSYSTEM_TARGETS)
foreach(target IN LISTS targets)
get_target_property(type ${target} TYPE)
if (NOT type STREQUAL "INTERFACE_LIBRARY" AND NOT type STREQUAL "UTILITY")
target_compile_options(${target} PRIVATE -fno-sanitize=address -fno-sanitize=undefined)
target_link_options(${target} PRIVATE -fno-sanitize=address -fno-sanitize=undefined)
endif()
endforeach()

get_property(subdirs DIRECTORY "${dir}" PROPERTY SUBDIRECTORIES)
foreach(subdir IN LISTS subdirs)
ccr_disable_sanitizers("${subdir}")
endforeach()
endfunction()

foreach(dep_dir IN ITEMS "${abseil-cpp_SOURCE_DIR}" "${re2_SOURCE_DIR}")
if (dep_dir AND IS_DIRECTORY "${dep_dir}")
ccr_disable_sanitizers("${dep_dir}")
endif()
endforeach()
endif()

if(PROJECT_IS_TOP_LEVEL)
set(CMAKE_COMPILE_WARNING_AS_ERROR On)
endif()

add_subdirectory(cucumber_cpp)

if (PROJECT_IS_TOP_LEVEL)
if (CCR_BUILD_TESTS)
add_subdirectory(compatibility)
endif()
Loading
Loading