Test: N/A Change-Id: I86d5578eaac260e55a9583db7ab49812b4ba1f5d
9.3 KiB
Clang-Tidy Rules and Checks
Android C/C++ source files can be checked by clang-tidy for issues like coding style, error-prone/performance patterns, and static flow analysis. See the official clang-tidy document and list of clang-tidy checks.
Global defaults for Android builds
The simplest way to enable clang-tidy checks is
to set environment variable WITH_TIDY
.
$ WITH_TIDY=1 make
This will turn on the global default to run clang-tidy for every required
C/C++ source file compilation. The global default clang-tidy checks
do not include time-consuming static analyzer checks. To enable those
checks, set the CLANG_ANALYZER_CHECKS
variable.
$ WITH_TIDY=1 CLANG_ANALYZER_CHECKS=1 make
The default global clang-tidy checks and flags are defined in build/soong/cc/config/tidy.go.
Module clang-tidy properties
The global default can be overwritten by module properties in Android.bp.
tidy
, tidy_checks
, and ALLOW_LOCAL_TIDY_TRUE
For example, in system/bpf/Android.bp, clang-tidy is enabled explicitly and with a different check list:
cc_defaults {
name: "bpf_defaults",
// snipped
tidy: true,
tidy_checks: [
"android-*",
"cert-*",
"-cert-err34-c",
"clang-analyzer-security*",
// Disabling due to many unavoidable warnings from POSIX API usage.
"-google-runtime-int",
],
}
That means in normal builds, even without WITH_TIDY=1
,
the modules that use bpf_defaults
should run clang-tidy
over C/C++ source files with the given tidy_checks
.
However since clang-tidy warnings and its runtime cost might
not be wanted by all people, the default is to ignore the
tidy:true
property unless the environment variable
ALLOW_LOCAL_TIDY_TRUE
is set to true or 1.
To run clang-tidy on all modules that should be tested with clang-tidy,
ALLOW_LOCAL_TIDY_TRUE
or WITH_TIDY
should be set to true or 1.
Note that clang-analyzer-security*
is included in tidy_checks
but not all clang-analyzer-*
checks. Check cert-err34-c
is
disabled, although cert-*
is selected.
Some modules might want to disable clang-tidy even when
environment variable WITH_TIDY=1
is set.
Examples can be found in
system/netd/tests/Android.bp
cc_test {
name: "netd_integration_test",
// snipped
defaults: ["netd_defaults"],
tidy: false, // cuts test build time by almost 1 minute
and in bionic/tests/Android.bp.
cc_test_library {
name: "fortify_disabled_for_tidy",
// snipped
srcs: ["clang_fortify_tests.cpp"],
tidy: false,
}
Note that tidy:false
always disables clang-tidy, no matter
ALLOW_LOCAL_TIDY_TRUE
is set or not.
tidy_checks_as_errors
The global tidy checks are enabled as warnings. If a C/C++ module wants to be free of certain clang-tidy warnings, it can chose those checks to be treated as errors. For example system/core/libsysutils/Android.bp has enabled clang-tidy explicitly, selected its own tidy checks, and set three groups of tidy checks as errors:
cc_library {
name: "libsysutils",
// snipped
tidy: true,
tidy_checks: [
"-*",
"cert-*",
"clang-analyzer-security*",
"android-*",
],
tidy_checks_as_errors: [
"cert-*",
"clang-analyzer-security*",
"android-*",
],
// snipped
}
tidy_flags
and tidy_disabled_srcs
Extra clang-tidy flags can be passed with the tidy_flags
property.
Some Android modules use the tidy_flags
to pass "-warnings-as-errors="
to clang-tidy. This usage should now be replaced with the
tidy_checks_as_errors
property.
Some other tidy flags examples are -format-style=
and -header-filter=
For example, in
art/odrefresh/Android.bp,
we found
cc_defaults {
name: "odrefresh-defaults",
srcs: [
"odrefresh.cc",
"odr_common.cc",
"odr_compilation_log.cc",
"odr_fs_utils.cc",
"odr_metrics.cc",
"odr_metrics_record.cc",
],
// snipped
generated_sources: [
"apex-info-list-tinyxml",
"art-apex-cache-info",
"art-odrefresh-operator-srcs",
],
// snipped
tidy: true,
tidy_disabled_srcs: [":art-apex-cache-info"],
tidy_flags: [
"-format-style=file",
"-header-filter=(art/odrefresh/|system/apex/)",
],
}
That means all modules with the odrefresh-defaults
will
have clang-tidy enabled, but not for generated source
files in art-apex-cache-info
.
The clang-tidy is called with extra flags to specify the
format-style and header-filter.
Note that the globally set default for header-filter is to
include only the module directory. So, the default clang-tidy
warnings for art/odrefresh
modules will include source files
under that directory. Now odrefresh-defaults
is interested
in seeing warnings from both art/odrefresh/
and system/apex/
and it redefines -header-filter
in its tidy_flags
.
Phony tidy-* targets
The tidy-directory targets
Setting WITH_TIDY=1
is easy to enable clang-tidy globally for any build.
However, it adds extra compilation time.
For developers focusing on just one directory, they only want to compile
their files with clang-tidy and wish to build other Android components as
fast as possible. Changing the WITH_TIDY=1
variable setting is also expensive
since the build.ninja file will be regenerated due to any such variable change.
To manually select only some directories or modules to compile with clang-tidy,
do not set the WITH_TIDY=1
variable, but use the special tidy-<directory>
phony target. For example, a person working on system/libbase
can build
Android quickly with
unset WITH_TIDY # Optional, not if you haven't set WITH_TIDY
make droid tidy-system-libbase
For any directory d1/d2/d3
, a phony target tidy-d1-d2-d3 is generated
if there is any C/C++ source file under d1/d2/d3
.
Note that with make droid tidy-system-libbase
, some C/C++ files
that are not needed by the droid
target will be passed to clang-tidy
if they are under system/libbase
. This is like a checkbuild
under system/libbase
to include all modules, but only C/C++
files of those modules are compiled with clang-tidy.
The tidy-soong target
A special tidy-soong
target is defined to include all C/C++
source files in all directories. This phony target is sometimes
used to test if all source files compile with a new clang-tidy release.
The tidy-*_subset targets
A subset of each tidy-* phony target is defined to reduce test time.
Since any Android module, a C/C++ library or binary, can be built
for many different variants, one C/C++ source file is usually
compiled multiple times with different compilation flags.
Many of such variant flags have little or no effect on clang-tidy
checks. To reduce clang-tidy check time, a subset target like
tidy-soong_subset
or tidy-system-libbase_subset
is generated
to include only a subset, the first variant, of each module in
the directory.
Hence, for C/C++ source code quality, instead of a long "make checkbuild", we can use "make tidy-soong_subset".
Limit clang-tidy runtime
Some Android modules have large files that take a long time to compile with clang-tidy, with or without the clang-analyzer checks. To limit clang-tidy time, an environment variable can be set as
WITH_TIDY=1 TIDY_TIMEOUT=90 make
This 90-second limit is actually the default time limit
in several Android continuous builds where WITH_TIDY=1
and
CLANG_ANALYZER_CHECKS=1
are set.
Similar to tidy_disabled_srcs
a tidy_timeout_srcs
list
can be used to include all source files that took too much time to compile
with clang-tidy. Files listed in tidy_timeout_srcs
will not
be compiled by clang-tidy when TIDY_TIMEOUT
is defined.
This can save global build time, when it is necessary to set some
time limit globally to finish in an acceptable time.
For developers who want to find all clang-tidy warnings and
are willing to spend more time on all files in a project,
they should not define TIDY_TIMEOUT
and build only the wanted project directories.
Capabilities for Android.bp and Android.mk
Some of the previously mentioned features are defined only for modules in Android.bp files, not for Android.mk modules yet.
-
The global
WITH_TIDY=1
variable will enable clang-tidy for all C/C++ modules in Android.bp or Android.mk files. -
The global
TIDY_TIMEOUT
variable is recognized by Android prebuilt clang-tidy, so it should work for any clang-tidy invocation. -
The clang-tidy module level properties are defined for Android.bp modules. For Android.mk modules, old
LOCAL_TIDY
,LOCAL_TIDY_CHECKS
,LOCAL_TIDY_FLAGS
work similarly, but it would be better to convert those modules to use Android.bp files. -
The
tidy-*
phony targets are only generated for Android.bp modules.