1#!/usr/bin/env python3 2 3# Converts clang-scan-deps output into response files. 4# 5# Usage: 6# 7# clang-scan-deps -compilation-database compile_commands.json ... > deps.json 8# module-deps-to-rsp.py deps.json --module-name=ModuleName > module_name.cc1.rsp 9# module-deps-to-rsp.py deps.json --tu-index=0 > tu.rsp 10# clang @module_name.cc1.rsp 11# clang @tu.rsp 12 13import argparse 14import json 15import sys 16 17 18class ModuleNotFoundError(Exception): 19 def __init__(self, module_name): 20 self.module_name = module_name 21 22 23class FullDeps: 24 def __init__(self): 25 self.modules = {} 26 self.translation_units = [] 27 28 29def findModule(module_name, full_deps): 30 for m in full_deps.modules.values(): 31 if m["name"] == module_name: 32 return m 33 raise ModuleNotFoundError(module_name) 34 35 36def parseFullDeps(json): 37 ret = FullDeps() 38 for m in json["modules"]: 39 ret.modules[m["name"] + "-" + m["context-hash"]] = m 40 ret.translation_units = json["translation-units"] 41 return ret 42 43 44def quote(str): 45 return '"' + str.replace("\\", "\\\\") + '"' 46 47 48def main(): 49 parser = argparse.ArgumentParser() 50 parser.add_argument( 51 "full_deps_file", help="Path to the full dependencies json file", type=str 52 ) 53 action = parser.add_mutually_exclusive_group(required=True) 54 action.add_argument( 55 "--module-name", help="The name of the module to get arguments for", type=str 56 ) 57 action.add_argument( 58 "--tu-index", 59 help="The index of the translation unit to get arguments for", 60 type=int, 61 ) 62 parser.add_argument( 63 "--tu-cmd-index", 64 help="The index of the command within the translation unit (default=0)", 65 type=int, 66 default=0, 67 ) 68 args = parser.parse_args() 69 70 full_deps = parseFullDeps(json.load(open(args.full_deps_file, "r"))) 71 72 try: 73 cmd = [] 74 75 if args.module_name: 76 cmd = findModule(args.module_name, full_deps)["command-line"] 77 elif args.tu_index is not None: 78 tu = full_deps.translation_units[args.tu_index] 79 cmd = tu["commands"][args.tu_cmd_index]["command-line"] 80 81 print(" ".join(map(quote, cmd))) 82 except: 83 print("Unexpected error:", sys.exc_info()[0]) 84 raise 85 86 87if __name__ == "__main__": 88 main() 89