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
72 changes: 72 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
name: CI

on:
push:
branches: [main, dev, '**']
pull_request:
branches: [main, dev]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build (${{ matrix.os }}, ${{ matrix.compiler }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
compiler: [clang]

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set compiler (Linux)
if: matrix.os == 'ubuntu-latest'
run: |
if [ "${{ matrix.compiler }}" = "gcc" ]; then
echo "CXX=g++" >> $GITHUB_ENV
else
echo "CXX=clang++" >> $GITHUB_ENV
fi

- name: Set compiler (macOS)
if: matrix.os == 'macos-latest'
run: echo "CXX=clang++" >> $GITHUB_ENV

- name: Set compiler (Windows)
if: matrix.os == 'windows-latest'
run: echo "CXX=clang++" >> $GITHUB_ENV

- name: Configure CMake
run: cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON -DBUILD_TESTING=ON

- name: Build
run: cmake --build build --parallel

- name: Run tests
run: ctest --test-dir build --output-on-failure

- name: Build and Run examples (Linux/macOS)
if: matrix.os != 'windows-latest'
run: |
if [ -d "build/examples" ]; then
for exe in build/examples/*_example; do
if [ -f "$exe" ]; then
"$exe"
fi
done
fi

- name: Build and Run examples (Windows)
if: matrix.os == 'windows-latest'
run: |
if (Test-Path build/examples) {
Get-ChildItem -Path build/examples -Filter "*.exe" | ForEach-Object { & $_.FullName }
}
42 changes: 42 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: Code Quality

on:
push:
branches: [main, dev, '**']
pull_request:
branches: [main, dev]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
clang-format:
name: Clang Format Check
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Check formatting
run: |
# Install clang-format if not available
if ! command -v clang-format &> /dev/null; then
sudo apt-get update
sudo apt-get install -y clang-format
fi

# Find all C++ source files
FAILED=0
for file in $(find . -name '*.hpp' -o -name '*.cc'); do
if ! clang-format --style=file --dry-run "$file" 2>/dev/null; then
echo "Formatting issues found in: $file"
FAILED=1
fi
done

if [ $FAILED -eq 1 ]; then
echo "Some files have formatting issues. Run 'cmake --build . --target format' to fix."
fi
133 changes: 133 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
name: Release

on:
push:
tags:
- 'v*'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Get version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT

- name: Setup CMake and Ninja
if: runner.os != 'Windows'
run: |
if [ "$RUNNER_OS" = "Linux" ]; then
sudo apt-get update && sudo apt-get install -y cmake ninja-build
elif [ "$RUNNER_OS" = "macOS" ]; then
brew install cmake ninja
fi

- name: Configure CMake
run: |
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_EXAMPLES=ON -DBUILD_TESTING=ON

- name: Build
run: |
cmake --build build --parallel

- name: Run tests
run: ctest --test-dir build --output-on-failure

- name: Run examples (Linux/macOS)
if: runner.os != 'Windows'
run: |
if [ -d "build/examples" ]; then
for exe in build/examples/*_example; do
if [ -f "$exe" ] || [ -f "$exe.exe" ]; then
"$exe" || exit 1
fi
done
fi

- name: Run examples (Windows)
if: runner.os == 'Windows'
run: |
if (Test-Path build/examples) {
Get-ChildItem -Path build/examples -Filter "*.exe" | ForEach-Object { & $_.FullName }
}

- name: Package (Linux/macOS)
if: runner.os != 'Windows'
run: |
cmake -B release -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DXCMATH_BUILD_EXAMPLES=ON \
-DCMAKE_INSTALL_PREFIX=install \
-DBUILD_TESTING=OFF
cmake --build release --target install

# Create archive
cd install
tar -czvf ../xcmath-${{ steps.version.outputs.VERSION }}-${{ matrix.os }}.tar.gz *

- name: Package (Windows)
if: runner.os == 'Windows'
run: |
cmake -B release -G Ninja -DCMAKE_BUILD_TYPE=Release -DXCMATH_BUILD_EXAMPLES=ON -DCMAKE_INSTALL_PREFIX=install -DBUILD_TESTING=OFF
cmake --build release --target install

# Create archive
Compress-Archive -Path 'install/*' -DestinationPath 'xcmath-${{ steps.version.outputs.VERSION }}-${{ matrix.os }}.zip'

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: xcmath-${{ matrix.os }}
path: xcmath-${{ steps.version.outputs.VERSION }}-${{ matrix.os }}.*
retention-days: 5

release:
name: Create Release
needs: build
runs-on: ubuntu-latest
permissions:
contents: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive

- name: Get version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT

- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts

- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
name: xcmath v${{ steps.version.outputs.VERSION }}
draft: false
prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') }}
generate_release_notes: true
files: |
artifacts/xcmath-ubuntu-latest/*
artifacts/xcmath-macos-latest/*
artifacts/xcmath-windows-latest/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 changes: 9 additions & 9 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
!/README-zh.md
!/LICENSE
!/.clang-format
!resources/
!vcpkg.json
!CMakePresets.json
!Doxyfile
!xmake.lua
!examples/
!TODO
!cmake
!/resources/
!/CMakePresets.json
!/Doxyfile
!/xmake.lua
!/examples/
!/TODO
!/cmake
!/third_party/
docs/doxygen
!/docs/doxygen
!/.github/
62 changes: 62 additions & 0 deletions cmake/get_version.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Version Management via Git Tags
#
# This module provides functions to extract project version from git tags.
# Version format: vX.Y.Z (e.g., v1.0.0)
#
# Usage:
# include(cmake/get_version.cmake)
# xc_get_project_version(PROJECT_VERSION)
#
# Public API:
# xc_get_last_git_tag(TAG_VAR DEFAULT_VALUE) - Get the most recent git tag
# xc_get_project_version(VERSION_VAR) - Get version from latest tag

find_program(GIT_EXE NAMES git)

# xc_get_last_git_tag(TAG_VAR DEFAULT_VALUE)
# Get the most recent git tag
#
# Args:
# TAG_VAR - Variable to store the tag
# DEFAULT_VALUE - Default value if no tag found
#
# Examples:
# xc_get_last_git_tag(TAG "v0.0.0")
function(xc_get_last_git_tag TAG_VAR DEFAULT_VALUE)
if(NOT GIT_EXE)
message(FATAL_ERROR "git not found")
endif()

set(${TAG_VAR} ${DEFAULT_VALUE} PARENT_SCOPE)

execute_process(
COMMAND ${GIT_EXE} describe --abbrev=0 --tags
OUTPUT_VARIABLE GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
)

if(GIT_TAG)
message(STATUS "GIT_TAG: ${GIT_TAG}")
set(${TAG_VAR} ${GIT_TAG} PARENT_SCOPE)
endif()
endfunction(xc_get_last_git_tag)

# xc_get_project_version(VERSION_VAR)
# Get project version from latest git tag
#
# Extracts version in format X.Y.Z from tag (e.g., v1.2.3 -> 1.2.3)
# Defaults to 0.0.0 if no valid tag found
#
# Args:
# VERSION_VAR - Variable to store the version
#
# Examples:
# xc_get_project_version(PROJECT_VERSION)
function(xc_get_project_version VERSION_VAR)
xc_get_last_git_tag(GIT_TAG "v0.0.0")
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" VERSION ${GIT_TAG})
if(NOT VERSION)
message(FATAL_ERROR "git tag ${GIT_TAG} not match version format")
endif()
set(${VERSION_VAR} ${VERSION} PARENT_SCOPE)
endfunction(xc_get_project_version)
58 changes: 58 additions & 0 deletions cmake/install.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Installation configuration for xcmath
#
# This file handles the installation of xcmath library targets and headers.

include(CMakePackageConfigHelpers)

# Set uppercase project name
set(UP_XCMATH "XCMATH")

# Define install directory for CMake config
set(UP_XCMATH_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/xcmath")

# Install export set
install(
TARGETS xcmath
EXPORT xcmath
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

# Install headers
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/xcmath/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/xcmath/
FILES_MATCHING
PATTERN "*.hpp"
PATTERN "*.h"
)

# Generate and install CMake config files
configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/xcmathConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/xcmathConfig.cmake
INSTALL_DESTINATION ${UP_XCMATH_CMAKE_INSTALL_DIR}
)

write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/xcmathConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)

install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/xcmathConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/xcmathConfigVersion.cmake
DESTINATION ${UP_XCMATH_CMAKE_INSTALL_DIR}
)

# Install export
install(
EXPORT xcmath
NAMESPACE xcmath::
FILE xcmathConfig.cmake
DESTINATION ${UP_XCMATH_CMAKE_INSTALL_DIR}
)
Loading
Loading