diff options
Diffstat (limited to 'clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py')
-rwxr-xr-x | clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py b/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py new file mode 100755 index 00000000..5e9dde72 --- /dev/null +++ b/clang-include-fixer/find-all-symbols/tool/run-find-all-symbols.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +# +#=- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python -*-=# +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +#===------------------------------------------------------------------------===# + +""" +Parallel find-all-symbols runner +================================ + +Runs find-all-symbols over all files in a compilation database. + +Example invocations. +- Run find-all-symbols on all files in the current working directory. + run-find-all-symbols.py <source-file> + +Compilation database setup: +http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html +""" + +import argparse +import json +import multiprocessing +import os +import Queue +import shutil +import subprocess +import sys +import tempfile +import threading + + +def find_compilation_database(path): + """Adjusts the directory until a compilation database is found.""" + result = './' + while not os.path.isfile(os.path.join(result, path)): + if os.path.realpath(result) == '/': + print 'Error: could not find compilation database.' + sys.exit(1) + result += '../' + return os.path.realpath(result) + + +def MergeSymbols(directory, args): + """Merge all symbol files (yaml) in a given directaory into a single file.""" + invocation = [args.binary, '-merge-dir='+directory, args.saving_path] + subprocess.call(invocation) + print 'Merge is finished. Saving results in ' + args.saving_path + + +def run_find_all_symbols(args, tmpdir, build_path, queue): + """Takes filenames out of queue and runs find-all-symbols on them.""" + while True: + name = queue.get() + invocation = [args.binary, name, '-output-dir='+tmpdir, '-p='+build_path] + sys.stdout.write(' '.join(invocation) + '\n') + subprocess.call(invocation) + queue.task_done() + + +def main(): + parser = argparse.ArgumentParser(description='Runs find-all-symbols over all' + 'files in a compilation database.') + parser.add_argument('-binary', metavar='PATH', + default='./bin/find-all-symbols', + help='path to find-all-symbols binary') + parser.add_argument('-j', type=int, default=0, + help='number of instances to be run in parallel.') + parser.add_argument('-p', dest='build_path', + help='path used to read a compilation database.') + parser.add_argument('-saving-path', default='./find_all_symbols_db.yaml', + help='result saving path') + args = parser.parse_args() + + db_path = 'compile_commands.json' + + if args.build_path is not None: + build_path = args.build_path + else: + build_path = find_compilation_database(db_path) + + tmpdir = tempfile.mkdtemp() + + # Load the database and extract all files. + database = json.load(open(os.path.join(build_path, db_path))) + files = [entry['file'] for entry in database] + + max_task = args.j + if max_task == 0: + max_task = multiprocessing.cpu_count() + + try: + # Spin up a bunch of tidy-launching threads. + queue = Queue.Queue(max_task) + for _ in range(max_task): + t = threading.Thread(target=run_find_all_symbols, + args=(args, tmpdir, build_path, queue)) + t.daemon = True + t.start() + + # Fill the queue with files. + for name in files: + queue.put(name) + + # Wait for all threads to be done. + queue.join() + + MergeSymbols(tmpdir, args) + + + except KeyboardInterrupt: + # This is a sad hack. Unfortunately subprocess goes + # bonkers with ctrl-c and we start forking merrily. + print '\nCtrl-C detected, goodbye.' + os.kill(0, 9) + + +if __name__ == '__main__': + main() |