| #!/usr/bin/env python3 |
| import json |
| import os |
| import subprocess |
| import sys |
| from typing import Any, Dict, List |
| import yaml |
| |
| ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| |
| IGNORE_LIST = set([ |
| 'grpcpp_channelz', |
| 'grpc++_reflection', |
| 'benchmark_helpers', |
| 'boringssl_test_util', |
| ]) |
| |
| SOURCE_SET_TARGET = """ |
| source_set("{name}") {{ |
| sources = {srcs} |
| public_deps = {deps} |
| public_configs = ["..:{config_name}"] |
| configs -= [ "//gn/standalone:extra_warnings" ] |
| }}""" |
| |
| |
| def grpc_relpath(*segments: str) -> str: |
| '''From path segments to GRPC root, returns the absolute path.''' |
| return os.path.join(ROOT_DIR, 'buildtools', 'grpc', 'src', *segments) |
| |
| |
| GRPC_GN_HEADER = ''' |
| # |
| # DO NOT EDIT. AUTOGENERATED file |
| # |
| # This file is generated with the command: |
| # tools/gen_grpc_build_gn.py > buildtools/grpc/BUILD.gn |
| # |
| |
| # Prevent the gRPC from being depended upon without explicitly being opted in. |
| assert(enable_perfetto_grpc) |
| ''' |
| |
| GRPC_BUILD_YAML = grpc_relpath('build_autogenerated.yaml') |
| ABSL_GEN_BUILD_YAML = grpc_relpath('src', 'abseil-cpp', 'gen_build_yaml.py') |
| UPB_GEN_BUILD_YAML = grpc_relpath('src', 'upb', 'gen_build_yaml.py') |
| BSSL_GEN_BUILD_YAML = grpc_relpath('src', 'boringssl', 'gen_build_yaml.py') |
| |
| |
| def bazel_label_to_gn_target(dep: str): |
| '''Converts a Bazel label name into a gn target name.''' |
| if dep == 'libssl': |
| return 'boringssl' |
| return dep.replace('/', '_').replace(':', '_') |
| |
| |
| def gen_grpc_dep_yaml(gen_path: str) -> Dict[str, Any]: |
| '''Invokes a gen_build_yaml.py file for creating YAML for gRPC deps.''' |
| return yaml.safe_load(subprocess.check_output(['python3', gen_path])) |
| |
| |
| def yaml_to_gn_targets(desc: Dict[str, Any], build_type: str, config_name: str, |
| out: List[str]): |
| '''Given a gRPC YAML description of the build graph, generates GN targets.''' |
| for lib in desc['libs']: |
| if lib['build'] != build_type: |
| continue |
| if lib['name'] in IGNORE_LIST: |
| continue |
| srcs = json.dumps([f'src/{file}' for file in lib['src'] + lib['headers']]) |
| deps = json.dumps( |
| [f':{bazel_label_to_gn_target(dep)}' for dep in lib.get('deps', [])]) |
| source_set_target = SOURCE_SET_TARGET.format( |
| name=bazel_label_to_gn_target(lib['name']), |
| config_name=config_name, |
| srcs=srcs, |
| deps=deps) |
| out.append(source_set_target) |
| |
| |
| def main(): |
| out: List[str] = [] |
| |
| # Generate absl rules |
| absl_yaml = gen_grpc_dep_yaml(ABSL_GEN_BUILD_YAML) |
| yaml_to_gn_targets(absl_yaml, 'private', 'grpc_absl_config', out) |
| |
| # Generate upb rules |
| upb_yaml = gen_grpc_dep_yaml(UPB_GEN_BUILD_YAML) |
| yaml_to_gn_targets(upb_yaml, 'all', 'grpc_upb_config', out) |
| |
| # Generate boringssl rules |
| boringssl_yaml = gen_grpc_dep_yaml(BSSL_GEN_BUILD_YAML) |
| yaml_to_gn_targets(boringssl_yaml, 'private', 'grpc_boringssl_config', out) |
| |
| # Generate grpc rules |
| with open(GRPC_BUILD_YAML, 'r', encoding='utf-8') as f: |
| grpc_yaml = yaml.safe_load(f.read()) |
| yaml_to_gn_targets(grpc_yaml, 'all', 'grpc_internal_config', out) |
| |
| print(GRPC_GN_HEADER) |
| print('\n'.join(out)) |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |