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:
Executable
+64
@@ -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
@@ -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')
|
||||
|
||||
@@ -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__':
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user