1*7594170eSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 2*7594170eSAndroid Build Coastguard Worker# 3*7594170eSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*7594170eSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*7594170eSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*7594170eSAndroid Build Coastguard Worker# 7*7594170eSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*7594170eSAndroid Build Coastguard Worker# 9*7594170eSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*7594170eSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*7594170eSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*7594170eSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*7594170eSAndroid Build Coastguard Worker# limitations under the License. 14*7594170eSAndroid Build Coastguard Worker 15*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//lib:paths.bzl", "paths") 16*7594170eSAndroid Build Coastguard Workerload("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") 17*7594170eSAndroid Build Coastguard Workerload( 18*7594170eSAndroid Build Coastguard Worker "@bazel_tools//tools/build_defs/cc:action_names.bzl", 19*7594170eSAndroid Build Coastguard Worker "CPP_COMPILE_ACTION_NAME", 20*7594170eSAndroid Build Coastguard Worker "C_COMPILE_ACTION_NAME", 21*7594170eSAndroid Build Coastguard Worker) 22*7594170eSAndroid Build Coastguard Workerload("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") 23*7594170eSAndroid Build Coastguard Workerload("@soong_injection//cc_toolchain:config_constants.bzl", "constants") 24*7594170eSAndroid Build Coastguard Workerload("//build/bazel/rules:common.bzl", "get_dep_targets") 25*7594170eSAndroid Build Coastguard Workerload(":cc_library_common.bzl", "get_compilation_args") 26*7594170eSAndroid Build Coastguard Worker 27*7594170eSAndroid Build Coastguard WorkerClangTidyInfo = provider( 28*7594170eSAndroid Build Coastguard Worker "Info provided from clang-tidy actions", 29*7594170eSAndroid Build Coastguard Worker fields = { 30*7594170eSAndroid Build Coastguard Worker "tidy_files": "Outputs from the clang-tidy tool", 31*7594170eSAndroid Build Coastguard Worker # TODO(b/282188514) stop propagating transitive tidy files after Bazel migration 32*7594170eSAndroid Build Coastguard Worker "transitive_tidy_files": "Outputs from the clang-tidy tool for all transitive dependencies." + 33*7594170eSAndroid Build Coastguard Worker " Currently, these are needed so that mixed-build targets can also run clang-tidy for their dependencies.", 34*7594170eSAndroid Build Coastguard Worker }, 35*7594170eSAndroid Build Coastguard Worker) 36*7594170eSAndroid Build Coastguard Worker 37*7594170eSAndroid Build Coastguard Worker_TIDY_GLOBAL_NO_CHECKS = constants.TidyGlobalNoChecks.split(",") 38*7594170eSAndroid Build Coastguard Worker_TIDY_GLOBAL_NO_ERROR_CHECKS = constants.TidyGlobalNoErrorChecks.split(",") 39*7594170eSAndroid Build Coastguard Worker_TIDY_DEFAULT_GLOBAL_CHECKS = constants.TidyDefaultGlobalChecks.split(",") 40*7594170eSAndroid Build Coastguard Worker_TIDY_EXTERNAL_VENDOR_CHECKS = constants.TidyExternalVendorChecks.split(",") 41*7594170eSAndroid Build Coastguard Worker_TIDY_DEFAULT_GLOBAL_CHECKS_NO_ANALYZER = constants.TidyDefaultGlobalChecks.split(",") + ["-clang-analyzer-*"] 42*7594170eSAndroid Build Coastguard Worker_TIDY_EXTRA_ARG_FLAGS = constants.TidyExtraArgFlags 43*7594170eSAndroid Build Coastguard Worker 44*7594170eSAndroid Build Coastguard Workerdef _check_bad_tidy_flags(tidy_flags): 45*7594170eSAndroid Build Coastguard Worker """should be kept up to date with 46*7594170eSAndroid Build Coastguard Worker https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/check.go;l=128;drc=b45a2ea782074944f79fc388df20b06e01f265f7 47*7594170eSAndroid Build Coastguard Worker """ 48*7594170eSAndroid Build Coastguard Worker for flag in tidy_flags: 49*7594170eSAndroid Build Coastguard Worker flag = flag.strip() 50*7594170eSAndroid Build Coastguard Worker if not flag.startswith("-"): 51*7594170eSAndroid Build Coastguard Worker fail("Flag `%s` must start with `-`" % flag) 52*7594170eSAndroid Build Coastguard Worker if flag.startswith("-fix"): 53*7594170eSAndroid Build Coastguard Worker fail("Flag `%s` is not allowed, since it could cause multiple writes to the same source file" % flag) 54*7594170eSAndroid Build Coastguard Worker if flag.startswith("-checks="): 55*7594170eSAndroid Build Coastguard Worker fail("Flag `%s` is not allowed, use `tidy_checks` property instead" % flag) 56*7594170eSAndroid Build Coastguard Worker if "-warnings-as-errors=" in flag: 57*7594170eSAndroid Build Coastguard Worker fail("Flag `%s` is not allowed, use `tidy_checks_as_errors` property instead" % flag) 58*7594170eSAndroid Build Coastguard Worker if " " in flag: 59*7594170eSAndroid Build Coastguard Worker fail("Bad flag: `%s` is not an allowed multi-word flag. Should it be split into multiple flags?" % flag) 60*7594170eSAndroid Build Coastguard Worker 61*7594170eSAndroid Build Coastguard Workerdef _check_bad_tidy_checks(tidy_checks): 62*7594170eSAndroid Build Coastguard Worker """should be kept up to date with 63*7594170eSAndroid Build Coastguard Worker https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/check.go;l=145;drc=b45a2ea782074944f79fc388df20b06e01f265f7 64*7594170eSAndroid Build Coastguard Worker """ 65*7594170eSAndroid Build Coastguard Worker for check in tidy_checks: 66*7594170eSAndroid Build Coastguard Worker if " " in check: 67*7594170eSAndroid Build Coastguard Worker fail("Check `%s` invalid, cannot contain spaces" % check) 68*7594170eSAndroid Build Coastguard Worker if "," in check: 69*7594170eSAndroid Build Coastguard Worker fail("Check `%s` invalid, cannot contain commas. Split each entry into its own string instead" % check) 70*7594170eSAndroid Build Coastguard Worker 71*7594170eSAndroid Build Coastguard Workerdef _add_with_tidy_flags(ctx, tidy_flags): 72*7594170eSAndroid Build Coastguard Worker with_tidy_flags = ctx.attr._with_tidy_flags[BuildSettingInfo].value 73*7594170eSAndroid Build Coastguard Worker if with_tidy_flags: 74*7594170eSAndroid Build Coastguard Worker return tidy_flags + with_tidy_flags 75*7594170eSAndroid Build Coastguard Worker return tidy_flags 76*7594170eSAndroid Build Coastguard Worker 77*7594170eSAndroid Build Coastguard Workerdef _add_header_filter(ctx, tidy_flags): 78*7594170eSAndroid Build Coastguard Worker """If TidyFlags does not contain -header-filter, add default header filter. 79*7594170eSAndroid Build Coastguard Worker """ 80*7594170eSAndroid Build Coastguard Worker for flag in tidy_flags: 81*7594170eSAndroid Build Coastguard Worker # Find the substring because the flag could also appear as --header-filter=... 82*7594170eSAndroid Build Coastguard Worker # and with or without single or double quotes. 83*7594170eSAndroid Build Coastguard Worker if "-header-filter=" in flag: 84*7594170eSAndroid Build Coastguard Worker return tidy_flags 85*7594170eSAndroid Build Coastguard Worker 86*7594170eSAndroid Build Coastguard Worker # Default header filter should include only the module directory, 87*7594170eSAndroid Build Coastguard Worker # not the out/soong/.../ModuleDir/... 88*7594170eSAndroid Build Coastguard Worker # Otherwise, there will be too many warnings from generated files in out/... 89*7594170eSAndroid Build Coastguard Worker # If a module wants to see warnings in the generated source files, 90*7594170eSAndroid Build Coastguard Worker # it should specify its own -header-filter flag. 91*7594170eSAndroid Build Coastguard Worker default_dirs = ctx.attr._default_tidy_header_dirs[BuildSettingInfo].value 92*7594170eSAndroid Build Coastguard Worker if default_dirs == "": 93*7594170eSAndroid Build Coastguard Worker header_filter = "-header-filter=^" + ctx.label.package + "/" 94*7594170eSAndroid Build Coastguard Worker else: 95*7594170eSAndroid Build Coastguard Worker header_filter = "-header-filter=\"(^%s/|%s)\"" % (ctx.label.package, default_dirs) 96*7594170eSAndroid Build Coastguard Worker return tidy_flags + [header_filter] 97*7594170eSAndroid Build Coastguard Worker 98*7594170eSAndroid Build Coastguard Workerdef _add_extra_arg_flags(tidy_flags): 99*7594170eSAndroid Build Coastguard Worker return tidy_flags + ["-extra-arg-before=" + f for f in _TIDY_EXTRA_ARG_FLAGS] 100*7594170eSAndroid Build Coastguard Worker 101*7594170eSAndroid Build Coastguard Workerdef _add_quiet_if_not_global_tidy(ctx, tidy_flags): 102*7594170eSAndroid Build Coastguard Worker tidy_checks = ctx.attr._tidy_checks[BuildSettingInfo].value 103*7594170eSAndroid Build Coastguard Worker if not tidy_checks: 104*7594170eSAndroid Build Coastguard Worker return tidy_flags + [ 105*7594170eSAndroid Build Coastguard Worker "-quiet", 106*7594170eSAndroid Build Coastguard Worker "-extra-arg-before=-fno-caret-diagnostics", 107*7594170eSAndroid Build Coastguard Worker ] 108*7594170eSAndroid Build Coastguard Worker return tidy_flags 109*7594170eSAndroid Build Coastguard Worker 110*7594170eSAndroid Build Coastguard Workerdef _clang_rewrite_tidy_checks(tidy_checks): 111*7594170eSAndroid Build Coastguard Worker # List of tidy checks that should be disabled globally. When the compiler is 112*7594170eSAndroid Build Coastguard Worker # updated, some checks enabled by this module may be disabled if they have 113*7594170eSAndroid Build Coastguard Worker # become more strict, or if they are a new match for a wildcard group like 114*7594170eSAndroid Build Coastguard Worker # `modernize-*`. 115*7594170eSAndroid Build Coastguard Worker clang_tidy_disable_checks = [ 116*7594170eSAndroid Build Coastguard Worker "misc-no-recursion", 117*7594170eSAndroid Build Coastguard Worker "readability-function-cognitive-complexity", # http://b/175055536 118*7594170eSAndroid Build Coastguard Worker ] 119*7594170eSAndroid Build Coastguard Worker 120*7594170eSAndroid Build Coastguard Worker tidy_checks = tidy_checks + ["-" + c for c in clang_tidy_disable_checks] 121*7594170eSAndroid Build Coastguard Worker 122*7594170eSAndroid Build Coastguard Worker # clang-tidy does not allow later arguments to override earlier arguments, 123*7594170eSAndroid Build Coastguard Worker # so if we just disabled an argument that was explicitly enabled we must 124*7594170eSAndroid Build Coastguard Worker # remove the enabling argument from the list. 125*7594170eSAndroid Build Coastguard Worker return [t for t in tidy_checks if t not in clang_tidy_disable_checks] 126*7594170eSAndroid Build Coastguard Worker 127*7594170eSAndroid Build Coastguard Workerdef _add_checks_for_dir(directory): 128*7594170eSAndroid Build Coastguard Worker """should be kept up to date with 129*7594170eSAndroid Build Coastguard Worker https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/config/tidy.go;l=170;drc=b45a2ea782074944f79fc388df20b06e01f265f7 130*7594170eSAndroid Build Coastguard Worker """ 131*7594170eSAndroid Build Coastguard Worker 132*7594170eSAndroid Build Coastguard Worker # This is a map of local path prefixes to the set of default clang-tidy checks 133*7594170eSAndroid Build Coastguard Worker # to be used. This is like android.IsThirdPartyPath, but with more patterns. 134*7594170eSAndroid Build Coastguard Worker # The last matched local_path_prefix should be the most specific to be used. 135*7594170eSAndroid Build Coastguard Worker directory_checks = [ 136*7594170eSAndroid Build Coastguard Worker ("external/", _TIDY_EXTERNAL_VENDOR_CHECKS), 137*7594170eSAndroid Build Coastguard Worker ("frameworks/compile/mclinker/", _TIDY_EXTERNAL_VENDOR_CHECKS), 138*7594170eSAndroid Build Coastguard Worker ("hardware/", _TIDY_EXTERNAL_VENDOR_CHECKS), 139*7594170eSAndroid Build Coastguard Worker ("hardware/google/", _TIDY_DEFAULT_GLOBAL_CHECKS), 140*7594170eSAndroid Build Coastguard Worker ("hardware/interfaces/", _TIDY_DEFAULT_GLOBAL_CHECKS), 141*7594170eSAndroid Build Coastguard Worker ("hardware/ril/", _TIDY_DEFAULT_GLOBAL_CHECKS), 142*7594170eSAndroid Build Coastguard Worker ("hardware/libhardware", _TIDY_DEFAULT_GLOBAL_CHECKS), # all 'hardware/libhardware*' 143*7594170eSAndroid Build Coastguard Worker ("vendor/", _TIDY_EXTERNAL_VENDOR_CHECKS), 144*7594170eSAndroid Build Coastguard Worker ("vendor/google", _TIDY_DEFAULT_GLOBAL_CHECKS), # all 'vendor/google*' 145*7594170eSAndroid Build Coastguard Worker ("vendor/google/external/", _TIDY_EXTERNAL_VENDOR_CHECKS), 146*7594170eSAndroid Build Coastguard Worker ("vendor/google_arc/libs/org.chromium.arc.mojom", _TIDY_EXTERNAL_VENDOR_CHECKS), 147*7594170eSAndroid Build Coastguard Worker ("vendor/google_devices/", _TIDY_EXTERNAL_VENDOR_CHECKS), # many have vendor code 148*7594170eSAndroid Build Coastguard Worker ] 149*7594170eSAndroid Build Coastguard Worker 150*7594170eSAndroid Build Coastguard Worker for d, checks in reversed(directory_checks): 151*7594170eSAndroid Build Coastguard Worker if directory.startswith(d): 152*7594170eSAndroid Build Coastguard Worker return checks 153*7594170eSAndroid Build Coastguard Worker 154*7594170eSAndroid Build Coastguard Worker return _TIDY_DEFAULT_GLOBAL_CHECKS 155*7594170eSAndroid Build Coastguard Worker 156*7594170eSAndroid Build Coastguard Workerdef _add_global_tidy_checks(ctx, local_checks, input_file): 157*7594170eSAndroid Build Coastguard Worker tidy_checks = ctx.attr._tidy_checks[BuildSettingInfo].value 158*7594170eSAndroid Build Coastguard Worker global_tidy_checks = [] 159*7594170eSAndroid Build Coastguard Worker if tidy_checks: 160*7594170eSAndroid Build Coastguard Worker global_tidy_checks = tidy_checks 161*7594170eSAndroid Build Coastguard Worker elif not input_file.is_source: 162*7594170eSAndroid Build Coastguard Worker # don't run clang-tidy for generated files 163*7594170eSAndroid Build Coastguard Worker global_tidy_checks = _TIDY_DEFAULT_GLOBAL_CHECKS_NO_ANALYZER 164*7594170eSAndroid Build Coastguard Worker else: 165*7594170eSAndroid Build Coastguard Worker global_tidy_checks = _add_checks_for_dir(ctx.label.package) 166*7594170eSAndroid Build Coastguard Worker 167*7594170eSAndroid Build Coastguard Worker # If Tidy_checks contains "-*", ignore all checks before "-*". 168*7594170eSAndroid Build Coastguard Worker for i, check in enumerate(local_checks): 169*7594170eSAndroid Build Coastguard Worker if check == "-*": 170*7594170eSAndroid Build Coastguard Worker global_tidy_checks = [] 171*7594170eSAndroid Build Coastguard Worker local_checks = local_checks[i:] 172*7594170eSAndroid Build Coastguard Worker 173*7594170eSAndroid Build Coastguard Worker tidy_checks = global_tidy_checks + _clang_rewrite_tidy_checks(local_checks) 174*7594170eSAndroid Build Coastguard Worker tidy_checks.extend(_TIDY_GLOBAL_NO_CHECKS) 175*7594170eSAndroid Build Coastguard Worker 176*7594170eSAndroid Build Coastguard Worker #TODO(b/255747672) disable cert check on windows only 177*7594170eSAndroid Build Coastguard Worker return tidy_checks 178*7594170eSAndroid Build Coastguard Worker 179*7594170eSAndroid Build Coastguard Workerdef _add_global_tidy_checks_as_errors(tidy_checks_as_errors): 180*7594170eSAndroid Build Coastguard Worker return tidy_checks_as_errors + _TIDY_GLOBAL_NO_ERROR_CHECKS 181*7594170eSAndroid Build Coastguard Worker 182*7594170eSAndroid Build Coastguard Workerdef _create_clang_tidy_action( 183*7594170eSAndroid Build Coastguard Worker ctx, 184*7594170eSAndroid Build Coastguard Worker clang_tool, 185*7594170eSAndroid Build Coastguard Worker input_file, 186*7594170eSAndroid Build Coastguard Worker tidy_checks, 187*7594170eSAndroid Build Coastguard Worker tidy_checks_as_errors, 188*7594170eSAndroid Build Coastguard Worker tidy_flags, 189*7594170eSAndroid Build Coastguard Worker clang_flags, 190*7594170eSAndroid Build Coastguard Worker headers, 191*7594170eSAndroid Build Coastguard Worker tidy_timeout): 192*7594170eSAndroid Build Coastguard Worker tidy_flags = _add_with_tidy_flags(ctx, tidy_flags) 193*7594170eSAndroid Build Coastguard Worker tidy_flags = _add_header_filter(ctx, tidy_flags) 194*7594170eSAndroid Build Coastguard Worker tidy_flags = _add_extra_arg_flags(tidy_flags) 195*7594170eSAndroid Build Coastguard Worker tidy_flags = _add_quiet_if_not_global_tidy(ctx, tidy_flags) 196*7594170eSAndroid Build Coastguard Worker tidy_checks = _add_global_tidy_checks(ctx, tidy_checks, input_file) 197*7594170eSAndroid Build Coastguard Worker tidy_checks_as_errors = _add_global_tidy_checks_as_errors(tidy_checks_as_errors) 198*7594170eSAndroid Build Coastguard Worker 199*7594170eSAndroid Build Coastguard Worker _check_bad_tidy_checks(tidy_checks) 200*7594170eSAndroid Build Coastguard Worker _check_bad_tidy_flags(tidy_flags) 201*7594170eSAndroid Build Coastguard Worker 202*7594170eSAndroid Build Coastguard Worker args = ctx.actions.args() 203*7594170eSAndroid Build Coastguard Worker args.add(input_file) 204*7594170eSAndroid Build Coastguard Worker if tidy_checks: 205*7594170eSAndroid Build Coastguard Worker args.add("-checks=" + ",".join(tidy_checks)) 206*7594170eSAndroid Build Coastguard Worker if tidy_checks_as_errors: 207*7594170eSAndroid Build Coastguard Worker args.add("-warnings-as-errors=" + ",".join(tidy_checks_as_errors)) 208*7594170eSAndroid Build Coastguard Worker if tidy_flags: 209*7594170eSAndroid Build Coastguard Worker args.add_all(tidy_flags) 210*7594170eSAndroid Build Coastguard Worker args.add("--") 211*7594170eSAndroid Build Coastguard Worker args.add_all(clang_flags) 212*7594170eSAndroid Build Coastguard Worker 213*7594170eSAndroid Build Coastguard Worker tidy_file = ctx.actions.declare_file(paths.join(ctx.label.name, input_file.short_path + ".tidy")) 214*7594170eSAndroid Build Coastguard Worker env = { 215*7594170eSAndroid Build Coastguard Worker "CLANG_CMD": clang_tool, 216*7594170eSAndroid Build Coastguard Worker "TIDY_FILE": tidy_file.path, 217*7594170eSAndroid Build Coastguard Worker } 218*7594170eSAndroid Build Coastguard Worker if tidy_timeout: 219*7594170eSAndroid Build Coastguard Worker env["TIDY_TIMEOUT"] = tidy_timeout 220*7594170eSAndroid Build Coastguard Worker 221*7594170eSAndroid Build Coastguard Worker ctx.actions.run( 222*7594170eSAndroid Build Coastguard Worker inputs = [input_file] + headers, 223*7594170eSAndroid Build Coastguard Worker outputs = [tidy_file], 224*7594170eSAndroid Build Coastguard Worker arguments = [args], 225*7594170eSAndroid Build Coastguard Worker env = env, 226*7594170eSAndroid Build Coastguard Worker progress_message = "Running clang-tidy on {}".format(input_file.short_path), 227*7594170eSAndroid Build Coastguard Worker tools = [ 228*7594170eSAndroid Build Coastguard Worker ctx.executable._clang_tidy, 229*7594170eSAndroid Build Coastguard Worker ctx.executable._clang_tidy_real, 230*7594170eSAndroid Build Coastguard Worker ], 231*7594170eSAndroid Build Coastguard Worker executable = ctx.executable._clang_tidy_sh, 232*7594170eSAndroid Build Coastguard Worker execution_requirements = { 233*7594170eSAndroid Build Coastguard Worker "no-sandbox": "1", 234*7594170eSAndroid Build Coastguard Worker }, 235*7594170eSAndroid Build Coastguard Worker mnemonic = "ClangTidy", 236*7594170eSAndroid Build Coastguard Worker ) 237*7594170eSAndroid Build Coastguard Worker 238*7594170eSAndroid Build Coastguard Worker return tidy_file 239*7594170eSAndroid Build Coastguard Worker 240*7594170eSAndroid Build Coastguard Workerdef generate_clang_tidy_actions( 241*7594170eSAndroid Build Coastguard Worker ctx, 242*7594170eSAndroid Build Coastguard Worker flags, 243*7594170eSAndroid Build Coastguard Worker deps, 244*7594170eSAndroid Build Coastguard Worker srcs, 245*7594170eSAndroid Build Coastguard Worker hdrs, 246*7594170eSAndroid Build Coastguard Worker language, 247*7594170eSAndroid Build Coastguard Worker tidy_flags, 248*7594170eSAndroid Build Coastguard Worker tidy_checks, 249*7594170eSAndroid Build Coastguard Worker tidy_checks_as_errors, 250*7594170eSAndroid Build Coastguard Worker tidy_timeout): 251*7594170eSAndroid Build Coastguard Worker """Generates actions for clang tidy 252*7594170eSAndroid Build Coastguard Worker 253*7594170eSAndroid Build Coastguard Worker Args: 254*7594170eSAndroid Build Coastguard Worker ctx (Context): rule context that is expected to contain 255*7594170eSAndroid Build Coastguard Worker - ctx.executable._clang_tidy 256*7594170eSAndroid Build Coastguard Worker - ctx.executable._clang_tidy_sh 257*7594170eSAndroid Build Coastguard Worker - ctx.executable._clang_tidy_real 258*7594170eSAndroid Build Coastguard Worker - ctx.label._with_tidy_flags 259*7594170eSAndroid Build Coastguard Worker flags (list[str]): list of target-specific (non-toolchain) flags passed 260*7594170eSAndroid Build Coastguard Worker to clang compile action 261*7594170eSAndroid Build Coastguard Worker deps (list[Target]): list of Targets which provide headers to 262*7594170eSAndroid Build Coastguard Worker compilation context 263*7594170eSAndroid Build Coastguard Worker srcs (list[File]): list of srcs to which clang-tidy will be applied 264*7594170eSAndroid Build Coastguard Worker hdrs (list[File]): list of headers used by srcs. This is used to provide 265*7594170eSAndroid Build Coastguard Worker explicit inputs to the action 266*7594170eSAndroid Build Coastguard Worker language (str): must be one of ["c++", "c"]. This is used to decide what 267*7594170eSAndroid Build Coastguard Worker toolchain arguments are passed to the clang compile action 268*7594170eSAndroid Build Coastguard Worker tidy_flags (list[str]): additional flags to pass to the clang-tidy tool 269*7594170eSAndroid Build Coastguard Worker tidy_checks (list[str]): list of checks for clang-tidy to perform 270*7594170eSAndroid Build Coastguard Worker tidy_checks_as_errors (list[str]): list of checks to pass as 271*7594170eSAndroid Build Coastguard Worker "-warnings-as-errors" to clang-tidy 272*7594170eSAndroid Build Coastguard Worker tidy_checks_as_errors (str): timeout to pass to clang-tidy tool 273*7594170eSAndroid Build Coastguard Worker tidy_timeout (str): timeout in seconds after which to stop a clang-tidy 274*7594170eSAndroid Build Coastguard Worker invocation 275*7594170eSAndroid Build Coastguard Worker Returns: 276*7594170eSAndroid Build Coastguard Worker tidy_file_outputs: (list[File]): list of .tidy files output by the 277*7594170eSAndroid Build Coastguard Worker clang-tidy.sh tool 278*7594170eSAndroid Build Coastguard Worker """ 279*7594170eSAndroid Build Coastguard Worker toolchain = find_cpp_toolchain(ctx) 280*7594170eSAndroid Build Coastguard Worker feature_config = cc_common.configure_features( 281*7594170eSAndroid Build Coastguard Worker ctx = ctx, 282*7594170eSAndroid Build Coastguard Worker cc_toolchain = toolchain, 283*7594170eSAndroid Build Coastguard Worker language = "c++", 284*7594170eSAndroid Build Coastguard Worker requested_features = ctx.features, 285*7594170eSAndroid Build Coastguard Worker unsupported_features = ctx.disabled_features, 286*7594170eSAndroid Build Coastguard Worker ) 287*7594170eSAndroid Build Coastguard Worker 288*7594170eSAndroid Build Coastguard Worker language = language 289*7594170eSAndroid Build Coastguard Worker action_name = "" 290*7594170eSAndroid Build Coastguard Worker if language == "c++": 291*7594170eSAndroid Build Coastguard Worker action_name = CPP_COMPILE_ACTION_NAME 292*7594170eSAndroid Build Coastguard Worker elif language == "c": 293*7594170eSAndroid Build Coastguard Worker action_name = C_COMPILE_ACTION_NAME 294*7594170eSAndroid Build Coastguard Worker else: 295*7594170eSAndroid Build Coastguard Worker fail("invalid language:", language) 296*7594170eSAndroid Build Coastguard Worker 297*7594170eSAndroid Build Coastguard Worker dep_info = cc_common.merge_cc_infos(direct_cc_infos = [d[CcInfo] for d in deps]) 298*7594170eSAndroid Build Coastguard Worker compilation_ctx = dep_info.compilation_context 299*7594170eSAndroid Build Coastguard Worker args = get_compilation_args( 300*7594170eSAndroid Build Coastguard Worker toolchain = toolchain, 301*7594170eSAndroid Build Coastguard Worker feature_config = feature_config, 302*7594170eSAndroid Build Coastguard Worker flags = flags, 303*7594170eSAndroid Build Coastguard Worker compilation_ctx = compilation_ctx, 304*7594170eSAndroid Build Coastguard Worker action_name = action_name, 305*7594170eSAndroid Build Coastguard Worker ) 306*7594170eSAndroid Build Coastguard Worker 307*7594170eSAndroid Build Coastguard Worker clang_tool = cc_common.get_tool_for_action( 308*7594170eSAndroid Build Coastguard Worker feature_configuration = feature_config, 309*7594170eSAndroid Build Coastguard Worker action_name = action_name, 310*7594170eSAndroid Build Coastguard Worker ) 311*7594170eSAndroid Build Coastguard Worker 312*7594170eSAndroid Build Coastguard Worker header_inputs = ( 313*7594170eSAndroid Build Coastguard Worker hdrs + 314*7594170eSAndroid Build Coastguard Worker compilation_ctx.headers.to_list() + 315*7594170eSAndroid Build Coastguard Worker compilation_ctx.direct_headers + 316*7594170eSAndroid Build Coastguard Worker compilation_ctx.direct_private_headers + 317*7594170eSAndroid Build Coastguard Worker compilation_ctx.direct_public_headers + 318*7594170eSAndroid Build Coastguard Worker compilation_ctx.direct_textual_headers 319*7594170eSAndroid Build Coastguard Worker ) 320*7594170eSAndroid Build Coastguard Worker 321*7594170eSAndroid Build Coastguard Worker tidy_file_outputs = [] 322*7594170eSAndroid Build Coastguard Worker for src in srcs: 323*7594170eSAndroid Build Coastguard Worker tidy_file = _create_clang_tidy_action( 324*7594170eSAndroid Build Coastguard Worker ctx = ctx, 325*7594170eSAndroid Build Coastguard Worker input_file = src, 326*7594170eSAndroid Build Coastguard Worker headers = header_inputs, 327*7594170eSAndroid Build Coastguard Worker clang_tool = paths.basename(clang_tool), 328*7594170eSAndroid Build Coastguard Worker tidy_checks = tidy_checks, 329*7594170eSAndroid Build Coastguard Worker tidy_checks_as_errors = tidy_checks_as_errors, 330*7594170eSAndroid Build Coastguard Worker tidy_flags = tidy_flags, 331*7594170eSAndroid Build Coastguard Worker clang_flags = args, 332*7594170eSAndroid Build Coastguard Worker tidy_timeout = tidy_timeout, 333*7594170eSAndroid Build Coastguard Worker ) 334*7594170eSAndroid Build Coastguard Worker tidy_file_outputs.append(tidy_file) 335*7594170eSAndroid Build Coastguard Worker 336*7594170eSAndroid Build Coastguard Worker return tidy_file_outputs 337*7594170eSAndroid Build Coastguard Worker 338*7594170eSAndroid Build Coastguard Workerdef collect_deps_clang_tidy_info(ctx): 339*7594170eSAndroid Build Coastguard Worker transitive_clang_tidy_files = [] 340*7594170eSAndroid Build Coastguard Worker for attr_deps in get_dep_targets(ctx.attr, predicate = lambda target: ClangTidyInfo in target).values(): 341*7594170eSAndroid Build Coastguard Worker for dep in attr_deps: 342*7594170eSAndroid Build Coastguard Worker transitive_clang_tidy_files.append(dep[ClangTidyInfo].transitive_tidy_files) 343*7594170eSAndroid Build Coastguard Worker return ClangTidyInfo( 344*7594170eSAndroid Build Coastguard Worker tidy_files = depset(), 345*7594170eSAndroid Build Coastguard Worker transitive_tidy_files = depset(transitive = transitive_clang_tidy_files), 346*7594170eSAndroid Build Coastguard Worker ) 347*7594170eSAndroid Build Coastguard Worker 348*7594170eSAndroid Build Coastguard Workerdef _never_tidy_for_dir(directory): 349*7594170eSAndroid Build Coastguard Worker # should stay up to date with https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/config/tidy.go;l=227;drc=f5864ba3633fdbadfb434483848887438fc11f59 350*7594170eSAndroid Build Coastguard Worker return directory.startswith("external/grpc-grpc") 351*7594170eSAndroid Build Coastguard Worker 352*7594170eSAndroid Build Coastguard Workerdef clang_tidy_for_dir(allow_external_vendor, directory): 353*7594170eSAndroid Build Coastguard Worker return not _never_tidy_for_dir(directory) and ( 354*7594170eSAndroid Build Coastguard Worker allow_external_vendor or _add_checks_for_dir(directory) != _TIDY_EXTERNAL_VENDOR_CHECKS 355*7594170eSAndroid Build Coastguard Worker ) 356