1#!/usr/bin/env python3 2 3# Converts clang-scan-deps output into response files. 4# * For modules, arguments in the resulting response file are enough to build a PCM. 5# * For translation units, the response file needs to be added to the original Clang invocation from compilation 6# database. 7# 8# Usage: 9# 10# clang-scan-deps -compilation-database compile_commands.json ... > deps.json 11# module-deps-to-rsp.py deps.json --module-name=ModuleName > module_name.cc1.rsp 12# module-deps-to-rsp.py deps.json --tu-index=0 > tu.rsp 13# clang @module_name.cc1.rsp 14# clang ... @tu.rsp 15 16import argparse 17import json 18import sys 19 20class ModuleNotFoundError(Exception): 21 def __init__(self, module_name): 22 self.module_name = module_name 23 24class FullDeps: 25 def __init__(self): 26 self.modules = {} 27 self.translation_units = [] 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 35def parseFullDeps(json): 36 ret = FullDeps() 37 for m in json['modules']: 38 ret.modules[m['name'] + '-' + m['context-hash']] = m 39 ret.translation_units = json['translation-units'] 40 return ret 41 42def quote(str): 43 return '"' + str.replace("\\", "\\\\") + '"' 44 45def main(): 46 parser = argparse.ArgumentParser() 47 parser.add_argument("full_deps_file", help="Path to the full dependencies json file", 48 type=str) 49 action = parser.add_mutually_exclusive_group(required=True) 50 action.add_argument("--module-name", help="The name of the module to get arguments for", 51 type=str) 52 action.add_argument("--tu-index", help="The index of the translation unit to get arguments for", 53 type=int) 54 args = parser.parse_args() 55 56 full_deps = parseFullDeps(json.load(open(args.full_deps_file, 'r'))) 57 58 try: 59 cmd = [] 60 61 if args.module_name: 62 cmd = findModule(args.module_name, full_deps)['command-line'] 63 elif args.tu_index != None: 64 cmd = full_deps.translation_units[args.tu_index]['command-line'] 65 66 print(" ".join(map(quote, cmd))) 67 except: 68 print("Unexpected error:", sys.exc_info()[0]) 69 raise 70 71if __name__ == '__main__': 72 main() 73