xref: /llvm-project/clang/utils/module-deps-to-rsp.py (revision e8182029516dae445f21db304953aa5f10880d2d)
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