xref: /aosp_15_r20/external/perfetto/tools/gen_grpc_build_gn.py (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2023 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 Workerimport json
17*6dbdd20aSAndroid Build Coastguard Workerimport os
18*6dbdd20aSAndroid Build Coastguard Workerimport subprocess
19*6dbdd20aSAndroid Build Coastguard Workerimport sys
20*6dbdd20aSAndroid Build Coastguard Workerfrom typing import Any, Dict, List
21*6dbdd20aSAndroid Build Coastguard Workerimport yaml
22*6dbdd20aSAndroid Build Coastguard Worker
23*6dbdd20aSAndroid Build Coastguard WorkerROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
24*6dbdd20aSAndroid Build Coastguard Worker
25*6dbdd20aSAndroid Build Coastguard WorkerGRPC_GN_HEADER = '''
26*6dbdd20aSAndroid Build Coastguard Worker#
27*6dbdd20aSAndroid Build Coastguard Worker# DO NOT EDIT. AUTOGENERATED file
28*6dbdd20aSAndroid Build Coastguard Worker#
29*6dbdd20aSAndroid Build Coastguard Worker# This file is generated with the command:
30*6dbdd20aSAndroid Build Coastguard Worker# tools/gen_grpc_build_gn.py > buildtools/grpc/BUILD.gn
31*6dbdd20aSAndroid Build Coastguard Worker#
32*6dbdd20aSAndroid Build Coastguard Worker
33*6dbdd20aSAndroid Build Coastguard Workerimport("../../gn/perfetto.gni")
34*6dbdd20aSAndroid Build Coastguard Worker
35*6dbdd20aSAndroid Build Coastguard Worker# Prevent the gRPC from being depended upon without explicitly being opted in.
36*6dbdd20aSAndroid Build Coastguard Workerassert(enable_perfetto_grpc)
37*6dbdd20aSAndroid Build Coastguard Worker
38*6dbdd20aSAndroid Build Coastguard Worker# BoringSSL has assembly code which is tied to platform-specific. For now, we
39*6dbdd20aSAndroid Build Coastguard Worker# only care about Linux x64 so assert this as the case.
40*6dbdd20aSAndroid Build Coastguard Workerassert(is_linux && current_cpu == "x64")
41*6dbdd20aSAndroid Build Coastguard Worker'''
42*6dbdd20aSAndroid Build Coastguard Worker
43*6dbdd20aSAndroid Build Coastguard WorkerTARGET_TEMPLATE = """
44*6dbdd20aSAndroid Build Coastguard Worker{target_type}("{name}") {{
45*6dbdd20aSAndroid Build Coastguard Worker  sources = {srcs}
46*6dbdd20aSAndroid Build Coastguard Worker  public_deps = {deps}
47*6dbdd20aSAndroid Build Coastguard Worker  public_configs = ["..:{config_name}"]
48*6dbdd20aSAndroid Build Coastguard Worker  configs -= [ "//gn/standalone:extra_warnings" ]
49*6dbdd20aSAndroid Build Coastguard Worker  check_includes = {check_includes}
50*6dbdd20aSAndroid Build Coastguard Worker}}"""
51*6dbdd20aSAndroid Build Coastguard Worker
52*6dbdd20aSAndroid Build Coastguard WorkerLIBRARY_IGNORE_LIST = set([
53*6dbdd20aSAndroid Build Coastguard Worker    'grpcpp_channelz',
54*6dbdd20aSAndroid Build Coastguard Worker    'grpc++_reflection',
55*6dbdd20aSAndroid Build Coastguard Worker    'benchmark_helpers',
56*6dbdd20aSAndroid Build Coastguard Worker    'boringssl_test_util',
57*6dbdd20aSAndroid Build Coastguard Worker    'grpcpp_otel_plugin',
58*6dbdd20aSAndroid Build Coastguard Worker    'otel_plugin_test',
59*6dbdd20aSAndroid Build Coastguard Worker])
60*6dbdd20aSAndroid Build Coastguard Worker
61*6dbdd20aSAndroid Build Coastguard WorkerTARGET_ALLOW_LIST = set([
62*6dbdd20aSAndroid Build Coastguard Worker    'grpc_cpp_plugin',
63*6dbdd20aSAndroid Build Coastguard Worker])
64*6dbdd20aSAndroid Build Coastguard Worker
65*6dbdd20aSAndroid Build Coastguard WorkerSTATIC_LIBRARY_TARGETS = set([
66*6dbdd20aSAndroid Build Coastguard Worker    'upb',
67*6dbdd20aSAndroid Build Coastguard Worker    're2',
68*6dbdd20aSAndroid Build Coastguard Worker    'boringssl',
69*6dbdd20aSAndroid Build Coastguard Worker    'grpc++',
70*6dbdd20aSAndroid Build Coastguard Worker    'upb_json_lib',
71*6dbdd20aSAndroid Build Coastguard Worker    'upb_textformat_lib',
72*6dbdd20aSAndroid Build Coastguard Worker])
73*6dbdd20aSAndroid Build Coastguard Worker
74*6dbdd20aSAndroid Build Coastguard WorkerDEP_DENYLIST = set([
75*6dbdd20aSAndroid Build Coastguard Worker    'cares',
76*6dbdd20aSAndroid Build Coastguard Worker])
77*6dbdd20aSAndroid Build Coastguard Worker
78*6dbdd20aSAndroid Build Coastguard Worker
79*6dbdd20aSAndroid Build Coastguard Workerdef grpc_relpath(*segments: str) -> str:
80*6dbdd20aSAndroid Build Coastguard Worker  '''From path segments to GRPC root, returns the absolute path.'''
81*6dbdd20aSAndroid Build Coastguard Worker  return os.path.join(ROOT_DIR, 'buildtools', 'grpc', 'src', *segments)
82*6dbdd20aSAndroid Build Coastguard Worker
83*6dbdd20aSAndroid Build Coastguard Worker
84*6dbdd20aSAndroid Build Coastguard WorkerGRPC_BUILD_YAML = grpc_relpath('build_autogenerated.yaml')
85*6dbdd20aSAndroid Build Coastguard WorkerABSL_GEN_BUILD_YAML = grpc_relpath('src', 'abseil-cpp', 'gen_build_yaml.py')
86*6dbdd20aSAndroid Build Coastguard WorkerBSSL_GEN_BUILD_YAML = grpc_relpath('src', 'boringssl', 'gen_build_yaml.py')
87*6dbdd20aSAndroid Build Coastguard Worker
88*6dbdd20aSAndroid Build Coastguard Worker
89*6dbdd20aSAndroid Build Coastguard Workerdef gen_grpc_dep_yaml(gen_path: str) -> Dict[str, Any]:
90*6dbdd20aSAndroid Build Coastguard Worker  '''Invokes a gen_build_yaml.py file for creating YAML for gRPC deps.'''
91*6dbdd20aSAndroid Build Coastguard Worker  return yaml.safe_load(subprocess.check_output(['python3', gen_path]))
92*6dbdd20aSAndroid Build Coastguard Worker
93*6dbdd20aSAndroid Build Coastguard Worker
94*6dbdd20aSAndroid Build Coastguard Workerdef bazel_label_to_gn_target(dep: str) -> str:
95*6dbdd20aSAndroid Build Coastguard Worker  '''Converts a Bazel label name into a gn target name.'''
96*6dbdd20aSAndroid Build Coastguard Worker  if dep == 'libssl':
97*6dbdd20aSAndroid Build Coastguard Worker    return 'boringssl'
98*6dbdd20aSAndroid Build Coastguard Worker  return dep.replace('/', '_').replace(':', '_')
99*6dbdd20aSAndroid Build Coastguard Worker
100*6dbdd20aSAndroid Build Coastguard Worker
101*6dbdd20aSAndroid Build Coastguard Workerdef bazel_label_to_gn_dep(dep: str) -> str:
102*6dbdd20aSAndroid Build Coastguard Worker  if dep == 'protobuf':
103*6dbdd20aSAndroid Build Coastguard Worker    return '..:protobuf_full'
104*6dbdd20aSAndroid Build Coastguard Worker  if dep == 'protoc':
105*6dbdd20aSAndroid Build Coastguard Worker    return '..:protoc_lib'
106*6dbdd20aSAndroid Build Coastguard Worker  if dep == 'z':
107*6dbdd20aSAndroid Build Coastguard Worker    return '..:zlib'
108*6dbdd20aSAndroid Build Coastguard Worker  return ':' + bazel_label_to_gn_target(dep)
109*6dbdd20aSAndroid Build Coastguard Worker
110*6dbdd20aSAndroid Build Coastguard Worker
111*6dbdd20aSAndroid Build Coastguard Workerdef get_library_target_type(target: str) -> str:
112*6dbdd20aSAndroid Build Coastguard Worker  if target in STATIC_LIBRARY_TARGETS:
113*6dbdd20aSAndroid Build Coastguard Worker    return 'static_library'
114*6dbdd20aSAndroid Build Coastguard Worker  return 'source_set'
115*6dbdd20aSAndroid Build Coastguard Worker
116*6dbdd20aSAndroid Build Coastguard Worker
117*6dbdd20aSAndroid Build Coastguard Workerdef yaml_to_gn_targets(desc: Dict[str, Any], build_types: list[str],
118*6dbdd20aSAndroid Build Coastguard Worker                       config_name: str) -> List[str]:
119*6dbdd20aSAndroid Build Coastguard Worker  '''Given a gRPC YAML description of the build graph, generates GN targets.'''
120*6dbdd20aSAndroid Build Coastguard Worker  out = []
121*6dbdd20aSAndroid Build Coastguard Worker  for lib in desc['libs']:
122*6dbdd20aSAndroid Build Coastguard Worker    if lib['build'] not in build_types:
123*6dbdd20aSAndroid Build Coastguard Worker      continue
124*6dbdd20aSAndroid Build Coastguard Worker    if lib['name'] in LIBRARY_IGNORE_LIST:
125*6dbdd20aSAndroid Build Coastguard Worker      continue
126*6dbdd20aSAndroid Build Coastguard Worker    srcs = [f'src/{file}' for file in lib['src'] + lib['headers']]
127*6dbdd20aSAndroid Build Coastguard Worker    if 'asm_src' in lib:
128*6dbdd20aSAndroid Build Coastguard Worker      srcs += [f'src/{file}' for file in lib['asm_src']['crypto_asm']]
129*6dbdd20aSAndroid Build Coastguard Worker    deps = [
130*6dbdd20aSAndroid Build Coastguard Worker        bazel_label_to_gn_dep(dep)
131*6dbdd20aSAndroid Build Coastguard Worker        for dep in lib.get('deps', [])
132*6dbdd20aSAndroid Build Coastguard Worker        if dep not in DEP_DENYLIST
133*6dbdd20aSAndroid Build Coastguard Worker    ]
134*6dbdd20aSAndroid Build Coastguard Worker    library_target = TARGET_TEMPLATE.format(
135*6dbdd20aSAndroid Build Coastguard Worker        name=bazel_label_to_gn_target(lib['name']),
136*6dbdd20aSAndroid Build Coastguard Worker        config_name=config_name,
137*6dbdd20aSAndroid Build Coastguard Worker        srcs=json.dumps(srcs),
138*6dbdd20aSAndroid Build Coastguard Worker        deps=json.dumps(deps),
139*6dbdd20aSAndroid Build Coastguard Worker        target_type=get_library_target_type(lib['name']),
140*6dbdd20aSAndroid Build Coastguard Worker        check_includes='false' if lib['name'] == 'upb_json_lib' or
141*6dbdd20aSAndroid Build Coastguard Worker        lib['name'] == 'upb_textformat_lib' else 'true')
142*6dbdd20aSAndroid Build Coastguard Worker    out.append(library_target)
143*6dbdd20aSAndroid Build Coastguard Worker
144*6dbdd20aSAndroid Build Coastguard Worker  for bin in desc.get('targets', []):
145*6dbdd20aSAndroid Build Coastguard Worker    if bin['build'] not in build_types:
146*6dbdd20aSAndroid Build Coastguard Worker      continue
147*6dbdd20aSAndroid Build Coastguard Worker    if bin['name'] not in TARGET_ALLOW_LIST:
148*6dbdd20aSAndroid Build Coastguard Worker      continue
149*6dbdd20aSAndroid Build Coastguard Worker    srcs = json.dumps([f'src/{file}' for file in bin['src'] + bin['headers']])
150*6dbdd20aSAndroid Build Coastguard Worker    deps = [
151*6dbdd20aSAndroid Build Coastguard Worker        bazel_label_to_gn_dep(dep)
152*6dbdd20aSAndroid Build Coastguard Worker        for dep in bin.get('deps', [])
153*6dbdd20aSAndroid Build Coastguard Worker        if dep not in DEP_DENYLIST
154*6dbdd20aSAndroid Build Coastguard Worker    ]
155*6dbdd20aSAndroid Build Coastguard Worker    binary_target = TARGET_TEMPLATE.format(
156*6dbdd20aSAndroid Build Coastguard Worker        name=bazel_label_to_gn_target(bin['name']),
157*6dbdd20aSAndroid Build Coastguard Worker        config_name=config_name,
158*6dbdd20aSAndroid Build Coastguard Worker        srcs=srcs,
159*6dbdd20aSAndroid Build Coastguard Worker        deps=json.dumps(deps),
160*6dbdd20aSAndroid Build Coastguard Worker        target_type='executable',
161*6dbdd20aSAndroid Build Coastguard Worker        check_includes='true')
162*6dbdd20aSAndroid Build Coastguard Worker    out.append(binary_target)
163*6dbdd20aSAndroid Build Coastguard Worker  return out
164*6dbdd20aSAndroid Build Coastguard Worker
165*6dbdd20aSAndroid Build Coastguard Worker
166*6dbdd20aSAndroid Build Coastguard Workerdef main():
167*6dbdd20aSAndroid Build Coastguard Worker  out: List[str] = []
168*6dbdd20aSAndroid Build Coastguard Worker
169*6dbdd20aSAndroid Build Coastguard Worker  # Generate absl rules
170*6dbdd20aSAndroid Build Coastguard Worker  absl_yaml = gen_grpc_dep_yaml(ABSL_GEN_BUILD_YAML)
171*6dbdd20aSAndroid Build Coastguard Worker  out.extend(yaml_to_gn_targets(absl_yaml, ['private'], 'grpc_absl_config'))
172*6dbdd20aSAndroid Build Coastguard Worker
173*6dbdd20aSAndroid Build Coastguard Worker  # Generate boringssl rules
174*6dbdd20aSAndroid Build Coastguard Worker  boringssl_yaml = gen_grpc_dep_yaml(BSSL_GEN_BUILD_YAML)
175*6dbdd20aSAndroid Build Coastguard Worker  out.extend(
176*6dbdd20aSAndroid Build Coastguard Worker      yaml_to_gn_targets(boringssl_yaml, ['private'], 'grpc_boringssl_config'))
177*6dbdd20aSAndroid Build Coastguard Worker
178*6dbdd20aSAndroid Build Coastguard Worker  # Generate grpc rules
179*6dbdd20aSAndroid Build Coastguard Worker  with open(GRPC_BUILD_YAML, 'r', encoding='utf-8') as f:
180*6dbdd20aSAndroid Build Coastguard Worker    grpc_yaml = yaml.safe_load(f.read())
181*6dbdd20aSAndroid Build Coastguard Worker  out.extend(
182*6dbdd20aSAndroid Build Coastguard Worker      yaml_to_gn_targets(grpc_yaml, ['all', 'protoc'], 'grpc_internal_config'))
183*6dbdd20aSAndroid Build Coastguard Worker
184*6dbdd20aSAndroid Build Coastguard Worker  print(GRPC_GN_HEADER)
185*6dbdd20aSAndroid Build Coastguard Worker  print('\n'.join(out))
186*6dbdd20aSAndroid Build Coastguard Worker  return 0
187*6dbdd20aSAndroid Build Coastguard Worker
188*6dbdd20aSAndroid Build Coastguard Worker
189*6dbdd20aSAndroid Build Coastguard Workerif __name__ == '__main__':
190*6dbdd20aSAndroid Build Coastguard Worker  sys.exit(main())
191