Skip to content

Commit ce8936e

Browse files
authored
chore: Modernize CMake build, CI workflows, and code quality tooling (#16)
This pull request introduces significant improvements to the C++ project's build system, code quality tooling, and codebase consistency. The main focus is on modernizing the CMake configuration, enhancing CI workflows, enforcing code quality standards, and making minor code improvements for readability and correctness. **Build System Modernization and CI Improvements:** * Migrated to CMake 3.25+ with modern target-based configuration, introduced `CMakePresets.json` for standardized build and test presets, and improved compiler warning handling using `target_compile_options`. [[1]](diffhunk://#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aL1-R12) [[2]](diffhunk://#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR36-R43) [[3]](diffhunk://#diff-1712b235e02bd4a3ad866fe26447a6dc5c1b449faeea513f449d244d46d03cf5R1-R107) * Updated the GitHub Actions workflow to split formatting and build/test jobs, enforce `clang-format` checks, and use CMake presets for CI builds. **Code Quality and Tooling Enhancements:** * Refined `.clang-tidy` configuration to enable/disable specific checks, treat critical warnings as errors, and set header filtering for source files. * Improved CMake targets for `clang-format` and `clang-tidy`, ensuring only source files are linted and all code is properly formatted. [[1]](diffhunk://#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aL60-R97) [[2]](diffhunk://#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR118-R133) * Added VSCode settings for YAML associations and updated documentation with requirements, build instructions, and code quality commands. [[1]](diffhunk://#diff-a5de3e5871ffcc383a2294845bd3df25d3eeff6c29ad46e3a396577c413bf357L7-R11) [[2]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R6-R55) * Removed obsolete `scripts/run_tests.sh` in favor of CMake presets and CI workflows. **Codebase Consistency and Minor Fixes:** * Added `[[nodiscard]]` and other modern C++ attributes to key methods, improved initialization, and standardized output formatting across several data structures and algorithms. [[1]](diffhunk://#diff-035b7389279440bf3472b6a9ab837486652786563c0bcb30e6c466af3d972ed0L29-R29) [[2]](diffhunk://#diff-035b7389279440bf3472b6a9ab837486652786563c0bcb30e6c466af3d972ed0L44-R44) [[3]](diffhunk://#diff-0b5eede64af7e5fa987b28c15c62d66036eef93142f747dd42406b49e2ee301dL47-R50) [[4]](diffhunk://#diff-ca43b5fe493a373d174223fe3547b0c58250493f79b5c95b1981b8c286d82c75L16-R16) [[5]](diffhunk://#diff-ca43b5fe493a373d174223fe3547b0c58250493f79b5c95b1981b8c286d82c75L49) [[6]](diffhunk://#diff-5524ccff0723a609f11dc709f077a3813e2a34d4533a7fca4b6b891a8408bd94L52-R52) [[7]](diffhunk://#diff-8e68f308a036639d8ef3c8d27b1d42015f92db971daba5e31fc26fd9acff1e40L190-R190) [[8]](diffhunk://#diff-e9c600dcc202ad9d737c0c1084beb09567317bf0b01fe089c212d36c602704afL32-R33) [[9]](diffhunk://#diff-e9c600dcc202ad9d737c0c1084beb09567317bf0b01fe089c212d36c602704afL47-R47) [[10]](diffhunk://#diff-2cf88c17b45aaab80a3a46e62ee7e698ad0a621a513f96e8c5283467eada8e43L88-R89) [[11]](diffhunk://#diff-c824d5e43b627b233c542eac5d32e3d436d356cd1b00fa93c89724de403f6cd4L35-R42) [[12]](diffhunk://#diff-c824d5e43b627b233c542eac5d32e3d436d356cd1b00fa93c89724de403f6cd4L74-R74) [[13]](diffhunk://#diff-f64e54e408e0f27c25e219f69f3f632f7efc4f70023e48716cb71aca45662392L39-R43) [[14]](diffhunk://#diff-96b15a28ce488fdb6264a757c5e03585c8032ca9f92b2a852bf1e3b0e40bb6f0R5) [[15]](diffhunk://#diff-96b15a28ce488fdb6264a757c5e03585c8032ca9f92b2a852bf1e3b0e40bb6f0L54-R55) [[16]](diffhunk://#diff-a3fbb7e77fc266ed86ac6d96d669c727b8d1c328c30d1db10b48c44c66a8094aL8-R8) [[17]](diffhunk://#diff-a3fbb7e77fc266ed86ac6d96d669c727b8d1c328c30d1db10b48c44c66a8094aL121-R120) [[18]](diffhunk://#diff-ffabb94a8f5f7a9e75419de83bfa5ef14f7a632dd612b0f19e245cf418bf022aL13-R13) **Summary of Most Important Changes:** **Build System & CI Modernization** - Migrated to CMake 3.25+ with modern target-based configuration, introduced `CMakePresets.json` for easier builds and tests, and improved compiler warning management. [[1]](diffhunk://#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aL1-R12) [[2]](diffhunk://#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR36-R43) [[3]](diffhunk://#diff-1712b235e02bd4a3ad866fe26447a6dc5c1b449faeea513f449d244d46d03cf5R1-R107) - Updated GitHub Actions workflow to separate formatting and build/test jobs, enforce code formatting with `clang-format`, and use CMake presets for CI. - Removed legacy shell script `scripts/run_tests.sh` in favor of CMake-based workflows. **Code Quality Tooling** - Enhanced `.clang-tidy` configuration: fine-tuned enabled/disabled checks, set key warnings as errors, and added header filtering for focused analysis. - Improved CMake integration for `clang-format` and `clang-tidy` targets, ensuring correct file selection and command usage. [[1]](diffhunk://#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aL60-R97) [[2]](diffhunk://#diff-1e7de1ae2d059d21e1dd75d5812d5a34b0222cef273b7c3a2af62eb747f9d20aR118-R133) - Updated VSCode settings for better YAML support and improved documentation with requirements and code quality instructions. [[1]](diffhunk://#diff-a5de3e5871ffcc383a2294845bd3df25d3eeff6c29ad46e3a396577c413bf357L7-R11) [[2]](diffhunk://#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R6-R55) **Codebase Improvements** - Applied modern C++ best practices: added `[[nodiscard]]`, improved initialization, standardized output, and fixed minor code issues for clarity and correctness across multiple files. [[1]](diffhunk://#diff-035b7389279440bf3472b6a9ab837486652786563c0bcb30e6c466af3d972ed0L29-R29) [[2]](diffhunk://#diff-035b7389279440bf3472b6a9ab837486652786563c0bcb30e6c466af3d972ed0L44-R44) [[3]](diffhunk://#diff-0b5eede64af7e5fa987b28c15c62d66036eef93142f747dd42406b49e2ee301dL47-R50) [[4]](diffhunk://#diff-ca43b5fe493a373d174223fe3547b0c58250493f79b5c95b1981b8c286d82c75L16-R16) [[5]](diffhunk://#diff-ca43b5fe493a373d174223fe3547b0c58250493f79b5c95b1981b8c286d82c75L49) [[6]](diffhunk://#diff-5524ccff0723a609f11dc709f077a3813e2a34d4533a7fca4b6b891a8408bd94L52-R52) [[7]](diffhunk://#diff-8e68f308a036639d8ef3c8d27b1d42015f92db971daba5e31fc26fd9acff1e40L190-R190) [[8]](diffhunk://#diff-e9c600dcc202ad9d737c0c1084beb09567317bf0b01fe089c212d36c602704afL32-R33) [[9]](diffhunk://#diff-e9c600dcc202ad9d737c0c1084beb09567317bf0b01fe089c212d36c602704afL47-R47) [[10]](diffhunk://#diff-2cf88c17b45aaab80a3a46e62ee7e698ad0a621a513f96e8c5283467eada8e43L88-R89) [[11]](diffhunk://#diff-c824d5e43b627b233c542eac5d32e3d436d356cd1b00fa93c89724de403f6cd4L35-R42) [[12]](diffhunk://#diff-c824d5e43b627b233c542eac5d32e3d436d356cd1b00fa93c89724de403f6cd4L74-R74) [[13]](diffhunk://#diff-f64e54e408e0f27c25e219f69f3f632f7efc4f70023e48716cb71aca45662392L39-R43) [[14]](diffhunk://#diff-96b15a28ce488fdb6264a757c5e03585c8032ca9f92b2a852bf1e3b0e40bb6f0R5) [[15]](diffhunk://#diff-96b15a28ce488fdb6264a757c5e03585c8032ca9f92b2a852bf1e3b0e40bb6f0L54-R55) [[16]](diffhunk://#diff-a3fbb7e77fc266ed86ac6d96d669c727b8d1c328c30d1db10b48c44c66a8094aL8-R8) [[17]](diffhunk://#diff-a3fbb7e77fc266ed86ac6d96d669c727b8d1c328c30d1db10b48c44c66a8094aL121-R120) [[18]](diffhunk://#diff-ffabb94a8f5f7a9e75419de83bfa5ef14f7a632dd612b0f19e245cf418bf022aL13-R13)
1 parent 85247b3 commit ce8936e

27 files changed

+366
-134
lines changed

.clang-format

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
BasedOnStyle: Google
22
IndentWidth: 2
3-
TabWidth: 3
3+
TabWidth: 2
44
ColumnLimit: 100
5+
RequiresClausePosition: OwnLine
6+
RequiresExpressionIndentation: OuterScope
7+
SpacesInContainerLiterals: true

.clang-tidy

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,45 @@
11
Checks: >
22
-*,
33
bugprone-*,
4-
modernize-*,
5-
readability-*,
6-
cppcoreguidelines-*,
7-
performance-*,
84
clang-analyzer-*,
9-
cert-*,
105
misc-*,
11-
google-*,
12-
llvm-*,
13-
hicpp-*
6+
modernize-*,
7+
performance-*,
8+
readability-const-return-type,
9+
readability-container-size-empty,
10+
readability-make-member-function-const,
11+
readability-redundant-member-init,
12+
readability-redundant-smartptr-get,
13+
readability-redundant-string-cstr,
14+
readability-simplify-boolean-expr,
15+
readability-static-accessed-through-instance,
16+
readability-string-compare,
17+
cppcoreguidelines-init-variables,
18+
cppcoreguidelines-prefer-member-initializer,
19+
cppcoreguidelines-slicing,
20+
-bugprone-easily-swappable-parameters,
21+
-misc-const-correctness,
22+
-misc-include-cleaner,
23+
-misc-no-recursion,
24+
-misc-non-private-member-variables-in-classes,
25+
-misc-unused-parameters,
26+
-misc-use-anonymous-namespace,
27+
-misc-definitions-in-headers,
28+
-misc-use-internal-linkage,
29+
-modernize-use-trailing-return-type
30+
31+
WarningsAsErrors: >
32+
bugprone-use-after-move,
33+
bugprone-dangling-handle
34+
35+
HeaderFilterRegex: 'src/.*\.(hpp|h)$'
36+
37+
FormatStyle: file
1438

1539
CheckOptions:
1640
- key: modernize-use-nullptr.NullMacros
17-
value: 'Google'
18-
- key: modernize-use-override.IgnoreDestructors
19-
value: true
41+
value: 'NULL'
42+
- key: performance-move-const-arg.CheckTriviallyCopyableMove
43+
value: 'false'
44+
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
45+
value: 'true'

.github/workflows/cpp-ci.yml

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,47 @@ name: C++ CI
22

33
on:
44
push:
5-
branches: [ "main" ]
5+
branches: ["main"]
66
pull_request:
7-
branches: [ "main" ]
7+
branches: ["main"]
88

99
jobs:
10-
build_and_test:
11-
runs-on: ubuntu-latest
10+
format-check:
11+
name: Format Check
12+
runs-on: ubuntu-24.04
1213
steps:
1314
- name: Check out repository
14-
uses: actions/checkout@v4
15-
- name: Install Dependencies
15+
uses: actions/checkout@v6
16+
17+
- name: Check format
18+
run: |
19+
clang-format --version
20+
find src tests \( -name "*.hpp" -o -name "*.cpp" -o -name "*.h" \) | \
21+
xargs clang-format --dry-run --Werror
22+
23+
build-and-test:
24+
name: Build and Test
25+
runs-on: ubuntu-24.04
26+
needs: format-check
27+
steps:
28+
- name: Check out repository
29+
uses: actions/checkout@v6
30+
31+
- name: Install dependencies
1632
run: |
1733
sudo apt-get update
18-
sudo apt-get install -y cmake build-essential libgtest-dev
19-
- name: Build and run tests
34+
sudo apt-get install -y libgtest-dev
35+
36+
- name: Show tool versions
2037
run: |
21-
chmod +x ./scripts/run_tests.sh
22-
./scripts/run_tests.sh
38+
cmake --version
39+
g++ --version
40+
41+
- name: Configure
42+
run: cmake --preset ci
43+
44+
- name: Build
45+
run: cmake --build --preset ci
46+
47+
- name: Test
48+
run: ctest --preset ci

.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@
44
"C_Cpp.default.includePath": [
55
"${workspaceFolder}/src"
66
],
7-
"C_Cpp.default.intelliSenseMode": "clang-x64"
7+
"C_Cpp.default.intelliSenseMode": "clang-x64",
8+
"files.associations": {
9+
".clang-tidy": "yaml",
10+
".clang-format": "yaml"
11+
}
812
}

CMakeLists.txt

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
1-
cmake_minimum_required(VERSION 3.10)
1+
cmake_minimum_required(VERSION 3.25)
22

33
project(CLAVIS LANGUAGES CXX)
4-
set(CMAKE_CXX_STANDARD 20)
5-
set(CMAKE_CXX_STANDARD_REQUIRED True)
64

75
# Set build type (default is Debug)
86
if(NOT CMAKE_BUILD_TYPE)
97
set(CMAKE_BUILD_TYPE Debug)
108
endif()
119

12-
# Basic compiler flags
13-
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
14-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
15-
endif()
16-
17-
# Collect source files
10+
# NOTE: file(GLOB) is not recommended by CMake official docs.
11+
# Consider listing source files explicitly for reliable rebuilds.
12+
# See: https://cmake.org/cmake/help/latest/command/file.html#glob
1813
file(GLOB CORE_SOURCES
1914
src/*.cpp
2015
src/graph/*.hpp
@@ -38,6 +33,14 @@ set(SOURCES ${CORE_SOURCES})
3833
# Create library
3934
add_library(clavis_algorithm ${SOURCES})
4035

36+
# Set C++ standard (modern target-based approach)
37+
target_compile_features(clavis_algorithm PUBLIC cxx_std_20)
38+
39+
# Set compiler warnings (target-based, not global CMAKE_CXX_FLAGS)
40+
target_compile_options(clavis_algorithm PRIVATE
41+
$<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-Wall -Wextra>
42+
)
43+
4144
# Set include directories
4245
target_include_directories(clavis_algorithm PUBLIC
4346
${CMAKE_SOURCE_DIR}/src
@@ -57,26 +60,41 @@ target_include_directories(clavis_algorithm_test PRIVATE
5760

5861
target_link_libraries(clavis_algorithm_test clavis_algorithm GTest::GTest GTest::Main)
5962

60-
# Register test
61-
add_test(NAME AlgorithmTest COMMAND clavis_algorithm_test)
63+
# Set compiler warnings for tests
64+
target_compile_options(clavis_algorithm_test PRIVATE
65+
$<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-Wall -Wextra>
66+
)
67+
68+
# Discover and register tests
69+
include(GoogleTest)
70+
gtest_discover_tests(clavis_algorithm_test)
6271

6372
# =============================================================================
6473
# Code Quality Tools
6574
# =============================================================================
6675

67-
# Collect all C++ files for formatting/linting
76+
# Collect all C++ files for formatting
6877
file(GLOB_RECURSE ALL_CXX_FILES
6978
${CMAKE_SOURCE_DIR}/src/*.hpp
7079
${CMAKE_SOURCE_DIR}/src/*.cpp
7180
${CMAKE_SOURCE_DIR}/src/*.h
7281
${CMAKE_SOURCE_DIR}/tests/*.cpp
7382
)
7483

84+
# Collect source files only for linting (exclude tests)
85+
file(GLOB_RECURSE SRC_CXX_FILES
86+
${CMAKE_SOURCE_DIR}/src/*.hpp
87+
${CMAKE_SOURCE_DIR}/src/*.cpp
88+
${CMAKE_SOURCE_DIR}/src/*.h
89+
)
90+
7591
# clang-format targets
7692
find_program(CLANG_FORMAT clang-format
7793
HINTS
94+
$ENV{LLVM_DIR}/bin
7895
/opt/homebrew/opt/llvm/bin
7996
/usr/local/opt/llvm/bin
97+
/usr/bin
8098
)
8199
if(CLANG_FORMAT)
82100
add_custom_target(format
@@ -97,13 +115,22 @@ endif()
97115
# clang-tidy target
98116
find_program(CLANG_TIDY clang-tidy
99117
HINTS
118+
$ENV{LLVM_DIR}/bin
100119
/opt/homebrew/opt/llvm/bin
101120
/usr/local/opt/llvm/bin
121+
/usr/bin
102122
)
103123
if(CLANG_TIDY)
104124
add_custom_target(lint
105-
COMMAND ${CLANG_TIDY} -p ${CMAKE_BINARY_DIR} ${ALL_CXX_FILES}
106-
COMMENT "Running clang-tidy"
125+
COMMAND ${CLANG_TIDY}
126+
-p ${CMAKE_BINARY_DIR}
127+
-header-filter=${CMAKE_SOURCE_DIR}/src/.*
128+
${SRC_CXX_FILES}
129+
--
130+
-x c++
131+
-std=c++20
132+
-I${CMAKE_SOURCE_DIR}/src
133+
COMMENT "Running clang-tidy on source files"
107134
VERBATIM
108135
)
109136
else()

CMakePresets.json

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{
2+
"$schema": "https://cmake.org/cmake/help/latest/_downloads/3e2d73bff478d88a7de0de736ba5e361/schema.json",
3+
"version": 8,
4+
"cmakeMinimumRequired": {
5+
"major": 3,
6+
"minor": 25,
7+
"patch": 0
8+
},
9+
"configurePresets": [
10+
{
11+
"name": "base",
12+
"hidden": true,
13+
"generator": "Ninja",
14+
"binaryDir": "${sourceDir}/build/${presetName}",
15+
"cacheVariables": {
16+
"CMAKE_CXX_STANDARD": "20",
17+
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
18+
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
19+
}
20+
},
21+
{
22+
"name": "debug",
23+
"displayName": "Debug",
24+
"inherits": "base",
25+
"cacheVariables": {
26+
"CMAKE_BUILD_TYPE": "Debug"
27+
}
28+
},
29+
{
30+
"name": "release",
31+
"displayName": "Release",
32+
"inherits": "base",
33+
"cacheVariables": {
34+
"CMAKE_BUILD_TYPE": "Release"
35+
}
36+
},
37+
{
38+
"name": "ci",
39+
"displayName": "CI",
40+
"inherits": "base",
41+
"generator": "Unix Makefiles",
42+
"binaryDir": "${sourceDir}/build",
43+
"cacheVariables": {
44+
"CMAKE_BUILD_TYPE": "Debug"
45+
}
46+
}
47+
],
48+
"buildPresets": [
49+
{
50+
"name": "debug",
51+
"configurePreset": "debug"
52+
},
53+
{
54+
"name": "release",
55+
"configurePreset": "release"
56+
},
57+
{
58+
"name": "ci",
59+
"configurePreset": "ci",
60+
"jobs": 4
61+
}
62+
],
63+
"testPresets": [
64+
{
65+
"name": "base",
66+
"hidden": true,
67+
"output": {
68+
"outputOnFailure": true,
69+
"verbosity": "default"
70+
},
71+
"execution": {
72+
"noTestsAction": "error",
73+
"stopOnFailure": false
74+
}
75+
},
76+
{
77+
"name": "debug",
78+
"configurePreset": "debug",
79+
"inherits": "base"
80+
},
81+
{
82+
"name": "release",
83+
"configurePreset": "release",
84+
"inherits": "base"
85+
},
86+
{
87+
"name": "ci",
88+
"configurePreset": "ci",
89+
"inherits": "base",
90+
"output": {
91+
"outputOnFailure": true,
92+
"verbosity": "verbose"
93+
}
94+
}
95+
],
96+
"workflowPresets": [
97+
{
98+
"name": "ci",
99+
"displayName": "CI Workflow",
100+
"steps": [
101+
{ "type": "configure", "name": "ci" },
102+
{ "type": "build", "name": "ci" },
103+
{ "type": "test", "name": "ci" }
104+
]
105+
}
106+
]
107+
}

0 commit comments

Comments
 (0)