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.
		
		
		
		
		
			
		
			
				
	
	
		
			217 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			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)
 |