[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang-tools-extra / clang-include-fixer / find-all-symbols / tool / run-find-all-symbols.py
blob471dbf8c110b433e8fd29387712036d867f0c9dc
1 #!/usr/bin/env python
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 # ===------------------------------------------------------------------------===#
11 """
12 Parallel find-all-symbols runner
13 ================================
15 Runs find-all-symbols over all files in a compilation database.
17 Example invocations.
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
23 """
25 import argparse
26 import json
27 import multiprocessing
28 import os
29 import Queue
30 import shutil
31 import subprocess
32 import sys
33 import tempfile
34 import threading
37 def find_compilation_database(path):
38 """Adjusts the directory until a compilation database is found."""
39 result = "./"
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.")
43 sys.exit(1)
44 result += "../"
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."""
57 while True:
58 name = queue.get()
59 invocation = [args.binary, name, "-output-dir=" + tmpdir, "-p=" + build_path]
60 sys.stdout.write(" ".join(invocation) + "\n")
61 subprocess.call(invocation)
62 queue.task_done()
65 def main():
66 parser = argparse.ArgumentParser(
67 description="Runs find-all-symbols over all" "files in a compilation database."
69 parser.add_argument(
70 "-binary",
71 metavar="PATH",
72 default="./bin/find-all-symbols",
73 help="path to find-all-symbols binary",
75 parser.add_argument(
76 "-j", type=int, default=0, help="number of instances to be run in parallel."
78 parser.add_argument(
79 "-p", dest="build_path", help="path used to read a compilation database."
81 parser.add_argument(
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
90 else:
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")]
102 max_task = args.j
103 if max_task == 0:
104 max_task = multiprocessing.cpu_count()
106 try:
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)
113 t.daemon = True
114 t.start()
116 # Fill the queue with files.
117 for name in files:
118 queue.put(name)
120 # Wait for all threads to be done.
121 queue.join()
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.")
129 os.kill(0, 9)
132 if __name__ == "__main__":
133 main()