25 from pathlib
import Path
30 RE_INCLUDE_SYSTEM = re.compile(
"\s*-I\s+/usr/[^ ]+")
37 bazel_options = shlex.split(os.environ.get(
"BAZEL_BUILD_OPTIONS",
"")) + [
39 "--remote_download_outputs=all",
42 subprocess.check_call([
"bazel",
"build"] + bazel_options + [
43 "--aspects=@bazel_compdb//:aspects.bzl%compilation_database_aspect",
44 "--output_groups=compdb_files,header_files"
45 ] + args.bazel_targets)
47 execroot = subprocess.check_output([
"bazel",
"info",
"execution_root"] +
48 bazel_options).
decode().strip()
51 for compdb_file
in Path(execroot).glob(
"**/*.compile_commands.json"):
55 compdb_file.read_text().replace(
"__EXEC_ROOT__", execroot) +
58 if args.dedup_targets:
59 compdb_map = {target[
"file"]: target
for target
in compdb}
60 compdb = list(compdb_map.values())
66 for ext
in (
".h",
".hh",
".hpp",
".hxx"):
67 if filename.endswith(ext):
73 filename = target[
"file"]
74 if not args.include_headers
and isHeader(filename):
76 if not args.include_genfiles:
77 if filename.startswith(
"bazel-out/"):
79 if not args.include_external:
80 if filename.startswith(
"external/"):
86 cc, options = target[
"command"].
split(
" ", 1)
90 options = options.replace(
"-std=c++0x ",
"")
91 options = options.replace(
"-std=c++14 ",
"")
94 options +=
" -DNDEBUG"
99 options = options.replace(
"-iquote ",
"-I ")
101 if args.ignore_system_headers:
103 options = RE_INCLUDE_SYSTEM.sub(
"", options)
106 options +=
" -Wno-pragma-once-outside-header -Wno-unused-const-variable"
107 options +=
" -Wno-unused-function"
108 if not target[
"file"].startswith(
"external/"):
110 options =
"-x c++ -std=c++14 -fexceptions " + options
112 target[
"command"] =
" ".join([cc, options])
123 with open(
"compile_commands.json",
"w")
as db_file:
124 json.dump(db, db_file, indent=2)
127 if __name__ ==
"__main__":
128 parser = argparse.ArgumentParser(
129 description=
'Generate JSON compilation database')
130 parser.add_argument(
'--include_external', action=
'store_true')
131 parser.add_argument(
'--include_genfiles', action=
'store_true')
132 parser.add_argument(
'--include_headers', action=
'store_true')
133 parser.add_argument(
'--vscode', action=
'store_true')
134 parser.add_argument(
'--ignore_system_headers', action=
'store_true')
135 parser.add_argument(
'--dedup_targets', action=
'store_true')
136 parser.add_argument(
'bazel_targets', nargs=
'*', default=[
"//..."])
137 args = parser.parse_args()