blob: 706e0621d06b8573f6d349b95f1c80db6db31a66 [file] [log] [blame]
#!/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())