xref: /aosp_15_r20/external/perfetto/tools/gen_binary_descriptors (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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