Skip to content

Commit 4758095

Browse files
committed
build: add clang-tidy configuration and tooling for code quality analysis
- Add comprehensive .clang-tidy configuration tailored for legacy C++98/C++20 hybrid codebase - Add Python helper script for running clang-tidy with project-specific filtering - Update TESTING.md with clang-tidy usage documentation and examples - Support MinGW-w64 cross-compilation environment and ReactOS ATL compatibility - CMAKE_EXPORT_COMPILE_COMMANDS already enabled in existing presets
1 parent d61ce1f commit 4758095

File tree

3 files changed

+533
-2
lines changed

3 files changed

+533
-2
lines changed

.clang-tidy

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
# TheSuperHackers @build JohnsterID 15/09/2025 Add clang-tidy configuration for code quality analysis
2+
---
3+
# Clang-tidy configuration for GeneralsGameCode project
4+
# This configuration is tailored for a legacy C++98/C++20 hybrid codebase
5+
# with Windows-specific code and COM interfaces
6+
7+
# Enable specific checks that are appropriate for this codebase
8+
Checks: >
9+
-*,
10+
bugprone-*,
11+
-bugprone-easily-swappable-parameters,
12+
-bugprone-implicit-widening-of-multiplication-result,
13+
-bugprone-narrowing-conversions,
14+
-bugprone-signed-char-misuse,
15+
cert-*,
16+
-cert-dcl21-cpp,
17+
-cert-dcl50-cpp,
18+
-cert-dcl58-cpp,
19+
-cert-env33-c,
20+
-cert-err58-cpp,
21+
clang-analyzer-*,
22+
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
23+
cppcoreguidelines-*,
24+
-cppcoreguidelines-avoid-c-arrays,
25+
-cppcoreguidelines-avoid-magic-numbers,
26+
-cppcoreguidelines-avoid-non-const-global-variables,
27+
-cppcoreguidelines-init-variables,
28+
-cppcoreguidelines-macro-usage,
29+
-cppcoreguidelines-no-malloc,
30+
-cppcoreguidelines-owning-memory,
31+
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
32+
-cppcoreguidelines-pro-bounds-constant-array-index,
33+
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
34+
-cppcoreguidelines-pro-type-cstyle-cast,
35+
-cppcoreguidelines-pro-type-reinterpret-cast,
36+
-cppcoreguidelines-pro-type-union-access,
37+
-cppcoreguidelines-pro-type-vararg,
38+
-cppcoreguidelines-special-member-functions,
39+
google-*,
40+
-google-build-using-namespace,
41+
-google-explicit-constructor,
42+
-google-readability-casting,
43+
-google-readability-todo,
44+
-google-runtime-int,
45+
-google-runtime-references,
46+
hicpp-*,
47+
-hicpp-avoid-c-arrays,
48+
-hicpp-explicit-conversions,
49+
-hicpp-no-array-decay,
50+
-hicpp-signed-bitwise,
51+
-hicpp-special-member-functions,
52+
-hicpp-uppercase-literal-suffix,
53+
-hicpp-use-auto,
54+
-hicpp-vararg,
55+
misc-*,
56+
-misc-const-correctness,
57+
-misc-include-cleaner,
58+
-misc-non-private-member-variables-in-classes,
59+
-misc-use-anonymous-namespace,
60+
modernize-*,
61+
-modernize-avoid-c-arrays,
62+
-modernize-concat-nested-namespaces,
63+
-modernize-loop-convert,
64+
-modernize-pass-by-value,
65+
-modernize-raw-string-literal,
66+
-modernize-return-braced-init-list,
67+
-modernize-use-auto,
68+
-modernize-use-default-member-init,
69+
-modernize-use-nodiscard,
70+
-modernize-use-trailing-return-type,
71+
performance-*,
72+
-performance-avoid-endl,
73+
portability-*,
74+
readability-*,
75+
-readability-avoid-const-params-in-decls,
76+
-readability-braces-around-statements,
77+
-readability-convert-member-functions-to-static,
78+
-readability-function-cognitive-complexity,
79+
-readability-identifier-length,
80+
-readability-implicit-bool-conversion,
81+
-readability-isolate-declaration,
82+
-readability-magic-numbers,
83+
-readability-named-parameter,
84+
-readability-redundant-access-specifiers,
85+
-readability-uppercase-literal-suffix
86+
87+
# Treat warnings as errors for CI/CD
88+
WarningsAsErrors: false
89+
90+
# Header filter to include project headers
91+
HeaderFilterRegex: '(Core|Generals|GeneralsMD|Dependencies)/.*\.(h|hpp)$'
92+
93+
# Analysis options
94+
AnalyzeTemporaryDtors: false
95+
96+
# Check options for specific rules
97+
CheckOptions:
98+
# Naming conventions - adapted for the existing codebase style
99+
- key: readability-identifier-naming.ClassCase
100+
value: CamelCase
101+
- key: readability-identifier-naming.StructCase
102+
value: CamelCase
103+
- key: readability-identifier-naming.FunctionCase
104+
value: CamelCase
105+
- key: readability-identifier-naming.MethodCase
106+
value: CamelCase
107+
- key: readability-identifier-naming.VariableCase
108+
value: lower_case
109+
- key: readability-identifier-naming.ParameterCase
110+
value: lower_case
111+
- key: readability-identifier-naming.MemberCase
112+
value: lower_case
113+
- key: readability-identifier-naming.MemberPrefix
114+
value: m_
115+
- key: readability-identifier-naming.ConstantCase
116+
value: UPPER_CASE
117+
- key: readability-identifier-naming.EnumConstantCase
118+
value: UPPER_CASE
119+
- key: readability-identifier-naming.MacroDefinitionCase
120+
value: UPPER_CASE
121+
122+
# Performance settings
123+
- key: performance-for-range-copy.WarnOnAllAutoCopies
124+
value: true
125+
- key: performance-unnecessary-value-param.AllowedTypes
126+
value: 'AsciiString;UnicodeString;Utf8String;Utf16String'
127+
128+
# Modernize settings - be conservative for legacy code
129+
- key: modernize-use-nullptr.NullMacros
130+
value: 'NULL'
131+
- key: modernize-replace-auto-ptr.IncludeStyle
132+
value: llvm
133+
134+
# Readability settings
135+
- key: readability-function-size.LineThreshold
136+
value: 150
137+
- key: readability-function-size.StatementThreshold
138+
value: 100
139+
- key: readability-function-size.BranchThreshold
140+
value: 25
141+
- key: readability-function-size.ParameterThreshold
142+
value: 8
143+
- key: readability-function-size.NestingThreshold
144+
value: 6
145+
146+
# Bugprone settings
147+
- key: bugprone-argument-comment.StrictMode
148+
value: false
149+
- key: bugprone-suspicious-string-compare.WarnOnImplicitComparison
150+
value: true
151+
- key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison
152+
value: true
153+
154+
# Google style settings
155+
- key: google-readability-braces-around-statements.ShortStatementLines
156+
value: 2
157+
- key: google-readability-function-size.StatementThreshold
158+
value: 100
159+
160+
# CERT settings
161+
- key: cert-dcl16-c.NewSuffixes
162+
value: 'L;LL;LU;LLU'
163+
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
164+
value: false
165+
166+
# Use .clang-format for formatting suggestions
167+
FormatStyle: file
168+
169+
# Exclude certain directories and files
170+
# Note: This is handled by HeaderFilterRegex above, but can be extended

TESTING.md

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# Test Replays
1+
# Testing
2+
3+
## Test Replays
24

35
The GeneralsReplays folder contains replays and the required maps that are tested in CI to ensure that the game is retail compatible.
46

@@ -11,4 +13,102 @@ START /B /W generalszh.exe -jobs 4 -headless -replay subfolder/*.rep > replay_ch
1113
echo %errorlevel%
1214
PAUSE
1315
```
14-
It will run the game in the background and check that each replay is compatible. You need to use a VC6 build with optimizations and RTS_BUILD_OPTION_DEBUG = OFF, otherwise the game won't be compatible.
16+
It will run the game in the background and check that each replay is compatible. You need to use a VC6 build with optimizations and RTS_BUILD_OPTION_DEBUG = OFF, otherwise the game won't be compatible.
17+
18+
## Code Quality Analysis with clang-tidy
19+
20+
The project includes clang-tidy configuration for static code analysis to help maintain code quality and catch potential bugs.
21+
22+
### Prerequisites
23+
24+
1. **CMake with compile commands export**: The CMake presets already have `CMAKE_EXPORT_COMPILE_COMMANDS=ON` configured.
25+
2. **clang-tidy**: Install clang-tidy for your platform:
26+
- **Linux**: `apt install clang-tidy` or `yum install clang-tools-extra`
27+
- **Windows**: Install LLVM or use the version that comes with Visual Studio
28+
- **macOS**: `brew install llvm` or use Xcode command line tools
29+
30+
### Running clang-tidy
31+
32+
#### Method 1: Using the helper script (Recommended)
33+
34+
The project includes a Python script that simplifies running clang-tidy:
35+
36+
```bash
37+
# Analyze all source files
38+
python3 scripts/run-clang-tidy.py
39+
40+
# Analyze only Core directory
41+
python3 scripts/run-clang-tidy.py --include Core/
42+
43+
# Analyze GeneralsMD but exclude certain patterns
44+
python3 scripts/run-clang-tidy.py --include GeneralsMD/ --exclude test
45+
46+
# Use specific build directory
47+
python3 scripts/run-clang-tidy.py --build-dir build/win32
48+
49+
# Apply fixes automatically (use with caution!)
50+
python3 scripts/run-clang-tidy.py --fix --include Core/Libraries/
51+
```
52+
53+
#### Method 2: Direct clang-tidy usage
54+
55+
First, ensure you have a `compile_commands.json` file:
56+
57+
```bash
58+
# Configure with any preset that exports compile commands
59+
cmake --preset win32 # or vc6, unix, etc.
60+
61+
# Run clang-tidy on specific files
62+
clang-tidy -p build/win32 Core/Libraries/Source/RTS/File.cpp
63+
64+
# Run on multiple files with pattern
65+
find Core/ -name "*.cpp" | xargs clang-tidy -p build/win32
66+
```
67+
68+
### Configuration
69+
70+
The `.clang-tidy` file in the project root contains configuration tailored for this legacy C++ codebase:
71+
72+
- **Enabled checks**: Focus on bug-prone patterns, performance issues, and readability
73+
- **Disabled checks**: Overly strict modernization rules that don't fit the legacy codebase
74+
- **Naming conventions**: Adapted to match the existing code style (CamelCase for classes, m_ prefix for members)
75+
- **Header filtering**: Only analyzes project headers, not system/external headers
76+
77+
### Integration with Development Workflow
78+
79+
#### For Contributors
80+
81+
Run clang-tidy on your changes before submitting PRs:
82+
83+
```bash
84+
# Analyze only files you've modified
85+
python3 scripts/run-clang-tidy.py --include "path/to/your/changes/"
86+
```
87+
88+
#### For Maintainers
89+
90+
Consider running periodic full codebase analysis:
91+
92+
```bash
93+
# Full analysis (may take a while)
94+
python3 scripts/run-clang-tidy.py > clang-tidy-report.txt 2>&1
95+
```
96+
97+
### MinGW-w64 Compatibility
98+
99+
The clang-tidy configuration is designed to work with the MinGW-w64 cross-compilation setup. The project supports:
100+
101+
- **MinGW-w64 headers**: For Windows API compatibility
102+
- **ReactOS ATL**: For COM interface support (as referenced in PR #672)
103+
- **Legacy C++98 patterns**: While encouraging modern practices where appropriate
104+
105+
### Troubleshooting
106+
107+
**Issue**: `compile_commands.json not found`
108+
**Solution**: Run cmake configuration first: `cmake --preset <preset-name>`
109+
110+
**Issue**: clang-tidy reports errors in system headers
111+
**Solution**: The configuration should filter these out, but you can also use `--system-headers=false`
112+
113+
**Issue**: Too many warnings for legacy code
114+
**Solution**: Use the `--include` flag to focus on specific directories or files you're working on

0 commit comments

Comments
 (0)