1#!/usr/bin/env python3 2# Copyright (C) 2018 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16from __future__ import absolute_import 17from __future__ import division 18from __future__ import print_function 19import os 20import re 21import argparse 22import tempfile 23import subprocess 24from compat import iteritems 25 26SOURCE_TARGET = [ 27 ('protos/perfetto/trace_processor/trace_processor.proto', 28 'python/perfetto/trace_processor/trace_processor.descriptor'), 29 ('protos/perfetto/metrics/metrics.proto', 30 'python/perfetto/trace_processor/metrics.descriptor'), 31] 32 33ROOT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) 34 35SCRIPT_PATH = 'tools/gen_binary_descriptors' 36 37 38def find_protoc(): 39 for root, _, files in os.walk(os.path.join(ROOT_DIR, 'out')): 40 if 'protoc' in files: 41 return os.path.join(root, 'protoc') 42 return None 43 44 45def generate(source, target, protoc_path, check_only): 46 # delete=False + manual unlink is required for Windows. Otherwise the temp 47 # file is kept locked exclusively and unaccassible until it's destroyed. 48 with tempfile.NamedTemporaryFile(delete=False) as fdescriptor: 49 subprocess.check_call([ 50 protoc_path, 51 '--include_imports', 52 '--proto_path=.', 53 '--proto_path=' + \ 54 os.path.join(ROOT_DIR, "buildtools", "protobuf", "src"), 55 '--descriptor_set_out={}'.format(fdescriptor.name), 56 source, 57 ], cwd=ROOT_DIR) 58 59 s = fdescriptor.read() 60 fdescriptor.close() 61 os.remove(fdescriptor.name) 62 63 if check_only: 64 with open(target, 'rb') as old: 65 old_content = old.read() 66 if (s != old_content): 67 raise AssertionError('Target {} does not match', target) 68 return 69 70 with open(target, 'wb') as out: 71 out.write(s) 72 73 74def main(): 75 parser = argparse.ArgumentParser() 76 parser.add_argument('--check-only', action='store_true') 77 parser.add_argument('--protoc') 78 args = parser.parse_args() 79 80 try: 81 for source, target in SOURCE_TARGET: 82 protoc = args.protoc or find_protoc() 83 assert protoc, 'protoc not found specific (--protoc PROTOC_PATH)' 84 assert os.path.exists(protoc), '{} does not exist'.format(protoc) 85 if protoc is not args.protoc: 86 print('Using protoc: {}'.format(protoc)) 87 generate(source, target, protoc, args.check_only) 88 except AssertionError as e: 89 if not str(e): 90 raise 91 print('Error: {}'.format(e)) 92 return 1 93 94 95if __name__ == '__main__': 96 exit(main()) 97