This commit is contained in:
Сергей Маринкевич
2025-12-02 19:18:36 +07:00
parent 4433568545
commit 785fca07f1
15 changed files with 140 additions and 62 deletions
+77 -20
View File
@@ -73,11 +73,22 @@ def load_compile_flags(compile_commands_path, src_path):
if skip_next:
skip_next = False
continue
if tok.endswith('g++') or tok.endswith('clang++') or tok.endswith('clang') or tok.endswith('g++') or tok.endswith('cc'):
# skip the compiler binary itself
if (
tok.endswith("g++")
or tok.endswith("clang++")
or tok.endswith("clang")
or tok.endswith("cc")
or tok.endswith("c++")
):
continue
if tok == "-c":
skip_next = True
continue
# drop output file flag: -o <file>
if tok == "-o":
skip_next = True
continue
filtered.append(tok)
return filtered
return []
@@ -183,7 +194,13 @@ def main():
p = argparse.ArgumentParser()
p.add_argument("--out-dir", "-o", required=True)
p.add_argument("--compile-commands", "-c", default=None)
p.add_argument("inputs", nargs="+")
p.add_argument("--header", required=True, help="C++ header file to scan for exported RPC classes")
p.add_argument("--source", required=True, help="C++ source file to use for resolving compile flags (from compile_commands.json)")
p.add_argument(
"--out-base",
required=True,
help="Base name for generated files: <out-base>.proxy.[h|cpp], <out-base>.skeleton.[h|cpp]",
)
p.add_argument("--templates", "-t", default=os.path.join(os.path.dirname(__file__), "templates"))
args = p.parse_args()
@@ -199,28 +216,68 @@ def main():
except Exception as e:
print("WARNING: cannot set libclang path:", e)
# determine compile flags from the source file (which is what appears in compile_commands.json)
if not os.path.exists(args.header):
print("ERROR: header file not found:", args.header)
return 1
if not os.path.exists(args.source):
print("ERROR: source file not found:", args.source)
return 1
compile_args = load_compile_flags(args.compile_commands, args.source)
if not any(a.startswith("-x") for a in compile_args):
compile_args = ["-x", "c++", "-std=c++17"] + compile_args
print("Parsing", args.header, "with args:", compile_args)
index = Index.create()
all_classes = []
classes = parse_file(index, args.header, compile_args)
for inp in args.inputs:
if not os.path.exists(inp):
print("WARN: input file not found:", inp)
continue
compile_args = load_compile_flags(args.compile_commands, inp)
# ensure -x c++ if missing
if not any(a.startswith("-x") for a in compile_args):
compile_args = ["-x", "c++", "-std=c++17"] + compile_args
print("Parsing", inp, "with args:", compile_args)
classes = parse_file(index, inp, compile_args)
all_classes.extend(classes)
if not all_classes:
print("No exported classes/methods found. Nothing to generate.")
if not classes:
print("No exported classes/methods found in header. Nothing to generate.")
return 0
# render templates
render_templates(all_classes, out_dir, args.templates)
print("Generated files for classes:", ", ".join(c.name for c in all_classes))
# For this PoC we expect a single exported service per header.
# If there are multiple, refuse to guess which one should define the filenames.
if len(classes) > 1:
print(
"ERROR: multiple exported classes found in header; "
"current generator expects exactly one when using --out-base."
)
for c in classes:
print(" -", c.name)
return 1
# render templates using the single discovered class but the userprovided base name
cls = classes[0]
env = Environment(
loader=FileSystemLoader(args.templates),
autoescape=False,
trim_blocks=True,
lstrip_blocks=True,
)
proxy_h = env.get_template("proxy.h.j2")
proxy_cpp = env.get_template("proxy.cpp.j2")
skeleton_h = env.get_template("skeleton.h.j2")
skeleton_cpp = env.get_template("skeleton.cpp.j2")
base = args.out_base
with open(f"{out_dir}/{base}.proxy.h", "w") as f:
f.write(proxy_h.render(cls=cls))
with open(f"{out_dir}/{base}.proxy.cpp", "w") as f:
f.write(proxy_cpp.render(cls=cls))
with open(f"{out_dir}/{base}.skeleton.h", "w") as f:
f.write(skeleton_h.render(cls=cls))
with open(f"{out_dir}/{base}.skeleton.cpp", "w") as f:
f.write(skeleton_cpp.render(cls=cls))
print("Generated files for class", cls.name, "into base", base)
return 0
if __name__ == "__main__":
+1 -1
View File
@@ -1,5 +1,5 @@
#include "{{ cls.name }}.proxy.h"
#include "rpc/ProxyMarshaller.h"
#include "proxy/ProxyMarshaller.h"
class {{ cls.name }}Proxy::Impl {
public:
+1 -1
View File
@@ -1,6 +1,6 @@
#pragma once
#include "rpc/IpcChannel.h"
#include "ipc/IpcChannel.h"
class {{ cls.name }}Proxy {
public: