1# -*- coding: utf-8 -*- 2# Copyright 2010-2018, Google Inc. 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions are 7# met: 8# 9# * Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# * Redistributions in binary form must reproduce the above 12# copyright notice, this list of conditions and the following disclaimer 13# in the documentation and/or other materials provided with the 14# distribution. 15# * Neither the name of Google Inc. nor the names of its 16# contributors may be used to endorse or promote products derived from 17# this software without specific prior written permission. 18# 19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31"""Script to invoke protoc with considering project root directory. 32 33 % python protoc_wrapper.py \ 34 --protoc_command=protoc \ 35 --protoc_dir=/usr/bin (optional) \ 36 --proto=../protos/my_data.proto \ 37 --proto_path=../protos (optional) \ 38 --cpp_out=../out/debug/gen \ 39 --project_root=../ 40""" 41 42__author__ = "yukawa" 43 44import optparse 45import os 46import subprocess 47import sys 48 49def ParseOption(): 50 """Parse command line options.""" 51 parser = optparse.OptionParser() 52 parser.add_option('--protoc_command', dest='protoc_command', 53 help='executable name of protoc') 54 parser.add_option('--protoc_dir', dest='protoc_dir', 55 help='directory where protoc is located') 56 parser.add_option('--proto', dest='proto', help='path of the *.proto file') 57 parser.add_option('--cpp_out', dest='cpp_out', default='', 58 help='path where cpp files should be generated') 59 parser.add_option('--java_out', dest='java_out', default='', 60 help='path where java files should be generated') 61 parser.add_option('--project_root', dest='project_root', default='.', 62 help='run protoc after moving this directory') 63 parser.add_option('--proto_path', dest='proto_path', default='', 64 help='directory to be passed to --proto_path option') 65 66 (opts, _) = parser.parse_args() 67 68 return opts 69 70 71def main(): 72 """The main function.""" 73 opts = ParseOption() 74 75 # Convert to absolute paths before changing the current directory. 76 project_root = os.path.abspath(opts.project_root) 77 proto_path = os.path.abspath(opts.proto_path) if opts.proto_path else '' 78 cpp_out = os.path.abspath(opts.cpp_out) if opts.cpp_out else '' 79 java_out = os.path.abspath(opts.java_out) if opts.java_out else '' 80 81 protoc_path = opts.protoc_command 82 if opts.protoc_dir: 83 protoc_path = os.path.join(os.path.abspath(opts.protoc_dir), protoc_path) 84 85 # The path of proto file should be transformed as a relative path from 86 # the project root so that correct relative paths should be embedded into 87 # generated files. 88 proto_files = [os.path.relpath(os.path.abspath(p), project_root) 89 for p in opts.proto.split(' ')] 90 91 # Move to the project root. 92 os.chdir(project_root) 93 94 commands = [protoc_path] + proto_files 95 if cpp_out: 96 commands += ['--cpp_out=' + cpp_out] 97 if java_out: 98 commands += ['--java_out=' + java_out] 99 if proto_path: 100 rel_proto_path = os.path.relpath(proto_path, project_root) 101 commands += ['--proto_path=' + rel_proto_path] 102 sys.exit(subprocess.call(commands)) 103 104 105if __name__ == '__main__': 106 main() 107