3 # =- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python -*-=#
5 # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 # See https://llvm.org/LICENSE.txt for license information.
7 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9 # ===------------------------------------------------------------------------===#
12 Parallel find-all-symbols runner
13 ================================
15 Runs find-all-symbols over all files in a compilation database.
18 - Run find-all-symbols on all files in the current working directory.
19 run-find-all-symbols.py <source-file>
21 Compilation database setup:
22 http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
27 import multiprocessing
37 def find_compilation_database(path
):
38 """Adjusts the directory until a compilation database is found."""
40 while not os
.path
.isfile(os
.path
.join(result
, path
)):
41 if os
.path
.realpath(result
) == "/":
42 print("Error: could not find compilation database.")
45 return os
.path
.realpath(result
)
48 def MergeSymbols(directory
, args
):
49 """Merge all symbol files (yaml) in a given directory into a single file."""
50 invocation
= [args
.binary
, "-merge-dir=" + directory
, args
.saving_path
]
51 subprocess
.call(invocation
)
52 print("Merge is finished. Saving results in " + args
.saving_path
)
55 def run_find_all_symbols(args
, tmpdir
, build_path
, queue
):
56 """Takes filenames out of queue and runs find-all-symbols on them."""
59 invocation
= [args
.binary
, name
, "-output-dir=" + tmpdir
, "-p=" + build_path
]
60 sys
.stdout
.write(" ".join(invocation
) + "\n")
61 subprocess
.call(invocation
)
66 parser
= argparse
.ArgumentParser(
67 description
="Runs find-all-symbols over all" "files in a compilation database."
72 default
="./bin/find-all-symbols",
73 help="path to find-all-symbols binary",
76 "-j", type=int, default
=0, help="number of instances to be run in parallel."
79 "-p", dest
="build_path", help="path used to read a compilation database."
82 "-saving-path", default
="./find_all_symbols_db.yaml", help="result saving path"
84 args
= parser
.parse_args()
86 db_path
= "compile_commands.json"
88 if args
.build_path
is not None:
89 build_path
= args
.build_path
91 build_path
= find_compilation_database(db_path
)
93 tmpdir
= tempfile
.mkdtemp()
95 # Load the database and extract all files.
96 database
= json
.load(open(os
.path
.join(build_path
, db_path
)))
97 files
= [entry
["file"] for entry
in database
]
99 # Filter out .rc files on Windows. CMake includes them for some reason.
100 files
= [f
for f
in files
if not f
.endswith(".rc")]
104 max_task
= multiprocessing
.cpu_count()
107 # Spin up a bunch of tidy-launching threads.
108 queue
= Queue
.Queue(max_task
)
109 for _
in range(max_task
):
110 t
= threading
.Thread(
111 target
=run_find_all_symbols
, args
=(args
, tmpdir
, build_path
, queue
)
116 # Fill the queue with files.
120 # Wait for all threads to be done.
123 MergeSymbols(tmpdir
, args
)
125 except KeyboardInterrupt:
126 # This is a sad hack. Unfortunately subprocess goes
127 # bonkers with ctrl-c and we start forking merrily.
128 print("\nCtrl-C detected, goodbye.")
132 if __name__
== "__main__":