build: add capnp compiler wrapper

we need this to generate dependency information, and it'll be the entry
point for custom codegen once we need it. a wrapper also makes it a lot
easier to generate a whole namespace's worth of rpc definitions at once

Change-Id: Iba7a1c92a8a40bede9ed71aa3ab455477ff5e568
This commit is contained in:
eldritch horrors
2025-07-15 06:40:48 +00:00
parent ea11d075e6
commit ca12657a68
4 changed files with 92 additions and 2 deletions
+64
View File
@@ -0,0 +1,64 @@
#!@python@
import argparse
import capnp
from pathlib import Path
import os
import subprocess
import sys
if lang := os.environ.get('lix_capnp_lang'):
outputs = os.environ['lix_capnp_outputs'].split()
old_cwd = os.environ['lix_capnp_old_cwd']
schema = capnp.load('@capnp_include@/capnp/schema.capnp', imports=['@capnp_include@'])
request = schema.CodeGeneratorRequest.read(sys.stdin)
subprocess.run([lang], input=request.as_builder().to_bytes()).check_returncode()
base_dir = os.getcwd()
os.chdir(old_cwd)
include = [ str(Path(p).resolve()) for p in os.environ['lix_capnp_include'].split(':') ]
if depfile := os.environ['lix_capnp_depfile']:
deps = ""
for input in request.requestedFiles:
deps += " ".join(f"{input.filename}.{o}" for o in outputs)
deps += ":"
for dep in input.imports:
if dep.name.startswith("/"):
for candidate in (Path(i + dep.name) for i in include):
if candidate.exists():
deps += " " + str(candidate)
break
else:
raise RuntimeError("not handling relative includes")
deps += "\n\n"
Path(depfile).write_text(deps)
else:
parser = argparse.ArgumentParser()
parser.add_argument('--language')
parser.add_argument('--outdir')
parser.add_argument('--src-prefix')
parser.add_argument('--depfile', default="")
parser.add_argument('-I', '--include', action='append', default=['@capnp_include@'])
parser.add_argument('inputs', nargs='+')
args = parser.parse_args()
for infile in args.inputs:
os.environ['lix_capnp_lang'] = f"capnpc-{args.language}"
os.environ['lix_capnp_include'] = ':'.join(args.include)
os.environ['lix_capnp_depfile'] = args.depfile
os.environ['lix_capnp_old_cwd'] = os.getcwd()
if args.language == "c++":
os.environ['lix_capnp_outputs'] = "c++ h"
else:
raise RuntimeError("unknown language " + args.language)
subprocess.run([
'@capnp@',
'compile',
f'-o{sys.argv[0]}:{args.outdir}',
f'--src-prefix={args.src_prefix}',
*(f"-I{i}" for i in args.include),
infile
]).check_returncode()
+16
View File
@@ -248,6 +248,7 @@ configdata += {
boost = dependency('boost', required : true, modules : ['container'], include_type : 'system')
kj = dependency('kj-async', required : true, include_type : 'system')
capnp_rpc = dependency('capnp-rpc', required : true, include_type : 'system')
# cpuid only makes sense on x86_64
cpuid_required = is_x64 ? get_option('cpuid') : false
@@ -628,6 +629,21 @@ if is_darwin
)
endif
capnpc_wrapper = custom_target(
'capnpc_wrapper',
command : ['cp', '@INPUT@', '@OUTPUT@'],
input : configure_file(
input : 'lix/code-generation/capnpc_wrapper.py',
output : 'capnpc_wrapper.configured',
configuration : {
'capnp_include' : capnp_rpc.get_variable(pkgconfig : 'includedir'),
'capnp' : find_program('capnp', required : true, native : true).full_path(),
'python' : python.full_path(),
},
),
output : 'capnpc_wrapper',
)
subdir('lix')
subdir('scripts')
subdir('misc')
+10 -2
View File
@@ -14,8 +14,16 @@ def main():
args = ap.parse_args()
targets = [t for t in get_targets_of_rule(args.build_root, 'CUSTOM_COMMAND') if t.endswith('.gen.hh')]
targets += [t for t in get_targets_of_rule(args.build_root, 'CUSTOM_COMMAND') if t.endswith('.gen.inc')]
targets = [
t for t in get_targets_of_rule(args.build_root, 'CUSTOM_COMMAND')
if t.endswith('.gen.hh')
] + [
t for t in get_targets_of_rule(args.build_root, 'CUSTOM_COMMAND_DEP')
if t.endswith('.capnp.h')
] + [
t for t in get_targets_of_rule(args.build_root, 'CUSTOM_COMMAND')
if t.endswith('.gen.inc')
]
ninja_build(args.build_root, targets)
if __name__ == '__main__':
+2
View File
@@ -208,6 +208,7 @@ stdenv.mkDerivation (finalAttrs: {
p:
[
p.python-frontmatter
p.pycapnp
]
++ lib.optionals finalAttrs.doCheck [
p.pytest
@@ -560,6 +561,7 @@ stdenv.mkDerivation (finalAttrs: {
p.aiohttp
p.python-frontmatter
p.toml
p.pycapnp
p.yapf
p.requests