brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 49a1b14 Raw
134 lines · python
1#!/usr/bin/env python2#3# =- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python  -*-=#4#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-exception8#9# ===------------------------------------------------------------------------===#10 11"""12Parallel find-all-symbols runner13================================14 15Runs find-all-symbols over all files in a compilation database.16 17Example invocations.18- Run find-all-symbols on all files in the current working directory.19    run-find-all-symbols.py <source-file>20 21Compilation database setup:22http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html23"""24 25import argparse26import json27import multiprocessing28import os29from queue import Queue30import shutil31import subprocess32import sys33import tempfile34import threading35 36 37def 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)46 47 48def 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)53 54 55def 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()63 64 65def 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_path90    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.j103    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(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 = True114            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 goes127        # bonkers with ctrl-c and we start forking merrily.128        print("\nCtrl-C detected, goodbye.")129        os.kill(0, 9)130 131 132if __name__ == "__main__":133    main()134