scons编译protobuffer脚本代码

scons编译protobuffer脚本代码

protoc.py:

"""
Google's Protoc builder
Example, will produce c++ output files in the src directory.
protoc_cc = env.Protoc(["src/Example.proto"],
    PROTOC_PATH='#src',
    PROTOC_CCOUT='#src',
    )
"""

import os
import SCons.Util
from SCons.Script import Builder, Action, Dir, File, Entry

def _detect(env):
    """Try to find the Protoc compiler"""
    try:
        return env['PROTOC']
    except KeyError:
        pass

    protoc = env.WhereIs('protoc')
    if protoc:
        return protoc

    raise SCons.Errors.StopError(
        "Could not detect protoc Compiler")

def _protoc_emitter(target, source, env):
    """Process target, sources, and flags"""
    
    # always ignore target
    target = []

    # suffix
    protoc_suffix = env.subst('$PROTOC_SUFFIX')
    protoc_h_suffix = env.subst('$PROTOC_HSUFFIX')
    protoc_cc_suffix = env.subst('$PROTOC_CCSUFFIX')
    protoc_py_suffix = env.subst('$PROTOC_PYSUFFIX')
    protoc_java_suffix = env.subst('$PROTOC_JAVASUFFIX')

    # fetch all protoc flags
    if env['PROTOC_FLAGS']:
        protocflags = env.subst("$PROTOC_FLAGS",
            target=target, source=source)
        flags = SCons.Util.CLVar(protocflags)
    else:
        flags = SCons.Util.CLVar('')

    # flag --proto_path, -I
    proto_path = []
    if env['PROTOC_PATH']:
        inc = env['PROTOC_PATH']
        if SCons.Util.is_List(inc):
            for path in inc:
                path = Dir(path)
                #print "path:",path
                proto_path.append(path)
                flags.append('--proto_path='+str(path.abspath))
        elif SCons.Util.is_Scalar(inc):
            path=Dir(inc)
            #print "path:",path
            proto_path.append(path)
            flags.append('--proto_path='+str(path.abspath))

    # flag --cpp_out
    if env['PROTOC_CCOUT']:
        env['PROTOC_CCOUT'] = Dir(env['PROTOC_CCOUT'])
        flags.append('--cpp_out=${PROTOC_CCOUT.abspath}')
    
    # flag --python_out
    if env['PROTOC_PYOUT']:
        env['PROTOC_PYOUT'] = Dir(env['PROTOC_PYOUT'])
        flags.append('--python_out=${PROTOC_PYOUT.abspath}')

    # flag --java_out
    if env['PROTOC_JAVAOUT']:
        env['PROTOC_JAVAOUT'] = Dir(env['PROTOC_JAVAOUT'])
        flags.append('--java_out=${PROTOC_JAVAOUT.abspath}')

    # updated flags
    env['PROTOC_FLAGS'] = str(flags)
    #print "flags:",flags

    # source scons dirs
    src_struct = Dir('#')
    src_script = Dir('.').srcnode()

    # produce proper targets
    for src in source:
        src = File(src)

        # find proto_path for this source
        longest_common = '/'
        for path in proto_path:
            common = os.path.commonprefix([path.abspath, src.abspath])
            if len(common) > len(longest_common):
                longest_common = common
        #print "longest_common:",longest_common

        src_relpath = os.path.relpath(src.abspath, start=longest_common)
        #print "src_relpath:",src_relpath

        # create stem by remove the $PROTOC_SUFFIX or take a guess
        if src_relpath.endswith(protoc_suffix):
            stem = src_relpath[:-len(protoc_suffix)]
        else:
            stem = src_relpath

        # C++ output, append
        if env['PROTOC_CCOUT']:
            out = Dir(env['PROTOC_CCOUT'])
            base = os.path.join(out.abspath, stem)
            target.append(File(base+protoc_cc_suffix))
            target.append(File(base+protoc_h_suffix))

        # python output, append
        if env['PROTOC_PYOUT']:
            out = Dir(env['PROTOC_PYOUT'])
            base = os.path.join(out.abspath, stem)
            target.append(File(base+protoc_py_suffix))

        # java output, append
        if env['PROTOC_JAVAOUT']:
            out = Dir(env['PROTOC_JAVAOUT'])
            base = os.path.join(out.abspath, stem)
            target.append(File(base+protoc_java_suffix))

    #print "targets:",env.subst("${TARGETS}", target=target, source=source)
    #print "sources:",env.subst("${SOURCES}", target=target, source=source)

    return target, source


_protoc_builder = Builder(
        action = Action('$PROTOC_COM', '$PROTOC_COMSTR'),
        suffix = '$PROTOC_CCSUFFIX',
        src_suffix = '$PROTOC_SUFFIX',
        emitter = _protoc_emitter,
        )

def generate(env):
    """Add Builders and construction variables."""
    
    env['PROTOC'] = _detect(env)
    env.SetDefault(

        # Additional command-line flags
        PROTOC_FLAGS = SCons.Util.CLVar(''),

        # Source path(s)
        PROTOC_PATH = SCons.Util.CLVar(''),

        # Output path
        PROTOC_CCOUT = '',
        PROTOC_PYOUT = '',
        PROTOC_JAVAOUT = '',

        # Suffixies / prefixes
        PROTOC_SUFFIX = '.proto',
        PROTOC_HSUFFIX = '.pb.h',
        PROTOC_CCSUFFIX = '.pb.cc',
        PROTOC_PYSUFFIX = '_pb2.py',
        PROTOC_JAVASUFFIX = '.java',

        # Protoc command
        PROTOC_COM = "$PROTOC $PROTOC_FLAGS $SOURCES.abspath",
        PROTOC_COMSTR = '',

        )

    env['BUILDERS']['Protoc'] = _protoc_builder

def exists(env):
    return _detect(env)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值