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