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