• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Clang-Tidy Rules and Checks
2
3Android C/C++ source files can be checked by clang-tidy for issues like
4coding style, error-prone/performance patterns, and static flow analysis.
5See the official
6[clang-tidy document](https://clang.llvm.org/extra/clang-tidy)
7and list of
8[clang-tidy checks](https://clang.llvm.org/extra/clang-tidy/checks/list.html).
9
10## Global defaults for Android builds
11
12The simplest way to enable clang-tidy checks is
13to set environment variable `WITH_TIDY`.
14```
15$ WITH_TIDY=1 make
16```
17
18This will turn on the global default to run clang-tidy for every required
19C/C++ source file compilation. The global default clang-tidy checks
20do not include time-consuming static analyzer checks. To enable those
21checks, set the `CLANG_ANALYZER_CHECKS` variable.
22```
23$ WITH_TIDY=1 CLANG_ANALYZER_CHECKS=1 make
24```
25
26The default global clang-tidy checks and flags are defined in
27[build/soong/cc/config/tidy.go](https://android.googlesource.com/platform/build/soong/+/refs/heads/master/cc/config/tidy.go).
28
29
30## Module clang-tidy properties
31
32The global default can be overwritten by module properties in Android.bp.
33
34### `tidy` and `tidy_checks`
35
36For example, in
37[system/bpf/Android.bp](https://android.googlesource.com/platform/system/bpf/+/refs/heads/master/Android.bp),
38clang-tidy is enabled explicitly and with a different check list:
39```
40cc_defaults {
41    name: "bpf_defaults",
42    // snipped
43    tidy: true,
44    tidy_checks: [
45        "android-*",
46        "cert-*",
47        "-cert-err34-c",
48        "clang-analyzer-security*",
49        // Disabling due to many unavoidable warnings from POSIX API usage.
50        "-google-runtime-int",
51    ],
52}
53```
54That means in normal builds, even without `WITH_TIDY=1`,
55the modules that use `bpf_defaults` will run clang-tidy
56over C/C++ source files with the given `tidy_checks`.
57Note that `clang-analyzer-security*` is included in `tidy_checks`
58but not all `clang-analyzer-*` checks. Check `cert-err34-c` is
59disabled, although `cert-*` is selected.
60
61Some modules might want to disable clang-tidy even when
62environment variable `WITH_TIDY=1` is set.
63Examples can be found in
64[system/netd/tests/Android.bp](https://android.googlesource.com/platform/system/netd/+/refs/heads/master/tests/Android.bp)
65```
66cc_test {
67    name: "netd_integration_test",
68    // snipped
69    defaults: ["netd_defaults"],
70    tidy: false,  // cuts test build time by almost 1 minute
71```
72and in
73[bionic/tests/Android.bp](https://android.googlesource.com/platform/bionic/+/refs/heads/master/tests/Android.bp).
74```
75cc_test_library {
76    name: "fortify_disabled_for_tidy",
77    // snipped
78    srcs: ["clang_fortify_tests.cpp"],
79    tidy: false,
80}
81```
82
83### `tidy_checks_as_errors`
84
85The global tidy checks are enabled as warnings.
86If a C/C++ module wants to be free of certain clang-tidy warnings,
87it can chose those checks to be treated as errors.
88For example
89[system/core/libsysutils/Android.bp](https://android.googlesource.com/platform/system/core/+/refs/heads/master/libsysutils/Android.bp)
90has enabled clang-tidy explicitly, selected its own tidy checks,
91and set three groups of tidy checks as errors:
92```
93cc_library {
94    name: "libsysutils",
95    // snipped
96    tidy: true,
97    tidy_checks: [
98        "-*",
99        "cert-*",
100        "clang-analyzer-security*",
101        "android-*",
102    ],
103    tidy_checks_as_errors: [
104        "cert-*",
105        "clang-analyzer-security*",
106        "android-*",
107    ],
108    // snipped
109}
110```
111
112### `tidy_flags` and `tidy_disabled_srcs`
113
114Extra clang-tidy flags can be passed with the `tidy_flags` property.
115
116Some Android modules use the `tidy_flags` to pass "-warnings-as-errors="
117to clang-tidy. This usage should now be replaced with the
118`tidy_checks_as_errors` property.
119
120Some other tidy flags examples are `-format-style=` and `-header-filter=`
121For example, in
122[art/odrefresh/Android.bp](https://android.googlesource.com/platform/art/+/refs/heads/master/odrefresh/Android.bp),
123we found
124```
125cc_defaults {
126    name: "odrefresh-defaults",
127    srcs: [
128        "odrefresh.cc",
129        "odr_common.cc",
130        "odr_compilation_log.cc",
131        "odr_fs_utils.cc",
132        "odr_metrics.cc",
133        "odr_metrics_record.cc",
134    ],
135    // snipped
136    generated_sources: [
137        "apex-info-list-tinyxml",
138        "art-apex-cache-info",
139        "art-odrefresh-operator-srcs",
140    ],
141    // snipped
142    tidy: true,
143    tidy_disabled_srcs: [":art-apex-cache-info"],
144    tidy_flags: [
145        "-format-style=file",
146        "-header-filter=(art/odrefresh/|system/apex/)",
147    ],
148}
149```
150That means all modules with the `odrefresh-defaults` will
151have clang-tidy enabled, but not for generated source
152files in `art-apex-cache-info`.
153The clang-tidy is called with extra flags to specify the
154format-style and header-filter.
155
156Note that the globally set default for header-filter is to
157include only the module directory. So, the default clang-tidy
158warnings for `art/odrefresh` modules will include source files
159under that directory. Now `odrefresh-defaults` is interested
160in seeing warnings from both `art/odrefresh/` and `system/apex/`
161and it redefines `-header-filter` in its `tidy_flags`.
162
163
164## Phony tidy-* targets
165
166### The tidy-*directory* targets
167
168Setting `WITH_TIDY=1` is easy to enable clang-tidy globally for any build.
169However, it adds extra compilation time.
170
171For developers focusing on just one directory, they only want to compile
172their files with clang-tidy and wish to build other Android components as
173fast as possible. Changing the `WITH_TIDY=1` variable setting is also expensive
174since the build.ninja file will be regenerated due to any such variable change.
175
176To manually select only some directories or modules to compile with clang-tidy,
177do not set the `WITH_TIDY=1` variable, but use the special `tidy-<directory>`
178phony target. For example, a person working on `system/libbase` can build
179Android quickly with
180```
181unset WITH_TIDY # Optional, not if you haven't set WITH_TIDY
182make droid tidy-system-libbase
183```
184
185For any directory `d1/d2/d3`, a phony target tidy-d1-d2-d3 is generated
186if there is any C/C++ source file under `d1/d2/d3`.
187
188Note that with `make droid tidy-system-libbase`, some C/C++ files
189that are not needed by the `droid` target will be passed to clang-tidy
190if they are under `system/libbase`. This is like a `checkbuild`
191under `system/libbase` to include all modules, but only C/C++
192files of those modules are compiled with clang-tidy.
193
194### The tidy-soong target
195
196A special `tidy-soong` target is defined to include all C/C++
197source files in *all* directories. This phony target is sometimes
198used to test if all source files compile with a new clang-tidy release.
199
200### The tidy-*_subset targets
201
202A *subset* of each tidy-* phony target is defined to reduce test time.
203Since any Android module, a C/C++ library or binary, can be built
204for many different *variants*, one C/C++ source file is usually
205compiled multiple times with different compilation flags.
206Many of such *variant* flags have little or no effect on clang-tidy
207checks. To reduce clang-tidy check time, a *subset* target like
208`tidy-soong_subset` or `tidy-system-libbase_subset` is generated
209to include only a subset, the first variant, of each module in
210the directory.
211
212Hence, for C/C++ source code quality, instead of a long
213"make checkbuild", we can use "make tidy-soong_subset".
214
215
216## Limit clang-tidy runtime
217
218Some Android modules have large files that take a long time to compile
219with clang-tidy, with or without the clang-analyzer checks.
220To limit clang-tidy time, an environment variable can be set as
221```base
222WITH_TIDY=1 TIDY_TIMEOUT=90 make
223```
224This 90-second limit is actually the default time limit
225in several Android continuous builds where `WITH_TIDY=1` and
226`CLANG_ANALYZER_CHECKS=1` are set.
227
228Similar to `tidy_disabled_srcs` a `tidy_timeout_srcs` list
229can be used to include all source files that took too much time to compile
230with clang-tidy. Files listed in `tidy_timeout_srcs` will not
231be compiled by clang-tidy when `TIDY_TIMEOUT` is defined.
232This can save global build time, when it is necessary to set some
233time limit globally to finish in an acceptable time.
234For developers who want to find all clang-tidy warnings and
235are willing to spend more time on all files in a project,
236they should not define `TIDY_TIMEOUT` and build only the wanted project directories.
237
238## Capabilities for Android.bp and Android.mk
239
240Some of the previously mentioned features are defined only
241for modules in Android.bp files, not for Android.mk modules yet.
242
243* The global `WITH_TIDY=1` variable will enable clang-tidy for all C/C++
244  modules in Android.bp or Android.mk files.
245
246* The global `TIDY_TIMEOUT` variable is recognized by Android prebuilt
247  clang-tidy, so it should work for any clang-tidy invocation.
248
249* The clang-tidy module level properties are defined for Android.bp modules.
250  For Android.mk modules, old `LOCAL_TIDY`, `LOCAL_TIDY_CHECKS`,
251  `LOCAL_TIDY_FLAGS` work similarly, but it would be better to convert
252  those modules to use Android.bp files.
253
254* The `tidy-*` phony targets are only generated for Android.bp modules.
255