refactor
This commit is contained in:
+77
-20
@@ -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 user‑provided 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,5 +1,5 @@
|
||||
#include "{{ cls.name }}.proxy.h"
|
||||
#include "rpc/ProxyMarshaller.h"
|
||||
#include "proxy/ProxyMarshaller.h"
|
||||
|
||||
class {{ cls.name }}Proxy::Impl {
|
||||
public:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "rpc/IpcChannel.h"
|
||||
#include "ipc/IpcChannel.h"
|
||||
|
||||
class {{ cls.name }}Proxy {
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user