Skip to content

Commit 5def127

Browse files
committed
clang tidy added
1 parent b866606 commit 5def127

3 files changed

Lines changed: 220 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,42 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp")
728728
add_executable(main src/main.cpp)
729729
endif()
730730

731+
message("\n########################################## clang-format ##########################################\n")
732+
find_program(CLANG_FORMAT_EXECUTABLE NAMES clang-format clang-format-18 clang-format-17 clang-format-16 clang-format-15)
733+
if(CLANG_FORMAT_EXECUTABLE)
734+
execute_process(
735+
COMMAND ${CLANG_FORMAT_EXECUTABLE} --version
736+
OUTPUT_VARIABLE CLANG_FORMAT_VERSION
737+
OUTPUT_STRIP_TRAILING_WHITESPACE
738+
)
739+
message(STATUS "clang-format found: ${CLANG_FORMAT_EXECUTABLE}")
740+
message(STATUS "clang-format version: ${CLANG_FORMAT_VERSION}")
741+
else()
742+
message(WARNING "clang-format is not installed. Install it to enable format-on-save in VS Code.\n"
743+
" Ubuntu/Debian: sudo apt install clang-format\n"
744+
" macOS: brew install clang-format\n"
745+
" Windows: choco install llvm (or install LLVM from https://releases.llvm.org)")
746+
endif()
747+
748+
749+
message("\n########################################## clang-tidy ##########################################\n")
750+
find_program(CLANG_TIDY_EXECUTABLE NAMES clang-tidy clang-tidy-18 clang-tidy-17 clang-tidy-16 clang-tidy-15)
751+
if(CLANG_TIDY_EXECUTABLE)
752+
execute_process(
753+
COMMAND ${CLANG_TIDY_EXECUTABLE} --version
754+
OUTPUT_VARIABLE CLANG_TIDY_VERSION
755+
OUTPUT_STRIP_TRAILING_WHITESPACE
756+
)
757+
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXECUTABLE}")
758+
message(STATUS "clang-tidy version:\n${CLANG_TIDY_VERSION}")
759+
else()
760+
message(WARNING "clang-tidy is not installed. Install it to enable static analysis / linting.\n"
761+
" Ubuntu/Debian: sudo apt install clang-tidy\n"
762+
" macOS: brew install llvm (clang-tidy ships with LLVM)\n"
763+
" Windows: choco install llvm (or install LLVM from https://releases.llvm.org)")
764+
endif()
765+
766+
731767
message("\n########################################## System Design ##########################################\n")
732768

733769
add_executable(reusable_library src/reusable_library.cpp)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ This change ensures that VSCode uses the "Ninja Multi-Config" generator by defau
388388
- [Goolge C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
389389
- [isocpp](https://isocpp.org/wiki/faq/coding-standards)
390390
- [Bjarne Stroustrup's C++ Style](https://www.stroustrup.com/bs_faq2.html)
391+
- [Static analysis and linting with clang-tidy](docs/clang_tidy.md)
391392

392393
## [C++ System Design](#)
393394

docs/clang_tidy.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# clang-tidy
2+
3+
`clang-tidy` is a static analyzer / linter for C and C++ that ships with LLVM. It reads your code without running it and flags problems — many of which it can also auto-fix.
4+
5+
It is **not** the same as `clang-format`:
6+
7+
| | clang-format | clang-tidy |
8+
|---|---|---|
9+
| Touches | Whitespace, line breaks, indentation | Code logic, names, idioms |
10+
| Speed | Instant | Slower (semantic analysis) |
11+
| Needs build info? | No | Yes (`compile_commands.json`) |
12+
| Auto-fix | Always | Often (with `-fix`) |
13+
14+
## Installation
15+
16+
**Ubuntu / Debian**
17+
```
18+
sudo apt install clang-tidy
19+
```
20+
21+
**macOS**
22+
```
23+
brew install llvm
24+
```
25+
26+
**Windows**
27+
```
28+
choco install llvm
29+
```
30+
or download LLVM from https://releases.llvm.org
31+
32+
Verify:
33+
```
34+
clang-tidy --version
35+
```
36+
37+
## What it catches
38+
39+
Checks are grouped into categories. A few examples from each:
40+
41+
| Category | Check | What it catches |
42+
|---|---|---|
43+
| `bugprone-*` | `bugprone-use-after-move` | Using a variable after `std::move` |
44+
| `modernize-*` | `modernize-use-nullptr` | Replaces `NULL` / `0` with `nullptr` |
45+
| `modernize-*` | `modernize-use-auto` | `std::vector<int>::iterator it``auto it` |
46+
| `modernize-*` | `modernize-loop-convert` | Index `for` loops → range-for |
47+
| `performance-*` | `performance-unnecessary-copy-initialization` | `auto x = vec[0];` when `const auto&` suffices |
48+
| `performance-*` | `performance-for-range-copy` | `for (auto x : container)` should be `const auto&` |
49+
| `readability-*` | `readability-identifier-naming` | Enforce `snake_case` / `CamelCase` |
50+
| `cppcoreguidelines-*` | `cppcoreguidelines-pro-type-member-init` | Uninitialized members |
51+
| `cert-*` | `cert-err58-cpp` | CERT secure coding violations |
52+
| `clang-analyzer-*` | path-sensitive analysis | Null derefs, leaks, use-after-free |
53+
54+
Full list: https://clang.llvm.org/extra/clang-tidy/checks/list.html
55+
56+
## Generate `compile_commands.json`
57+
58+
clang-tidy needs to know each file's include paths, defines, and C++ standard. CMake produces this automatically:
59+
60+
```cmake
61+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
62+
```
63+
64+
After configuring, the file appears in your build directory. Symlink it to the project root so clang-tidy finds it:
65+
66+
```
67+
ln -s build/compile_commands.json compile_commands.json
68+
```
69+
70+
## Running clang-tidy
71+
72+
**One file**
73+
```
74+
clang-tidy src/main.cpp
75+
```
76+
77+
**Pick specific checks**
78+
```
79+
clang-tidy --checks='-*,modernize-*,performance-*,bugprone-*' src/main.cpp
80+
```
81+
82+
**Apply suggested fixes**
83+
```
84+
clang-tidy -fix src/main.cpp
85+
```
86+
87+
**Run on every file in a directory**
88+
```
89+
find src -name '*.cpp' | xargs clang-tidy
90+
```
91+
92+
## `.clang-tidy` config file
93+
94+
Place a `.clang-tidy` file at the project root to make checks consistent across the team:
95+
96+
```yaml
97+
Checks: >
98+
-*,
99+
bugprone-*,
100+
modernize-*,
101+
performance-*,
102+
readability-*,
103+
cppcoreguidelines-*,
104+
-modernize-use-trailing-return-type,
105+
-readability-identifier-length
106+
107+
WarningsAsErrors: ''
108+
HeaderFilterRegex: '.*'
109+
FormatStyle: file
110+
```
111+
112+
- `Checks` — comma-separated list. `-*` disables all, then re-enables groups. Prefix a check with `-` to silence it.
113+
- `WarningsAsErrors` — set to the same expression to fail builds on warnings.
114+
- `HeaderFilterRegex` — which headers to analyze (default skips system headers).
115+
- `FormatStyle: file` — apply `clang-format` to fix-ups using your `.clang-format`.
116+
117+
## Run via CMake on every build
118+
119+
Add to `CMakeLists.txt`:
120+
121+
```cmake
122+
set(CMAKE_CXX_CLANG_TIDY clang-tidy)
123+
```
124+
125+
Now every translation unit is linted as it compiles. Combine with the detection block already in this project's CMake:
126+
127+
```cmake
128+
find_program(CLANG_TIDY_EXECUTABLE NAMES clang-tidy)
129+
if(CLANG_TIDY_EXECUTABLE)
130+
set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_EXECUTABLE})
131+
endif()
132+
```
133+
134+
## VS Code integration
135+
136+
The **clangd** extension (`llvm-vs-code-extensions.vscode-clangd`) runs clang-tidy diagnostics inline as you type. With clangd installed:
137+
138+
```json
139+
{
140+
"clangd.arguments": [
141+
"--clang-tidy",
142+
"--compile-commands-dir=build"
143+
]
144+
}
145+
```
146+
147+
The C/C++ extension (`ms-vscode.cpptools`) also has built-in clang-tidy support — enable `C_Cpp.codeAnalysis.clangTidy.enabled` in settings.
148+
149+
## CI integration
150+
151+
Run on changed files only in pull requests:
152+
153+
```
154+
git diff --name-only origin/master...HEAD | grep -E '\.(cpp|h|hpp)$' | xargs clang-tidy -p build
155+
```
156+
157+
Fail the job if any warnings appear:
158+
159+
```
160+
clang-tidy --warnings-as-errors='*' -p build src/main.cpp
161+
```
162+
163+
## Common gotchas
164+
165+
- **"unable to find compile_commands.json"** — pass `-p path/to/build` or symlink it to project root.
166+
- **Slow runs** — clang-tidy reparses each TU; on large projects use `run-clang-tidy.py` (ships with LLVM) for parallel execution.
167+
- **Fix conflicts** — when two checks suggest overlapping edits, run clang-tidy multiple times until output is stable.
168+
- **Generated / third-party code** — exclude with `HeaderFilterRegex` or wrap in `// NOLINT` / `// NOLINTNEXTLINE` comments.
169+
170+
## Suppressing a single warning
171+
172+
```cpp
173+
int x; // NOLINT(cppcoreguidelines-init-variables)
174+
175+
// NOLINTNEXTLINE(modernize-use-nullptr)
176+
foo(0);
177+
```
178+
179+
## References
180+
181+
- Official docs: https://clang.llvm.org/extra/clang-tidy/
182+
- Check list: https://clang.llvm.org/extra/clang-tidy/checks/list.html
183+
- `run-clang-tidy.py`: https://github.com/llvm/llvm-project/blob/main/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py

0 commit comments

Comments
 (0)