Skip to content

Commit 209b4ce

Browse files
committed
Add centralized clang-tidy infrastructure
1 parent 07a78d6 commit 209b4ce

12 files changed

Lines changed: 302 additions & 4 deletions

File tree

MODULE.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ module(
1919
bazel_dep(name = "bazel_skylib", version = "1.8.2")
2020
bazel_dep(name = "platforms", version = "0.0.10")
2121

22+
bazel_dep(name = "aspect_rules_lint", version = "1.0.3")
23+

README.md

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Centralized C++ quality tool policies for Eclipse S-CORE, providing sanitizer configurations reusable across all S-CORE modules (logging, communication, baselibs, etc.).
44

5-
Planned: clang-tidy, clang-format, code coverage policies.
5+
Planned: clang-format, code coverage policies.
66

77
## What This Provides
88

@@ -11,6 +11,9 @@ Planned: clang-tidy, clang-format, code coverage policies.
1111
- **`sanitizers/sanitizers.bazelrc`** — canonical config that consumers import or copy
1212
- **Suppression files** — per-sanitizer suppression lists for known false positives (GoogleTest, etc.)
1313
- **Constraint system**`target_compatible_with` settings for sanitizer-incompatible targets
14+
- **`//clang_tidy:defs.bzl`**`make_clang_tidy_aspect` / `make_clang_tidy_test` macros wrapping `aspect_rules_lint`
15+
- **`clang_tidy/.clang-tidy`** — default S-CORE check set (conservative baseline, tailorable per module)
16+
- **`clang_tidy/clang_tidy.bazelrc`** — canonical bazelrc snippet consumers import
1417

1518
## Available Sanitizer Configurations
1619

@@ -127,13 +130,63 @@ cc_library(
127130
| `@score_cpp_policies//sanitizers/constraints:no_asan_ubsan_lsan` | Skip when `--config=asan_ubsan_lsan` |
128131
| `@score_cpp_policies//sanitizers/constraints:any_sanitizer` | Only builds with a sanitizer enabled |
129132

133+
## Clang-Tidy Integration
134+
135+
### Add Dependency
136+
137+
```python
138+
bazel_dep(name = "score_cpp_policies", version = "0.0.0")
139+
bazel_dep(name = "toolchains_llvm", version = "1.5.0")
140+
```
141+
142+
Set up `@llvm_toolchain` via the `llvm` extension (see `tests/MODULE.bazel` for an example).
143+
144+
### Import the Bazelrc Snippet
145+
146+
In your `.bazelrc`:
147+
148+
```bazelrc
149+
import %workspace%/path/to/clang_tidy.bazelrc
150+
test:clang-tidy --aspects=//tools/lint:linters.bzl%clang_tidy_aspect
151+
```
152+
153+
### Create `tools/lint/linters.bzl`
154+
155+
```python
156+
load("@score_cpp_policies//clang_tidy:defs.bzl", "make_clang_tidy_aspect", "make_clang_tidy_test")
157+
158+
clang_tidy_aspect = make_clang_tidy_aspect(
159+
binary = Label("@llvm_toolchain//:clang-tidy"),
160+
configs = [Label("//:.clang-tidy")],
161+
)
162+
163+
clang_tidy_test = make_clang_tidy_test(aspect = clang_tidy_aspect)
164+
```
165+
166+
### Add a `.clang-tidy` Config
167+
168+
Place a `.clang-tidy` at your repo root. Use
169+
[`@score_cpp_policies//clang_tidy:.clang-tidy`](clang_tidy/.clang-tidy) as the starting point.
170+
171+
### Run
172+
173+
```bash
174+
# Lint all C++ targets
175+
bazel test --config=clang-tidy //...
176+
```
177+
178+
Reports are written to `bazel-out/.../rules_lint_report/` as text files.
179+
180+
---
181+
130182
## Testing This Repository
131183

132184
```bash
133185
cd tests
134186

135187
bazel test --config=asan_ubsan_lsan //...
136188
bazel test --config=tsan //...
189+
bazel test --config=clang-tidy //...
137190
```
138191

139192
## Contributing

clang_tidy/.clang-tidy

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
14+
---
15+
# Default clang-tidy configuration for S-CORE C++ modules.
16+
# NOTE: the set of enabled checks is yet subject to be tailored per module.
17+
Checks: >
18+
-*,
19+
clang-analyzer-*,
20+
cert-*,
21+
cppcoreguidelines-*,
22+
bugprone-*,
23+
misc-*,
24+
performance-*,
25+
readability-*,
26+
modernize-*
27+
28+
# NOTE: WarningsAsErrors is yet subject to be expanded per module as compliance increases.
29+
WarningsAsErrors: >
30+
clang-analyzer-*,
31+
32+
# Exclude third-party and generated headers from analysis.
33+
HeaderFilterRegex: '^(?!.*/third_party/).*'
34+
35+
FormatStyle: file
36+
37+
# NOTE: CheckOptions are yet subject to be provided for each enabled check per module.
38+
#CheckOptions:
39+
# none yet

clang_tidy/BUILD.bazel

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
14+
exports_files(
15+
[
16+
".clang-tidy",
17+
"clang_tidy.bazelrc",
18+
],
19+
visibility = ["//visibility:public"],
20+
)

clang_tidy/clang_tidy.bazelrc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
14+
# ==============================================================================
15+
# Centralized Clang-Tidy Configuration for S-CORE C++ Modules
16+
# ==============================================================================
17+
18+
test:clang-tidy --output_groups=+rules_lint_report
19+
test:clang-tidy --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux

clang_tidy/defs.bzl

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
14+
"""Clang-tidy support macros for S-CORE C++ modules.
15+
16+
Provides macros to create a clang-tidy aspect and test rule with S-CORE defaults.
17+
Consuming projects call make_clang_tidy_aspect() in their own linters.bzl to
18+
create a project-specific aspect bound to their toolchain and .clang-tidy config.
19+
20+
Example usage in your project's tools/lint/linters.bzl:
21+
22+
load("@score_cpp_policies//clang_tidy:defs.bzl", "make_clang_tidy_aspect", "make_clang_tidy_test")
23+
24+
clang_tidy_aspect = make_clang_tidy_aspect(
25+
binary = Label("@llvm_toolchain//:clang-tidy"),
26+
configs = [Label("//:.clang-tidy")],
27+
)
28+
29+
clang_tidy_test = make_clang_tidy_test(aspect = clang_tidy_aspect)
30+
"""
31+
32+
load("@aspect_rules_lint//lint:clang_tidy.bzl", "lint_clang_tidy_aspect")
33+
load("@aspect_rules_lint//lint:lint_test.bzl", "lint_test")
34+
35+
def make_clang_tidy_aspect(
36+
binary,
37+
configs,
38+
lint_target_headers = True,
39+
angle_includes_are_system = True,
40+
verbose = False):
41+
"""Creates a clang-tidy lint aspect with S-CORE defaults.
42+
43+
Args:
44+
binary: Label of the clang-tidy binary.
45+
Must be resolved in the calling .bzl file's repository context,
46+
e.g. Label("@llvm_toolchain//:clang-tidy").
47+
configs: List of Labels to .clang-tidy config files that clang-tidy needs
48+
as inputs, e.g. [Label("//:.clang-tidy")].
49+
lint_target_headers: Whether to lint headers owned by analyzed targets (default: True).
50+
angle_includes_are_system: Treat angle bracket includes as system headers (default: True).
51+
verbose: Enable verbose clang-tidy output (default: False).
52+
53+
Returns:
54+
A clang-tidy aspect. Assign to a top-level variable in your .bzl file
55+
so it can be referenced via --aspects= in .bazelrc.
56+
"""
57+
return lint_clang_tidy_aspect(
58+
binary = binary,
59+
configs = configs,
60+
lint_target_headers = lint_target_headers,
61+
angle_includes_are_system = angle_includes_are_system,
62+
verbose = verbose,
63+
)
64+
65+
def make_clang_tidy_test(aspect):
66+
"""Creates a clang-tidy lint test rule for per-target testing.
67+
68+
Args:
69+
aspect: The clang-tidy aspect returned by make_clang_tidy_aspect().
70+
71+
Returns:
72+
A rule that can be instantiated in BUILD files to run clang-tidy
73+
on individual cc_library / cc_binary / cc_test targets.
74+
75+
Example usage in a BUILD file:
76+
load("//tools/lint:linters.bzl", "clang_tidy_test")
77+
clang_tidy_test(name = "my_lib_tidy", srcs = [":my_lib"])
78+
"""
79+
return lint_test(aspect = aspect)

tests/.bazelrc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
# SPDX-License-Identifier: Apache-2.0
1212
# *******************************************************************************
1313

14-
# Import centralized sanitizer configurations
15-
# (includes --test_tag_filters for all configs)
14+
# Centralized sanitizer configurations
1615
import %workspace%/../sanitizers/sanitizers.bazelrc
1716

17+
# Clang-tidy: bazel test --config=clang-tidy //...
18+
test:clang-tidy --aspects=//tools/lint:linters.bzl%clang_tidy_aspect
19+
test:clang-tidy --output_groups=+rules_lint_report
20+
test:clang-tidy --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux
21+
1822
common --registry=https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/
1923
common --registry=https://bcr.bazel.build

tests/.clang-tidy

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# *******************************************************************************
2+
# Copyright (c) 2026 Contributors to the Eclipse Foundation
3+
#
4+
# See the NOTICE file(s) distributed with this work for additional
5+
# information regarding copyright ownership.
6+
#
7+
# This program and the accompanying materials are made available under the
8+
# terms of the Apache License Version 2.0 which is available at
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# SPDX-License-Identifier: Apache-2.0
12+
# *******************************************************************************
13+
14+
---
15+
# Clang-tidy configuration for the score_cpp_policies test workspace.
16+
# NOTE: conservative check set so that existing sample_test.cpp passes cleanly.
17+
Checks: >
18+
-*,
19+
clang-analyzer-*,
20+
bugprone-*
21+
22+
WarningsAsErrors: ""
23+
24+
# Exclude third-party and googletest headers from analysis.
25+
HeaderFilterRegex: '^(?!.*/third_party/)(?!.*/googletest/).*'
26+
27+
FormatStyle: file

tests/BUILD.bazel

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313

1414
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
1515

16+
# Required as input to the clang-tidy aspect (configs = [Label("//:.clang-tidy")]).
17+
exports_files([".clang-tidy"])
18+
1619
# ==============================================================================
17-
# Positive tests - verify clean code passes with all sanitizers
20+
# Positive tests - verify clean code passes with all sanitizers and clang-tidy
1821
# ==============================================================================
1922

2023
cc_test(

tests/MODULE.bazel

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,15 @@ local_path_override(
2424
module_name = "score_cpp_policies",
2525
path = "..",
2626
)
27+
28+
# LLVM toolchain for clang-tidy (provides @llvm_toolchain//:clang-tidy).
29+
bazel_dep(name = "toolchains_llvm", version = "1.5.0")
30+
31+
llvm = use_extension(
32+
"@toolchains_llvm//toolchain/extensions:llvm.bzl",
33+
"llvm",
34+
)
35+
llvm.toolchain(
36+
llvm_version = "19.1.7",
37+
)
38+
use_repo(llvm, "llvm_toolchain")

0 commit comments

Comments
 (0)