|
1 | 1 | #!/usr/bin/env python
|
2 | 2 | #
|
3 |
| -#=- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python -*-=# |
| 3 | +# =- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python -*-=# |
4 | 4 | #
|
5 | 5 | # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
6 | 6 | # See https://llvm.org/LICENSE.txt for license information.
|
7 | 7 | # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
8 | 8 | #
|
9 |
| -#===------------------------------------------------------------------------===# |
| 9 | +# ===------------------------------------------------------------------------===# |
10 | 10 |
|
11 | 11 | """
|
12 | 12 | Parallel find-all-symbols runner
|
|
35 | 35 |
|
36 | 36 |
|
37 | 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) |
| 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) |
46 | 46 |
|
47 | 47 |
|
48 | 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) |
| 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) |
53 | 53 |
|
54 | 54 |
|
55 | 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() |
| 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() |
63 | 63 |
|
64 | 64 |
|
65 | 65 | def main():
|
66 |
| - parser = argparse.ArgumentParser(description='Runs find-all-symbols over all' |
67 |
| - 'files in a compilation database.') |
68 |
| - parser.add_argument('-binary', metavar='PATH', |
69 |
| - default='./bin/find-all-symbols', |
70 |
| - help='path to find-all-symbols binary') |
71 |
| - parser.add_argument('-j', type=int, default=0, |
72 |
| - help='number of instances to be run in parallel.') |
73 |
| - parser.add_argument('-p', dest='build_path', |
74 |
| - help='path used to read a compilation database.') |
75 |
| - parser.add_argument('-saving-path', default='./find_all_symbols_db.yaml', |
76 |
| - help='result saving path') |
77 |
| - args = parser.parse_args() |
78 |
| - |
79 |
| - db_path = 'compile_commands.json' |
80 |
| - |
81 |
| - if args.build_path is not None: |
82 |
| - build_path = args.build_path |
83 |
| - else: |
84 |
| - build_path = find_compilation_database(db_path) |
85 |
| - |
86 |
| - tmpdir = tempfile.mkdtemp() |
87 |
| - |
88 |
| - # Load the database and extract all files. |
89 |
| - database = json.load(open(os.path.join(build_path, db_path))) |
90 |
| - files = [entry['file'] for entry in database] |
91 |
| - |
92 |
| - # Filter out .rc files on Windows. CMake includes them for some reason. |
93 |
| - files = [f for f in files if not f.endswith('.rc')] |
94 |
| - |
95 |
| - max_task = args.j |
96 |
| - if max_task == 0: |
97 |
| - max_task = multiprocessing.cpu_count() |
98 |
| - |
99 |
| - try: |
100 |
| - # Spin up a bunch of tidy-launching threads. |
101 |
| - queue = Queue.Queue(max_task) |
102 |
| - for _ in range(max_task): |
103 |
| - t = threading.Thread(target=run_find_all_symbols, |
104 |
| - args=(args, tmpdir, build_path, queue)) |
105 |
| - t.daemon = True |
106 |
| - t.start() |
107 |
| - |
108 |
| - # Fill the queue with files. |
109 |
| - for name in files: |
110 |
| - queue.put(name) |
111 |
| - |
112 |
| - # Wait for all threads to be done. |
113 |
| - queue.join() |
114 |
| - |
115 |
| - MergeSymbols(tmpdir, args) |
116 |
| - |
117 |
| - |
118 |
| - except KeyboardInterrupt: |
119 |
| - # This is a sad hack. Unfortunately subprocess goes |
120 |
| - # bonkers with ctrl-c and we start forking merrily. |
121 |
| - print('\nCtrl-C detected, goodbye.') |
122 |
| - os.kill(0, 9) |
123 |
| - |
124 |
| - |
125 |
| -if __name__ == '__main__': |
126 |
| - main() |
| 66 | + parser = argparse.ArgumentParser( |
| 67 | + description="Runs find-all-symbols over all" "files in a compilation database." |
| 68 | + ) |
| 69 | + parser.add_argument( |
| 70 | + "-binary", |
| 71 | + metavar="PATH", |
| 72 | + default="./bin/find-all-symbols", |
| 73 | + help="path to find-all-symbols binary", |
| 74 | + ) |
| 75 | + parser.add_argument( |
| 76 | + "-j", type=int, default=0, help="number of instances to be run in parallel." |
| 77 | + ) |
| 78 | + parser.add_argument( |
| 79 | + "-p", dest="build_path", help="path used to read a compilation database." |
| 80 | + ) |
| 81 | + parser.add_argument( |
| 82 | + "-saving-path", default="./find_all_symbols_db.yaml", help="result saving path" |
| 83 | + ) |
| 84 | + args = parser.parse_args() |
| 85 | + |
| 86 | + db_path = "compile_commands.json" |
| 87 | + |
| 88 | + if args.build_path is not None: |
| 89 | + build_path = args.build_path |
| 90 | + else: |
| 91 | + build_path = find_compilation_database(db_path) |
| 92 | + |
| 93 | + tmpdir = tempfile.mkdtemp() |
| 94 | + |
| 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] |
| 98 | + |
| 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")] |
| 101 | + |
| 102 | + max_task = args.j |
| 103 | + if max_task == 0: |
| 104 | + max_task = multiprocessing.cpu_count() |
| 105 | + |
| 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) |
| 112 | + ) |
| 113 | + t.daemon = True |
| 114 | + t.start() |
| 115 | + |
| 116 | + # Fill the queue with files. |
| 117 | + for name in files: |
| 118 | + queue.put(name) |
| 119 | + |
| 120 | + # Wait for all threads to be done. |
| 121 | + queue.join() |
| 122 | + |
| 123 | + MergeSymbols(tmpdir, args) |
| 124 | + |
| 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) |
| 130 | + |
| 131 | + |
| 132 | +if __name__ == "__main__": |
| 133 | + main() |
0 commit comments