xref: /openbsd-src/gnu/llvm/clang/utils/module-deps-to-rsp.py (revision 12c855180aad702bbcca06e0398d774beeafb155)
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