Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
104 changes: 92 additions & 12 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,23 @@ jobs:
triplet: x64-linux
runner: ubuntu-latest
preset: linux-release-vcpkg
coverage: true
install_cmd: |
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
sudo add-apt-repository -y "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-21 main"
sudo apt-get update
sudo apt-get install -y git build-essential cmake ninja-build \
zip unzip curl pkg-config ca-certificates \
clang-21 lld-21 libc++-21-dev libc++abi-21-dev
clang-21 lld-21 libc++-21-dev libc++abi-21-dev \
llvm-21
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-21 100
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-21 100
sudo update-alternatives --install /usr/bin/lld lld /usr/bin/lld-21 100
- name: Linux (Clang) (x86-linux)
triplet: x86-linux
runner: ubuntu-latest
preset: linux-release-vcpkg-x86
coverage: false
install_cmd: |
# Add LLVM 21 repository
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
Expand Down Expand Up @@ -65,6 +68,7 @@ jobs:
triplet: arm64-linux
runner: ubuntu-24.04-arm
preset: linux-release-vcpkg-arm64
coverage: false
install_cmd: |
wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc
sudo add-apt-repository -y "deb http://apt.llvm.org/noble/ llvm-toolchain-noble-21 main"
Expand All @@ -91,7 +95,7 @@ jobs:
- name: Set up vcpkg
shell: bash
run: |
git clone --branch 2025.12.12 --single-branch https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
cd "$VCPKG_ROOT"
./bootstrap-vcpkg.sh

Expand All @@ -102,6 +106,7 @@ jobs:
-DVCPKG_INSTALL_OPTIONS="--allow-unsupported" \
-DOMATH_BUILD_TESTS=ON \
-DOMATH_BUILD_BENCHMARK=OFF \
-DOMATH_ENABLE_COVERAGE=${{ matrix.coverage == true && 'ON' || 'OFF' }} \
-DVCPKG_MANIFEST_FEATURES="imgui;avx2;tests"

- name: Build
Expand All @@ -112,6 +117,25 @@ jobs:
shell: bash
run: ./out/Release/unit_tests

- name: Run Coverage
if: ${{ matrix.coverage == true }}
shell: bash
run: |
sudo apt-get install lcov
chmod +x scripts/coverage-llvm.sh
./scripts/coverage-llvm.sh \
"${{ github.workspace }}" \
"cmake-build/build/${{ matrix.preset }}" \
"./out/Release/unit_tests" \
"cmake-build/build/${{ matrix.preset }}/coverage"

- name: Upload Coverage Report
if: ${{ matrix.coverage == true }}
uses: actions/upload-artifact@v4
with:
name: coverage-report-linux
path: cmake-build/build/${{ matrix.preset }}/coverage/

- name: Upload logs on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -164,7 +188,7 @@ jobs:

- name: Configure (cmake --preset)
shell: bash
run: cmake --preset ${{ matrix.preset }} -DOMATH_BUILD_TESTS=ON -DOMATH_BUILD_BENCHMARK=OFF -DVCPKG_MANIFEST_FEATURES="imgui;avx2;tests"
run: cmake --preset ${{ matrix.preset }} -DOMATH_BUILD_TESTS=ON -DOMATH_BUILD_BENCHMARK=OFF -DOMATH_ENABLE_COVERAGE=OFF -DVCPKG_MANIFEST_FEATURES="imgui;avx2;tests"

- name: Build
shell: bash
Expand All @@ -174,6 +198,36 @@ jobs:
shell: bash
run: ./out/Release/unit_tests.exe

- name: Install OpenCppCoverage with Chocolatey
if: ${{ matrix.triplet == 'x64-windows' }}
run: choco install opencppcoverage -y

- name: Build Debug for Coverage
if: ${{ matrix.triplet == 'x64-windows' }}
shell: bash
run: |
cmake --preset ${{ matrix.preset }} \
-DOMATH_BUILD_TESTS=ON \
-DOMATH_BUILD_BENCHMARK=OFF \
-DOMATH_ENABLE_COVERAGE=ON \
-DCMAKE_BUILD_TYPE=Debug \
-DVCPKG_MANIFEST_FEATURES="imgui;avx2;tests"
cmake --build cmake-build/build/${{ matrix.preset }} --config Debug --target unit_tests omath

- name: Run Coverage
if: ${{ matrix.triplet == 'x64-windows' }}
shell: pwsh
run: |
$env:Path = "C:\Program Files\OpenCppCoverage;$env:Path"
cmake --build cmake-build/build/${{ matrix.preset }} --target coverage --config Debug

- name: Upload Coverage
if: ${{ matrix.triplet == 'x64-windows' }}
uses: actions/upload-artifact@v4
with:
name: coverage-report-windows
path: cmake-build/build/${{ matrix.preset }}/coverage/

- name: Upload logs on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v4
Expand All @@ -193,13 +247,15 @@ jobs:
matrix:
include:
- name: macOS (AppleClang) (arm64-osx)
runner: macOS-latest
runner: macos-latest
preset: darwin-release-vcpkg
triplet: arm64-osx
coverage: true
- name: macOS (AppleClang) (x64-osx)
runner: macos-15-intel
preset: darwin-release-vcpkg-x64
triplet: x64-osx
coverage: false
fail-fast: false
env:
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
Expand All @@ -217,20 +273,44 @@ jobs:
- name: Set up vcpkg
shell: bash
run: |
git clone --branch 2025.12.12 --single-branch https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT"

- name: Configure (cmake --preset)
shell: bash
run: cmake --preset ${{matrix.preset}} -DOMATH_BUILD_TESTS=ON -DOMATH_BUILD_BENCHMARK=OFF -DVCPKG_MANIFEST_FEATURES="imgui;avx2;tests"
run: |
cmake --preset ${{ matrix.preset }} \
-DOMATH_BUILD_TESTS=ON \
-DOMATH_BUILD_BENCHMARK=OFF \
-DOMATH_ENABLE_COVERAGE=${{ matrix.coverage == true && 'ON' || 'OFF' }} \
-DVCPKG_MANIFEST_FEATURES="imgui;avx2;tests"

- name: Build
shell: bash
run: cmake --build cmake-build/build/${{matrix.preset}} --target unit_tests omath
run: cmake --build cmake-build/build/${{ matrix.preset }} --target unit_tests omath

- name: Run unit_tests
shell: bash
run: ./out/Release/unit_tests

- name: Run Coverage
if: ${{ matrix.coverage == true }}
shell: bash
run: |
brew install lcov
chmod +x scripts/coverage-llvm.sh
./scripts/coverage-llvm.sh \
"${{ github.workspace }}" \
"cmake-build/build/${{ matrix.preset }}" \
"./out/Release/unit_tests" \
"cmake-build/build/${{ matrix.preset }}/coverage"

- name: Upload Coverage Report
if: ${{ matrix.coverage == true }}
uses: actions/upload-artifact@v4
with:
name: coverage-report-macos
path: cmake-build/build/${{ matrix.preset }}/coverage/

- name: Upload logs on failure
if: ${{ failure() }}
uses: actions/upload-artifact@v4
Expand Down Expand Up @@ -268,7 +348,7 @@ jobs:
- name: Set up vcpkg
shell: bash
run: |
git clone --branch 2025.12.12 --single-branch https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
cd "$VCPKG_ROOT"
./bootstrap-vcpkg.sh

Expand Down Expand Up @@ -330,7 +410,7 @@ jobs:
# Build vcpkg in /tmp to avoid sshfs timestamp sync issues
export VCPKG_ROOT=/tmp/vcpkg
rm -rf "$VCPKG_ROOT"
git clone --branch 2025.12.12 --single-branch https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
cd "$VCPKG_ROOT"
./bootstrap-vcpkg.sh
cd -
Expand Down Expand Up @@ -399,7 +479,7 @@ jobs:
- name: Set up vcpkg
shell: bash
run: |
git clone --branch 2025.12.12 --single-branch https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
cd "$VCPKG_ROOT"
./bootstrap-vcpkg.sh

Expand Down Expand Up @@ -468,7 +548,7 @@ jobs:
- name: Set up vcpkg
shell: bash
run: |
git clone --branch 2025.12.12 --single-branch https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
cd "$VCPKG_ROOT"
./bootstrap-vcpkg.sh

Expand Down Expand Up @@ -554,7 +634,7 @@ jobs:

- name: Set up vcpkg
run: |
git clone --branch 2025.12.12 --single-branch https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
git clone https://github.com/microsoft/vcpkg "$VCPKG_ROOT"
cd "$VCPKG_ROOT"
./bootstrap-vcpkg.sh

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
/extlibs/vcpkg
.idea/workspace.xml
/build/
/clang-coverage/
*.gcov
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project(omath VERSION ${OMATH_VERSION} LANGUAGES CXX)

include(CMakePackageConfigHelpers)
include(CheckCXXCompilerFlag)
include(cmake/Coverage.cmake)

if (MSVC)
check_cxx_compiler_flag("/arch:AVX2" COMPILER_SUPPORTS_AVX2)
Expand All @@ -23,7 +24,7 @@ option(OMATH_STATIC_MSVC_RUNTIME_LIBRARY "Force Omath to link static runtime" OF
option(OMATH_SUPRESS_SAFETY_CHECKS "Supress some safety checks in release build to improve general performance" ON)
option(OMATH_USE_UNITY_BUILD "Will enable unity build to speed up compilation" OFF)
option(OMATH_ENABLE_LEGACY "Will enable legacy classes that MUST be used ONLY for backward compatibility" ON)

option(OMATH_ENABLE_COVERAGE "Enable coverage" OFF)

if (VCPKG_MANIFEST_FEATURES)
foreach (omath_feature IN LISTS VCPKG_MANIFEST_FEATURES)
Expand Down Expand Up @@ -145,6 +146,9 @@ target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_23)
if (OMATH_BUILD_TESTS)
add_subdirectory(tests)
target_compile_definitions(${PROJECT_NAME} PUBLIC OMATH_BUILD_TESTS)
if(OMATH_ENABLE_COVERAGE)
omath_setup_coverage(${PROJECT_NAME})
endif()
endif ()

if (OMATH_BUILD_BENCHMARK)
Expand Down
122 changes: 122 additions & 0 deletions cmake/Coverage.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# cmake/Coverage.cmake
include_guard(GLOBAL)

function(omath_setup_coverage TARGET_NAME)
if(ANDROID OR IOS OR EMSCRIPTEN)
return()
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang")
# Apply to ALL configs when coverage is enabled (not just Debug)
target_compile_options(${TARGET_NAME} PRIVATE
-fprofile-instr-generate
-fcoverage-mapping
-g
-O0
)
target_link_options(${TARGET_NAME} PRIVATE
-fprofile-instr-generate
-fcoverage-mapping
)

elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(${TARGET_NAME} PRIVATE
--coverage
-g
-O0
)
target_link_options(${TARGET_NAME} PRIVATE
--coverage
)

elseif(MSVC)
target_compile_options(${TARGET_NAME} PRIVATE
/Zi
/Od
/Ob0
)
target_link_options(${TARGET_NAME} PRIVATE
/DEBUG:FULL
/INCREMENTAL:NO
)
endif()

# Create coverage target only once
if(TARGET coverage)
return()
endif()

if(MSVC OR MINGW)
# Windows: OpenCppCoverage
find_program(OPENCPPCOVERAGE_EXECUTABLE
NAMES OpenCppCoverage OpenCppCoverage.exe
PATHS
"$ENV{ProgramFiles}/OpenCppCoverage"
"$ENV{ProgramW6432}/OpenCppCoverage"
"C:/Program Files/OpenCppCoverage"
DOC "Path to OpenCppCoverage executable"
)

if(NOT OPENCPPCOVERAGE_EXECUTABLE)
message(WARNING "OpenCppCoverage not found. Install with: choco install opencppcoverage")
set(OPENCPPCOVERAGE_EXECUTABLE "C:/Program Files/OpenCppCoverage/OpenCppCoverage.exe")
else()
message(STATUS "Found OpenCppCoverage: ${OPENCPPCOVERAGE_EXECUTABLE}")
endif()

file(TO_NATIVE_PATH "${CMAKE_SOURCE_DIR}" COVERAGE_ROOT_PATH)
file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/coverage" COVERAGE_OUTPUT_PATH)
file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/coverage.xml" COVERAGE_XML_PATH)
file(TO_NATIVE_PATH "${OPENCPPCOVERAGE_EXECUTABLE}" OPENCPPCOVERAGE_NATIVE)

add_custom_target(coverage
DEPENDS unit_tests
COMMAND "${OPENCPPCOVERAGE_NATIVE}"
--verbose
--sources "${COVERAGE_ROOT_PATH}"
--modules "${COVERAGE_ROOT_PATH}"
--excluded_sources "*\\tests\\*"
--excluded_sources "*\\gtest\\*"
--excluded_sources "*\\googletest\\*"
--excluded_sources "*\\_deps\\*"
--excluded_sources "*\\vcpkg_installed\\*"
--export_type "html:${COVERAGE_OUTPUT_PATH}"
--export_type "cobertura:${COVERAGE_XML_PATH}"
--cover_children
-- "$<TARGET_FILE:unit_tests>"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMENT "Running OpenCppCoverage"
)

elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang")
# Linux/macOS: LLVM coverage via script
add_custom_target(coverage
DEPENDS unit_tests
COMMAND bash "${CMAKE_SOURCE_DIR}/scripts/coverage-llvm.sh"
"${CMAKE_SOURCE_DIR}"
"${CMAKE_BINARY_DIR}"
"$<TARGET_FILE:unit_tests>"
"${CMAKE_BINARY_DIR}/coverage"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMENT "Running LLVM coverage"
)

elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# GCC: lcov/gcov
add_custom_target(coverage
DEPENDS unit_tests
COMMAND $<TARGET_FILE:unit_tests> || true
COMMAND lcov --capture --directory "${CMAKE_BINARY_DIR}"
--output-file "${CMAKE_BINARY_DIR}/coverage.info"
--ignore-errors mismatch,gcov
COMMAND lcov --remove "${CMAKE_BINARY_DIR}/coverage.info"
"*/tests/*" "*/gtest/*" "*/googletest/*" "*/_deps/*" "/usr/*"
--output-file "${CMAKE_BINARY_DIR}/coverage.info"
--ignore-errors unused
COMMAND genhtml "${CMAKE_BINARY_DIR}/coverage.info"
--output-directory "${CMAKE_BINARY_DIR}/coverage"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Running lcov/genhtml"
)
endif()
endfunction()
Loading
Loading