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