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