mirror of https://github.com/grpc/grpc.git
Merge pull request #24193 from veblush/clang-tidy
Improve clang tidy to use compilation DBpull/23533/head^2
commit
09ace01cc1
22 changed files with 242 additions and 77 deletions
@ -1,20 +0,0 @@ |
||||
-Wall |
||||
-Wc++-compat |
||||
-I. |
||||
-Igens |
||||
-Iinclude |
||||
-Isrc/core/ext/upb-generated |
||||
-Ithird_party/abseil-cpp |
||||
-Ithird_party/address_sorting/include |
||||
-Ithird_party/benchmark/include |
||||
-Ithird_party/boringssl-with-bazel/src/include |
||||
-Ithird_party/cares |
||||
-Ithird_party/cares/cares |
||||
-Ithird_party/googletest |
||||
-Ithird_party/googletest/googlemock/include |
||||
-Ithird_party/googletest/googletest/include |
||||
-Ithird_party/googletest/include |
||||
-Ithird_party/protobuf/src |
||||
-Ithird_party/re2 |
||||
-Ithird_party/upb |
||||
-Ithird_party/zlib |
@ -0,0 +1,135 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
# Copyright 2020 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
# This is based on the script on the Envoy project |
||||
# https://github.com/envoyproxy/envoy/blob/master/tools/gen_compilation_database.py |
||||
|
||||
import argparse |
||||
import glob |
||||
import json |
||||
import logging |
||||
import os |
||||
import re |
||||
import shlex |
||||
import subprocess |
||||
from pathlib import Path |
||||
|
||||
RE_INCLUDE_SYSTEM = re.compile("\s*-I\s+/usr/[^ ]+") |
||||
|
||||
|
||||
# This method is equivalent to https://github.com/grailbio/bazel-compilation-database/blob/master/generate.sh |
||||
def generateCompilationDatabase(args): |
||||
# We need to download all remote outputs for generated source code. |
||||
# This option lives here to override those specified in bazelrc. |
||||
bazel_options = shlex.split(os.environ.get("BAZEL_BUILD_OPTIONS", "")) + [ |
||||
"--config=compdb", |
||||
"--remote_download_outputs=all", |
||||
] |
||||
|
||||
subprocess.check_call(["bazel", "build"] + bazel_options + [ |
||||
"--aspects=@bazel_compdb//:aspects.bzl%compilation_database_aspect", |
||||
"--output_groups=compdb_files,header_files" |
||||
] + args.bazel_targets) |
||||
|
||||
execroot = subprocess.check_output(["bazel", "info", "execution_root"] + |
||||
bazel_options).decode().strip() |
||||
|
||||
compdb = [] |
||||
for compdb_file in Path(execroot).glob("**/*.compile_commands.json"): |
||||
compdb.extend( |
||||
json.loads( |
||||
"[" + |
||||
compdb_file.read_text().replace("__EXEC_ROOT__", execroot) + |
||||
"]")) |
||||
|
||||
if args.dedup_targets: |
||||
compdb_map = {target["file"]: target for target in compdb} |
||||
compdb = list(compdb_map.values()) |
||||
|
||||
return compdb |
||||
|
||||
|
||||
def isHeader(filename): |
||||
for ext in (".h", ".hh", ".hpp", ".hxx"): |
||||
if filename.endswith(ext): |
||||
return True |
||||
return False |
||||
|
||||
|
||||
def isCompileTarget(target, args): |
||||
filename = target["file"] |
||||
if not args.include_headers and isHeader(filename): |
||||
return False |
||||
if not args.include_genfiles: |
||||
if filename.startswith("bazel-out/"): |
||||
return False |
||||
if not args.include_external: |
||||
if filename.startswith("external/"): |
||||
return False |
||||
return True |
||||
|
||||
|
||||
def modifyCompileCommand(target, args): |
||||
cc, options = target["command"].split(" ", 1) |
||||
|
||||
# Workaround for bazel added C++11 options, those doesn't affect build itself but |
||||
# clang-tidy will misinterpret them. |
||||
options = options.replace("-std=c++0x ", "") |
||||
options = options.replace("-std=c++11 ", "") |
||||
|
||||
if args.vscode: |
||||
# Visual Studio Code doesn't seem to like "-iquote". Replace it with |
||||
# old-style "-I". |
||||
options = options.replace("-iquote ", "-I ") |
||||
|
||||
if args.ignore_system_headers: |
||||
# Remove all include options for /usr/* directories |
||||
options = RE_INCLUDE_SYSTEM.sub("", options) |
||||
|
||||
if isHeader(target["file"]): |
||||
options += " -Wno-pragma-once-outside-header -Wno-unused-const-variable" |
||||
options += " -Wno-unused-function" |
||||
if not target["file"].startswith("external/"): |
||||
# *.h file is treated as C header by default while our headers files are all C++11. |
||||
options = "-x c++ -std=c++11 -fexceptions " + options |
||||
|
||||
target["command"] = " ".join([cc, options]) |
||||
return target |
||||
|
||||
|
||||
def fixCompilationDatabase(args, db): |
||||
db = [ |
||||
modifyCompileCommand(target, args) |
||||
for target in db |
||||
if isCompileTarget(target, args) |
||||
] |
||||
|
||||
with open("compile_commands.json", "w") as db_file: |
||||
json.dump(db, db_file, indent=2) |
||||
|
||||
|
||||
if __name__ == "__main__": |
||||
parser = argparse.ArgumentParser( |
||||
description='Generate JSON compilation database') |
||||
parser.add_argument('--include_external', action='store_true') |
||||
parser.add_argument('--include_genfiles', action='store_true') |
||||
parser.add_argument('--include_headers', action='store_true') |
||||
parser.add_argument('--vscode', action='store_true') |
||||
parser.add_argument('--ignore_system_headers', action='store_true') |
||||
parser.add_argument('--dedup_targets', action='store_true') |
||||
parser.add_argument('bazel_targets', nargs='*', default=["//..."]) |
||||
args = parser.parse_args() |
||||
fixCompilationDatabase(args, generateCompilationDatabase(args)) |
Loading…
Reference in new issue