You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libshit/misc/wscript_capnproto

217 lines
8.3 KiB
Python

# -*- python -*-
# against v0.8.0 57a4ca5af5a7f55b768a9d9d6655250bffb1257f
def options(ctx):
ctx.system_opt('capnproto')
grp = ctx.add_option_group('Dependency selection options')
grp.add_option('--system-capnpc', action='store_true', default=False,
help='Use system capnpc, even when bundling capnproto. '
'Speeds up build, but the system must have the EXACT same '
'capnproto version installed.')
def configure(ctx):
def find_tools(ctx):
ctx.find_program('capnpc', var='CAPNPC')
ctx.find_program('capnpc-c++', var='CAPNPC_CPP')
def system_capnproto(ctx):
ctx.check_cfg(package='capnp', args='--cflags --libs',
global_define=True)
ctx.undefine('HAVE_CAPNP')
find_tools(ctx)
def bundle_capnproto(ctx):
ctx.env.append_value('DEFINES_CAPNP', 'CAPNP_LITE')
ctx.env.append_value('SYSTEM_INCLUDES_CAPNP',
ctx.path.find_dir('capnproto/c++/src').abspath())
if ctx.options.system_capnpc:
find_tools(ctx)
ctx.with_chk('capnproto',
{'system': system_capnproto, 'bundle': bundle_capnproto})
ctx.add_os_flags('CAPNPCFLAGS')
def build(ctx):
if ctx.env.WITH_CAPNPROTO != 'bundle': return
src = [
'capnproto/c++/src/kj/arena.c++',
'capnproto/c++/src/kj/array.c++',
'capnproto/c++/src/kj/common.c++',
'capnproto/c++/src/kj/debug.c++',
'capnproto/c++/src/kj/encoding.c++', # only needed on windows
'capnproto/c++/src/kj/exception.c++',
'capnproto/c++/src/kj/hash.c++',
'capnproto/c++/src/kj/io.c++',
'capnproto/c++/src/kj/main.c++',
'capnproto/c++/src/kj/memory.c++',
'capnproto/c++/src/kj/mutex.c++',
'capnproto/c++/src/kj/string.c++',
'capnproto/c++/src/kj/table.c++',
'capnproto/c++/src/kj/time.c++', # only needed on windows
'capnproto/c++/src/kj/units.c++',
'capnproto/c++/src/capnp/any.c++',
'capnproto/c++/src/capnp/arena.c++',
'capnproto/c++/src/capnp/blob.c++',
'capnproto/c++/src/capnp/c++.capnp.c++',
'capnproto/c++/src/capnp/layout.c++',
'capnproto/c++/src/capnp/message.c++',
'capnproto/c++/src/capnp/schema.capnp.c++',
'capnproto/c++/src/capnp/serialize-packed.c++',
'capnproto/c++/src/capnp/serialize.c++',
]
src_heavy = src + [
# src has #ifdef guard around correct os so we can compile both
'capnproto/c++/src/kj/filesystem-disk-unix.c++',
'capnproto/c++/src/kj/filesystem-disk-win32.c++',
'capnproto/c++/src/kj/filesystem.c++',
'capnproto/c++/src/kj/parse/char.c++',
'capnproto/c++/src/kj/refcount.c++',
'capnproto/c++/src/kj/string-tree.c++',
'capnproto/c++/src/capnp/compat/json.c++',
'capnproto/c++/src/capnp/compat/json.capnp.c++',
'capnproto/c++/src/capnp/dynamic.c++',
'capnproto/c++/src/capnp/schema-loader.c++',
'capnproto/c++/src/capnp/schema-parser.c++',
'capnproto/c++/src/capnp/schema.c++',
'capnproto/c++/src/capnp/serialize-text.c++',
'capnproto/c++/src/capnp/stream.capnp.c++',
'capnproto/c++/src/capnp/stringify.c++',
]
ctx.stlib(idx = 51600,
source = src,
includes = 'capnproto/c++/src',
target = 'capnp',
uselib = 'CAPNP EXT')
def build_capnp_tool(ctx, pref):
# breaks with -fsanitize unless -fno-rtti is also used
# todo: figure out how to disable -fsanitize for this as it produces
# shittons of errors
ctx.stlib(idx = 51601,
source = src_heavy,
includes = 'capnproto/c++/src',
target = 'capnp_heavy',
uselib = 'EXT',
cxxflags = '-fno-rtti')
src = [
'capnproto/c++/src/capnp/compiler/capnp.c++',
'capnproto/c++/src/capnp/compiler/compiler.c++',
'capnproto/c++/src/capnp/compiler/error-reporter.c++',
'capnproto/c++/src/capnp/compiler/generics.c++',
'capnproto/c++/src/capnp/compiler/grammar.capnp.c++',
'capnproto/c++/src/capnp/compiler/lexer.c++',
'capnproto/c++/src/capnp/compiler/lexer.capnp.c++',
'capnproto/c++/src/capnp/compiler/module-loader.c++',
'capnproto/c++/src/capnp/compiler/node-translator.c++',
'capnproto/c++/src/capnp/compiler/parser.c++',
'capnproto/c++/src/capnp/compiler/type-id.c++',
]
ctx.program(idx = 51602,
source = src,
includes = 'capnproto/c++/src',
use = 'capnp_heavy',
uselib = 'EXT WINDOWS_CLI',
target = 'capnpc',
cxxflags = '-fno-rtti')
ctx.program(idx = 51603,
source = 'capnproto/c++/src/capnp/compiler/capnpc-c++.c++',
includes = 'capnproto/c++/src',
use = 'capnp_heavy',
uselib = 'EXT WINDOWS_CLI',
target = 'capnpc-c++',
cxxflags = '-fno-rtti')
if not ctx.env.CAPNPC:
ctx.in_host_env(build_capnp_tool)
import re
from waflib import Task
proto_re = re.compile('_([a-z0-9])')
import_re = re.compile('import +"([^\\"]*)\.o"')
cpp_re = re.compile('( |::)(get|set|has|is|init|adopt|disown|as)([A-Z])')
include_re = re.compile(r'^(#include ".*)\.o\.h"$', re.MULTILINE)
sys_include_re = re.compile(r'^(#include <.*>)$', re.MULTILINE)
undef_guard = '''
#pragma GCC diagnostic push
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wundef"
\\1
#pragma GCC diagnostic pop
'''
class capnp(Task.Task):
color = 'BLUE'
vars = ['CAPNPCC', 'CAPNPC_CPP', 'CAPNPCFLAGS']
def run(self):
inp = self.inputs[0]
data = inp.read()
data = proto_re.sub(lambda x: x.group(1).upper(), data)
out_proto = inp.change_ext('.capnp.o')
out_proto.write(data)
ret = self.exec_command(
[self.capnpc,
*self.flags,
*self.env.CAPNPCFLAGS,
'-o%s:%s' % (self.capnpc_cpp, self.outputs[0].parent.abspath()),
'--src-prefix=%s' % out_proto.parent.abspath(),
out_proto.abspath()])
if ret != 0: return ret
def fix(inp, out):
data = inp.read()
data = include_re.sub(r'\1.hpp"', data)
data = sys_include_re.sub(undef_guard, data)
data = cpp_re.sub(lambda x: x.group(1) + x.group(2).title() + x.group(3), data)
out.write(data)
fix(self.outputs[0].change_ext('.o.c++'), self.outputs[0])
fix(self.outputs[1].change_ext('.o.h'), self.outputs[1])
# parse 'import "foo.capnp.o";' things
# ideally we would only need to depend on the preprocessor step and
# automatically add the .o extension, but whatever
def scan(self):
inp = self.inputs[0]
data = inp.read()
dep = []
missing = []
for i in import_re.findall(data):
r = inp.parent.find_resource(i+'.hpp')
if r:
dep.append(r)
else:
missing.append(i)
return (dep, missing)
from waflib.TaskGen import extension
@extension('.capnp')
def compile_capnp(self, node):
out_cpp = node.change_ext('.capnp.cpp')
out_hpp = node.change_ext('.capnp.hpp')
tsk = self.create_task('capnp', node, [out_cpp, out_hpp])
if self.env.CAPNPC:
tsk.capnpc = self.env.CAPNPC[0]
tsk.capnpc_cpp = self.env.CAPNPC_CPP[0]
tsk.flags = []
else:
capnpc = self.bld.get_tgen_by_name('capnpc').link_task.outputs[0]
capnpc_cpp_tsk = self.bld.get_tgen_by_name('capnpc-c++')
capnpc_cpp = capnpc_cpp_tsk.link_task.outputs[0]
inc = capnpc_cpp_tsk.compiled_tasks[0].inputs[0].find_node('../../..')
tsk.capnpc = capnpc.abspath()
tsk.capnpc_cpp = capnpc_cpp.abspath()
tsk.flags = ['--no-standard-import', '-I%s' % inc.abspath()]
tsk.dep_nodes += [capnpc, capnpc_cpp]
self.source.append(out_cpp)