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 17class ModuleNotFoundError(Exception): 18 def __init__(self, module_name): 19 self.module_name = module_name 20 21class FullDeps: 22 def __init__(self): 23 self.modules = {} 24 self.translation_units = [] 25 26def findModule(module_name, full_deps): 27 for m in full_deps.modules.values(): 28 if m['name'] == module_name: 29 return m 30 raise ModuleNotFoundError(module_name) 31 32def parseFullDeps(json): 33 ret = FullDeps() 34 for m in json['modules']: 35 ret.modules[m['name'] + '-' + m['context-hash']] = m 36 ret.translation_units = json['translation-units'] 37 return ret 38 39def quote(str): 40 return '"' + str.replace("\\", "\\\\") + '"' 41 42def main(): 43 parser = argparse.ArgumentParser() 44 parser.add_argument("full_deps_file", help="Path to the full dependencies json file", 45 type=str) 46 action = parser.add_mutually_exclusive_group(required=True) 47 action.add_argument("--module-name", help="The name of the module to get arguments for", 48 type=str) 49 action.add_argument("--tu-index", help="The index of the translation unit to get arguments for", 50 type=int) 51 args = parser.parse_args() 52 53 full_deps = parseFullDeps(json.load(open(args.full_deps_file, 'r'))) 54 55 try: 56 cmd = [] 57 58 if args.module_name: 59 cmd = findModule(args.module_name, full_deps)['command-line'] 60 elif args.tu_index != None: 61 cmd = full_deps.translation_units[args.tu_index]['command-line'] 62 63 print(" ".join(map(quote, cmd))) 64 except: 65 print("Unexpected error:", sys.exc_info()[0]) 66 raise 67 68if __name__ == '__main__': 69 main() 70