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