1*6dbdd20aSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2018 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 Worker# This tool translates a collection of BUILD.gn files into a mostly equivalent 17*6dbdd20aSAndroid Build Coastguard Worker# BUILD file for the Bazel build system. The input to the tool is a 18*6dbdd20aSAndroid Build Coastguard Worker# JSON description of the GN build definition generated with the following 19*6dbdd20aSAndroid Build Coastguard Worker# command: 20*6dbdd20aSAndroid Build Coastguard Worker# 21*6dbdd20aSAndroid Build Coastguard Worker# gn desc out --format=json --all-toolchains "//*" > desc.json 22*6dbdd20aSAndroid Build Coastguard Worker# 23*6dbdd20aSAndroid Build Coastguard Worker# The tool is then given a list of GN labels for which to generate Bazel 24*6dbdd20aSAndroid Build Coastguard Worker# build rules. 25*6dbdd20aSAndroid Build Coastguard Worker 26*6dbdd20aSAndroid Build Coastguard Workerfrom __future__ import print_function 27*6dbdd20aSAndroid Build Coastguard Workerimport argparse 28*6dbdd20aSAndroid Build Coastguard Workerimport json 29*6dbdd20aSAndroid Build Coastguard Workerimport os 30*6dbdd20aSAndroid Build Coastguard Workerimport re 31*6dbdd20aSAndroid Build Coastguard Workerimport sys 32*6dbdd20aSAndroid Build Coastguard Workerfrom typing import Any 33*6dbdd20aSAndroid Build Coastguard Workerfrom typing import Dict 34*6dbdd20aSAndroid Build Coastguard Workerfrom typing import List 35*6dbdd20aSAndroid Build Coastguard Workerfrom typing import Optional 36*6dbdd20aSAndroid Build Coastguard Workerfrom typing import Union 37*6dbdd20aSAndroid Build Coastguard Worker 38*6dbdd20aSAndroid Build Coastguard Workerfrom gn_utils import GnParser 39*6dbdd20aSAndroid Build Coastguard Workerimport gn_utils 40*6dbdd20aSAndroid Build Coastguard Worker 41*6dbdd20aSAndroid Build Coastguard Workerfrom compat import itervalues, iteritems, basestring 42*6dbdd20aSAndroid Build Coastguard Worker 43*6dbdd20aSAndroid Build Coastguard Worker# Visibility option for targets which we want an allowlist of public targets 44*6dbdd20aSAndroid Build Coastguard Worker# which can depend on it. 45*6dbdd20aSAndroid Build Coastguard WorkerALLOWLIST_PUBLIC_VISIBILITY = 'PERFETTO_CONFIG.public_visibility' 46*6dbdd20aSAndroid Build Coastguard Worker 47*6dbdd20aSAndroid Build Coastguard Worker# Arguments for the GN output directory. 48*6dbdd20aSAndroid Build Coastguard Worker# host_os="linux" is to generate the right build files from Mac OS. 49*6dbdd20aSAndroid Build Coastguard Workergn_args_base = { 50*6dbdd20aSAndroid Build Coastguard Worker 'host_os': '"linux"', 51*6dbdd20aSAndroid Build Coastguard Worker 'is_debug': 'false', 52*6dbdd20aSAndroid Build Coastguard Worker 'is_perfetto_build_generator': 'true', 53*6dbdd20aSAndroid Build Coastguard Worker 'monolithic_binaries': 'true', 54*6dbdd20aSAndroid Build Coastguard Worker 'target_os': '"linux"', 55*6dbdd20aSAndroid Build Coastguard Worker 'enable_perfetto_heapprofd': 'false', 56*6dbdd20aSAndroid Build Coastguard Worker 'enable_perfetto_traced_perf': 'false', 57*6dbdd20aSAndroid Build Coastguard Worker 'perfetto_force_dcheck': '"off"', 58*6dbdd20aSAndroid Build Coastguard Worker 'enable_perfetto_llvm_demangle': 'true', 59*6dbdd20aSAndroid Build Coastguard Worker 'enable_perfetto_etm_importer': 'false', 60*6dbdd20aSAndroid Build Coastguard Worker} 61*6dbdd20aSAndroid Build Coastguard Workergn_args = ' '.join((map(lambda x:'='.join(x), gn_args_base.items()))) 62*6dbdd20aSAndroid Build Coastguard Worker 63*6dbdd20aSAndroid Build Coastguard Worker# We generate a second set of build rules for Windows, in order to 64*6dbdd20aSAndroid Build Coastguard Worker# conditionally filter out targets which are gated behind !is_win 65*6dbdd20aSAndroid Build Coastguard Worker# in the GN build files. 66*6dbdd20aSAndroid Build Coastguard Workergn_args_win_base = { 67*6dbdd20aSAndroid Build Coastguard Worker **gn_args_base, 68*6dbdd20aSAndroid Build Coastguard Worker 'host_os': '"win"', 69*6dbdd20aSAndroid Build Coastguard Worker 'host_cpu': '"x86"', 70*6dbdd20aSAndroid Build Coastguard Worker 'target_os': '"win"', 71*6dbdd20aSAndroid Build Coastguard Worker 'target_cpu': '"x64"', 72*6dbdd20aSAndroid Build Coastguard Worker 'is_cross_compiling': 'false', 73*6dbdd20aSAndroid Build Coastguard Worker} 74*6dbdd20aSAndroid Build Coastguard Workergn_args_win = ' '.join((map(lambda x:'='.join(x), gn_args_win_base.items()))) 75*6dbdd20aSAndroid Build Coastguard Worker 76*6dbdd20aSAndroid Build Coastguard Worker# Default targets to translate to the blueprint file. 77*6dbdd20aSAndroid Build Coastguard Worker 78*6dbdd20aSAndroid Build Coastguard Worker# These targets will be exported with public visibility in the generated BUILD. 79*6dbdd20aSAndroid Build Coastguard Workerpublic_targets = [ 80*6dbdd20aSAndroid Build Coastguard Worker '//:libperfetto_client_experimental', 81*6dbdd20aSAndroid Build Coastguard Worker '//src/perfetto_cmd:perfetto', 82*6dbdd20aSAndroid Build Coastguard Worker '//src/traced/probes:traced_probes', 83*6dbdd20aSAndroid Build Coastguard Worker '//src/traced/service:traced', 84*6dbdd20aSAndroid Build Coastguard Worker '//src/trace_processor:trace_processor_shell', 85*6dbdd20aSAndroid Build Coastguard Worker '//src/trace_processor:trace_processor', 86*6dbdd20aSAndroid Build Coastguard Worker '//src/traceconv:traceconv', 87*6dbdd20aSAndroid Build Coastguard Worker] 88*6dbdd20aSAndroid Build Coastguard Worker 89*6dbdd20aSAndroid Build Coastguard Worker# These targets will be exported with visibility only to our allowlist. 90*6dbdd20aSAndroid Build Coastguard Workerallowlist_public_targets = [ 91*6dbdd20aSAndroid Build Coastguard Worker '//src/shared_lib:libperfetto_c', 92*6dbdd20aSAndroid Build Coastguard Worker '//src/traceconv:libpprofbuilder', 93*6dbdd20aSAndroid Build Coastguard Worker] 94*6dbdd20aSAndroid Build Coastguard Worker 95*6dbdd20aSAndroid Build Coastguard Worker# These targets are required by internal build rules but don't need to be 96*6dbdd20aSAndroid Build Coastguard Worker# exported publicly. 97*6dbdd20aSAndroid Build Coastguard Workerdefault_targets = [ 98*6dbdd20aSAndroid Build Coastguard Worker '//src/base:perfetto_base_default_platform', 99*6dbdd20aSAndroid Build Coastguard Worker '//src/ipc:perfetto_ipc', 100*6dbdd20aSAndroid Build Coastguard Worker '//src/ipc/protoc_plugin:ipc_plugin', 101*6dbdd20aSAndroid Build Coastguard Worker '//src/protozero:protozero', 102*6dbdd20aSAndroid Build Coastguard Worker '//src/protozero/protoc_plugin:cppgen_plugin', 103*6dbdd20aSAndroid Build Coastguard Worker '//src/protozero/protoc_plugin:protozero_plugin', 104*6dbdd20aSAndroid Build Coastguard Worker '//src/tools/proto_filter:proto_filter', 105*6dbdd20aSAndroid Build Coastguard Worker '//src/tools/proto_merger:proto_merger', 106*6dbdd20aSAndroid Build Coastguard Worker '//src/trace_processor/rpc:trace_processor_rpc', 107*6dbdd20aSAndroid Build Coastguard Worker '//test:client_api_example', 108*6dbdd20aSAndroid Build Coastguard Worker] + public_targets + allowlist_public_targets 109*6dbdd20aSAndroid Build Coastguard Worker 110*6dbdd20aSAndroid Build Coastguard Worker# Proto target groups which will be made public. 111*6dbdd20aSAndroid Build Coastguard Workerproto_groups = { 112*6dbdd20aSAndroid Build Coastguard Worker 'config': { 113*6dbdd20aSAndroid Build Coastguard Worker 'sources': ['//protos/perfetto/config:source_set'], 114*6dbdd20aSAndroid Build Coastguard Worker 'visibility': ['//visibility:public'], 115*6dbdd20aSAndroid Build Coastguard Worker }, 116*6dbdd20aSAndroid Build Coastguard Worker 'trace': { 117*6dbdd20aSAndroid Build Coastguard Worker 'sources': [ 118*6dbdd20aSAndroid Build Coastguard Worker '//protos/perfetto/trace:non_minimal_source_set', 119*6dbdd20aSAndroid Build Coastguard Worker '//protos/perfetto/trace:minimal_source_set' 120*6dbdd20aSAndroid Build Coastguard Worker ], 121*6dbdd20aSAndroid Build Coastguard Worker 'visibility': ALLOWLIST_PUBLIC_VISIBILITY, 122*6dbdd20aSAndroid Build Coastguard Worker }, 123*6dbdd20aSAndroid Build Coastguard Worker 'metrics': { 124*6dbdd20aSAndroid Build Coastguard Worker 'sources': ['//protos/perfetto/metrics:source_set',], 125*6dbdd20aSAndroid Build Coastguard Worker 'visibility': ['//visibility:public'], 126*6dbdd20aSAndroid Build Coastguard Worker }, 127*6dbdd20aSAndroid Build Coastguard Worker 'chromium': { 128*6dbdd20aSAndroid Build Coastguard Worker 'sources': ['//protos/third_party/chromium:source_set',], 129*6dbdd20aSAndroid Build Coastguard Worker 'visibility': ALLOWLIST_PUBLIC_VISIBILITY, 130*6dbdd20aSAndroid Build Coastguard Worker }, 131*6dbdd20aSAndroid Build Coastguard Worker 'chrome_metrics': { 132*6dbdd20aSAndroid Build Coastguard Worker 'sources': ['//protos/perfetto/metrics/chrome:source_set',], 133*6dbdd20aSAndroid Build Coastguard Worker 'visibility': ALLOWLIST_PUBLIC_VISIBILITY, 134*6dbdd20aSAndroid Build Coastguard Worker }, 135*6dbdd20aSAndroid Build Coastguard Worker 'trace_processor': { 136*6dbdd20aSAndroid Build Coastguard Worker 'sources': ['//protos/perfetto/trace_processor:source_set',], 137*6dbdd20aSAndroid Build Coastguard Worker 'visibility': [], 138*6dbdd20aSAndroid Build Coastguard Worker }, 139*6dbdd20aSAndroid Build Coastguard Worker} 140*6dbdd20aSAndroid Build Coastguard Worker 141*6dbdd20aSAndroid Build Coastguard Worker# Path for the protobuf sources in the standalone build. 142*6dbdd20aSAndroid Build Coastguard Workerbuildtools_protobuf_src = '//buildtools/protobuf/src' 143*6dbdd20aSAndroid Build Coastguard Worker 144*6dbdd20aSAndroid Build Coastguard Worker# The directory where the generated perfetto_build_flags.h will be copied into. 145*6dbdd20aSAndroid Build Coastguard Workerbuildflags_dir = 'include/perfetto/base/build_configs/bazel' 146*6dbdd20aSAndroid Build Coastguard Worker 147*6dbdd20aSAndroid Build Coastguard Worker# Internal equivalents for third-party libraries that the upstream project 148*6dbdd20aSAndroid Build Coastguard Worker# depends on. 149*6dbdd20aSAndroid Build Coastguard Workerexternal_deps = { 150*6dbdd20aSAndroid Build Coastguard Worker '//gn:default_deps': [], 151*6dbdd20aSAndroid Build Coastguard Worker '//gn:base_platform': ['PERFETTO_CONFIG.deps.base_platform'], 152*6dbdd20aSAndroid Build Coastguard Worker '//gn:expat': ['PERFETTO_CONFIG.deps.expat'], 153*6dbdd20aSAndroid Build Coastguard Worker '//gn:jsoncpp': ['PERFETTO_CONFIG.deps.jsoncpp'], 154*6dbdd20aSAndroid Build Coastguard Worker '//gn:linenoise': ['PERFETTO_CONFIG.deps.linenoise'], 155*6dbdd20aSAndroid Build Coastguard Worker '//gn:open_csd': ['PERFETTO_CONFIG.deps.open_csd'], 156*6dbdd20aSAndroid Build Coastguard Worker '//gn:protobuf_full': ['PERFETTO_CONFIG.deps.protobuf_full'], 157*6dbdd20aSAndroid Build Coastguard Worker '//gn:protobuf_lite': ['PERFETTO_CONFIG.deps.protobuf_lite'], 158*6dbdd20aSAndroid Build Coastguard Worker '//gn:protoc_lib': ['PERFETTO_CONFIG.deps.protoc_lib'], 159*6dbdd20aSAndroid Build Coastguard Worker '//gn:protoc': ['PERFETTO_CONFIG.deps.protoc'], 160*6dbdd20aSAndroid Build Coastguard Worker '//gn:sqlite': [ 161*6dbdd20aSAndroid Build Coastguard Worker 'PERFETTO_CONFIG.deps.sqlite', 162*6dbdd20aSAndroid Build Coastguard Worker 'PERFETTO_CONFIG.deps.sqlite_ext_percentile' 163*6dbdd20aSAndroid Build Coastguard Worker ], 164*6dbdd20aSAndroid Build Coastguard Worker '//gn:zlib': ['PERFETTO_CONFIG.deps.zlib'], 165*6dbdd20aSAndroid Build Coastguard Worker '//gn:llvm_demangle': ['PERFETTO_CONFIG.deps.llvm_demangle'], 166*6dbdd20aSAndroid Build Coastguard Worker '//src/trace_processor:demangle': ['PERFETTO_CONFIG.deps.demangle_wrapper'], 167*6dbdd20aSAndroid Build Coastguard Worker gn_utils.GEN_VERSION_TARGET: ['PERFETTO_CONFIG.deps.version_header'], 168*6dbdd20aSAndroid Build Coastguard Worker} 169*6dbdd20aSAndroid Build Coastguard Worker 170*6dbdd20aSAndroid Build Coastguard Worker# These are Python targets which are exposed with public visibility. 171*6dbdd20aSAndroid Build Coastguard Workerpublic_python_targets = [ 172*6dbdd20aSAndroid Build Coastguard Worker '//python:batch_trace_processor', 173*6dbdd20aSAndroid Build Coastguard Worker '//python:trace_processor_py', 174*6dbdd20aSAndroid Build Coastguard Worker '//python:trace_processor_py_no_resolvers', 175*6dbdd20aSAndroid Build Coastguard Worker] 176*6dbdd20aSAndroid Build Coastguard Worker 177*6dbdd20aSAndroid Build Coastguard Worker# These are Python targets which are exposed by default. 178*6dbdd20aSAndroid Build Coastguard Workerdefault_python_targets = [ 179*6dbdd20aSAndroid Build Coastguard Worker '//python:batch_trace_processor', 180*6dbdd20aSAndroid Build Coastguard Worker '//python:experimental_slice_breakdown_bin', 181*6dbdd20aSAndroid Build Coastguard Worker '//python:trace_processor_table_generator', 182*6dbdd20aSAndroid Build Coastguard Worker '//python:trace_processor_py_example', 183*6dbdd20aSAndroid Build Coastguard Worker '//python:sql_processing', 184*6dbdd20aSAndroid Build Coastguard Worker] 185*6dbdd20aSAndroid Build Coastguard Worker 186*6dbdd20aSAndroid Build Coastguard Worker# Internal equivalents for third-party Python libraries. 187*6dbdd20aSAndroid Build Coastguard Workerexternal_python_deps: Dict[str, List[str]] = { 188*6dbdd20aSAndroid Build Coastguard Worker '//gn:pandas_py': ['PERFETTO_CONFIG.deps.pandas_py'], 189*6dbdd20aSAndroid Build Coastguard Worker '//gn:protobuf_py': ['PERFETTO_CONFIG.deps.protobuf_py'], 190*6dbdd20aSAndroid Build Coastguard Worker '//gn:tp_vendor_py': ['PERFETTO_CONFIG.deps.tp_vendor_py'], 191*6dbdd20aSAndroid Build Coastguard Worker '//gn:tp_resolvers_py': ['PERFETTO_CONFIG.deps.tp_resolvers_py'], 192*6dbdd20aSAndroid Build Coastguard Worker} 193*6dbdd20aSAndroid Build Coastguard Worker 194*6dbdd20aSAndroid Build Coastguard Worker# Additional arguments 195*6dbdd20aSAndroid Build Coastguard Workertarget_overrides = { 196*6dbdd20aSAndroid Build Coastguard Worker '//src/trace_processor/perfetto_sql/stdlib/chrome:chrome_sql': { 197*6dbdd20aSAndroid Build Coastguard Worker 'srcs': 'glob(["src/trace_processor/perfetto_sql/stdlib/chrome/**/*.sql"])' 198*6dbdd20aSAndroid Build Coastguard Worker } 199*6dbdd20aSAndroid Build Coastguard Worker} 200*6dbdd20aSAndroid Build Coastguard Worker 201*6dbdd20aSAndroid Build Coastguard Worker# Defines required for Bazel. 202*6dbdd20aSAndroid Build Coastguard Workerbazel_required_defines = [ 203*6dbdd20aSAndroid Build Coastguard Worker "PERFETTO_SHLIB_SDK_IMPLEMENTATION" 204*6dbdd20aSAndroid Build Coastguard Worker] 205*6dbdd20aSAndroid Build Coastguard Worker 206*6dbdd20aSAndroid Build Coastguard Worker# Targets with the "avoid_dep" tag; 207*6dbdd20aSAndroid Build Coastguard Workeravoid_dep_targets = set([ 208*6dbdd20aSAndroid Build Coastguard Worker '//python:trace_processor_py_no_resolvers', 209*6dbdd20aSAndroid Build Coastguard Worker]) 210*6dbdd20aSAndroid Build Coastguard Worker 211*6dbdd20aSAndroid Build Coastguard Worker# Filter defines that appear in the bazel build file to only those that bazel requires. 212*6dbdd20aSAndroid Build Coastguard Workerdef filter_defines(defines): 213*6dbdd20aSAndroid Build Coastguard Worker return [d for d in defines if d in bazel_required_defines] 214*6dbdd20aSAndroid Build Coastguard Worker 215*6dbdd20aSAndroid Build Coastguard Worker 216*6dbdd20aSAndroid Build Coastguard Workerdef gen_version_header(target): 217*6dbdd20aSAndroid Build Coastguard Worker label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_genrule') 218*6dbdd20aSAndroid Build Coastguard Worker label.srcs += [gn_utils.label_to_path(x) for x in sorted(target.inputs)] 219*6dbdd20aSAndroid Build Coastguard Worker label.outs += target.outputs 220*6dbdd20aSAndroid Build Coastguard Worker label.cmd = r'$(location gen_version_header_py)' 221*6dbdd20aSAndroid Build Coastguard Worker label.cmd += r' --cpp_out=$@ --changelog=$(location CHANGELOG)' 222*6dbdd20aSAndroid Build Coastguard Worker label.tools += [':gen_version_header_py'] 223*6dbdd20aSAndroid Build Coastguard Worker return [label] 224*6dbdd20aSAndroid Build Coastguard Worker 225*6dbdd20aSAndroid Build Coastguard Worker 226*6dbdd20aSAndroid Build Coastguard Workercustom_actions = { 227*6dbdd20aSAndroid Build Coastguard Worker gn_utils.GEN_VERSION_TARGET: gen_version_header, 228*6dbdd20aSAndroid Build Coastguard Worker} 229*6dbdd20aSAndroid Build Coastguard Worker 230*6dbdd20aSAndroid Build Coastguard Worker# ------------------------------------------------------------------------------ 231*6dbdd20aSAndroid Build Coastguard Worker# End of configuration. 232*6dbdd20aSAndroid Build Coastguard Worker# ------------------------------------------------------------------------------ 233*6dbdd20aSAndroid Build Coastguard Worker 234*6dbdd20aSAndroid Build Coastguard Worker 235*6dbdd20aSAndroid Build Coastguard Workerclass PythonBuildGenerator: 236*6dbdd20aSAndroid Build Coastguard Worker '''Generator of the BUILD file in the python folder. 237*6dbdd20aSAndroid Build Coastguard Worker 238*6dbdd20aSAndroid Build Coastguard Worker This code is split into its own class to avoid polluting 239*6dbdd20aSAndroid Build Coastguard Worker the generation of the main build file with Python related 240*6dbdd20aSAndroid Build Coastguard Worker content. 241*6dbdd20aSAndroid Build Coastguard Worker ''' 242*6dbdd20aSAndroid Build Coastguard Worker 243*6dbdd20aSAndroid Build Coastguard Worker def populate_python_deps(self, target: GnParser.Target, label: 'BazelLabel'): 244*6dbdd20aSAndroid Build Coastguard Worker '''Populates deps for a GN target into Bazel Python label.''' 245*6dbdd20aSAndroid Build Coastguard Worker for dep in sorted(target.non_proto_or_source_set_deps()): 246*6dbdd20aSAndroid Build Coastguard Worker if dep.name in external_python_deps: 247*6dbdd20aSAndroid Build Coastguard Worker assert (isinstance(external_python_deps[dep.name], list)) 248*6dbdd20aSAndroid Build Coastguard Worker label.external_deps += external_python_deps[dep.name] 249*6dbdd20aSAndroid Build Coastguard Worker else: 250*6dbdd20aSAndroid Build Coastguard Worker label.deps += [':' + get_bazel_python_label_name(dep.name)] 251*6dbdd20aSAndroid Build Coastguard Worker 252*6dbdd20aSAndroid Build Coastguard Worker def python_label_to_path(self, gn_name: str): 253*6dbdd20aSAndroid Build Coastguard Worker """Converts a Python GN path label into a Bazel path.""" 254*6dbdd20aSAndroid Build Coastguard Worker return re.sub(r'^python/', '', gn_utils.label_to_path(gn_name)) 255*6dbdd20aSAndroid Build Coastguard Worker 256*6dbdd20aSAndroid Build Coastguard Worker def python_data_to_path(self, gn_name: str): 257*6dbdd20aSAndroid Build Coastguard Worker """Converts a Python GN data label into a Bazel data label.""" 258*6dbdd20aSAndroid Build Coastguard Worker return re.sub(r'^\.\.(.*)', r'PERFETTO_CONFIG.root + "\1"', gn_name) 259*6dbdd20aSAndroid Build Coastguard Worker 260*6dbdd20aSAndroid Build Coastguard Worker def gen_python_library(self, target: GnParser.Target): 261*6dbdd20aSAndroid Build Coastguard Worker """Creates a Bazel target for a Python library GN target.""" 262*6dbdd20aSAndroid Build Coastguard Worker label = BazelLabel( 263*6dbdd20aSAndroid Build Coastguard Worker get_bazel_python_label_name(target.name), 'perfetto_py_library') 264*6dbdd20aSAndroid Build Coastguard Worker label.comment = target.name 265*6dbdd20aSAndroid Build Coastguard Worker label.srcs += (self.python_label_to_path(x) for x in target.sources) 266*6dbdd20aSAndroid Build Coastguard Worker label.data += (self.python_data_to_path(x) for x in target.data) 267*6dbdd20aSAndroid Build Coastguard Worker self.populate_python_deps(target, label) 268*6dbdd20aSAndroid Build Coastguard Worker if target.name in public_python_targets: 269*6dbdd20aSAndroid Build Coastguard Worker label.visibility = ['//visibility:public'] 270*6dbdd20aSAndroid Build Coastguard Worker if target.name in avoid_dep_targets: 271*6dbdd20aSAndroid Build Coastguard Worker label.tags += ['avoid_dep'] 272*6dbdd20aSAndroid Build Coastguard Worker return [label] 273*6dbdd20aSAndroid Build Coastguard Worker 274*6dbdd20aSAndroid Build Coastguard Worker def gen_python_binary(self, target: GnParser.Target): 275*6dbdd20aSAndroid Build Coastguard Worker """Creates a Bazel target for a Python binary GN target.""" 276*6dbdd20aSAndroid Build Coastguard Worker label = BazelLabel( 277*6dbdd20aSAndroid Build Coastguard Worker get_bazel_python_label_name(target.name), 'perfetto_py_binary') 278*6dbdd20aSAndroid Build Coastguard Worker label.comment = target.name 279*6dbdd20aSAndroid Build Coastguard Worker label.srcs += (self.python_label_to_path(x) for x in target.sources) 280*6dbdd20aSAndroid Build Coastguard Worker label.data += (self.python_data_to_path(x) for x in target.data) 281*6dbdd20aSAndroid Build Coastguard Worker label.main = target.python_main 282*6dbdd20aSAndroid Build Coastguard Worker label.python_version = 'PY3' 283*6dbdd20aSAndroid Build Coastguard Worker if target.name in public_python_targets: 284*6dbdd20aSAndroid Build Coastguard Worker label.visibility = ['//visibility:public'] 285*6dbdd20aSAndroid Build Coastguard Worker 286*6dbdd20aSAndroid Build Coastguard Worker self.populate_python_deps(target, label) 287*6dbdd20aSAndroid Build Coastguard Worker return [label] 288*6dbdd20aSAndroid Build Coastguard Worker 289*6dbdd20aSAndroid Build Coastguard Worker def gen_target(self, gn_target: GnParser.Target): 290*6dbdd20aSAndroid Build Coastguard Worker """Creates a Bazel target for a Python GN target.""" 291*6dbdd20aSAndroid Build Coastguard Worker assert (gn_target.type == 'action') 292*6dbdd20aSAndroid Build Coastguard Worker if gn_target.name in external_python_deps: 293*6dbdd20aSAndroid Build Coastguard Worker return [] 294*6dbdd20aSAndroid Build Coastguard Worker if gn_target.custom_action_type == 'python_library': 295*6dbdd20aSAndroid Build Coastguard Worker return self.gen_python_library(gn_target) 296*6dbdd20aSAndroid Build Coastguard Worker if gn_target.custom_action_type == 'python_binary': 297*6dbdd20aSAndroid Build Coastguard Worker return self.gen_python_binary(gn_target) 298*6dbdd20aSAndroid Build Coastguard Worker assert (False) 299*6dbdd20aSAndroid Build Coastguard Worker 300*6dbdd20aSAndroid Build Coastguard Worker def gen_target_str(self, gn_target: GnParser.Target): 301*6dbdd20aSAndroid Build Coastguard Worker """Creates a Bazel target string for a Python GN target.""" 302*6dbdd20aSAndroid Build Coastguard Worker return ''.join(str(x) for x in self.gen_target(gn_target)) 303*6dbdd20aSAndroid Build Coastguard Worker 304*6dbdd20aSAndroid Build Coastguard Worker def generate(self, gn_desc): 305*6dbdd20aSAndroid Build Coastguard Worker """Creates a Python BUILD file for the GN description.""" 306*6dbdd20aSAndroid Build Coastguard Worker gn = gn_utils.GnParser(gn_desc) 307*6dbdd20aSAndroid Build Coastguard Worker project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) 308*6dbdd20aSAndroid Build Coastguard Worker tool_name = os.path.relpath(os.path.abspath(__file__), project_root) 309*6dbdd20aSAndroid Build Coastguard Worker tool_name = tool_name.replace('\\', '/') 310*6dbdd20aSAndroid Build Coastguard Worker res = ''' 311*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2022 The Android Open Source Project 312*6dbdd20aSAndroid Build Coastguard Worker# 313*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 314*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 315*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 316*6dbdd20aSAndroid Build Coastguard Worker# 317*6dbdd20aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 318*6dbdd20aSAndroid Build Coastguard Worker# 319*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 320*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 321*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 322*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 323*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License. 324*6dbdd20aSAndroid Build Coastguard Worker# 325*6dbdd20aSAndroid Build Coastguard Worker# This file is automatically generated by {}. Do not edit. 326*6dbdd20aSAndroid Build Coastguard Worker 327*6dbdd20aSAndroid Build Coastguard Workerload("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG") 328*6dbdd20aSAndroid Build Coastguard Workerload( 329*6dbdd20aSAndroid Build Coastguard Worker "@perfetto//bazel:rules.bzl", 330*6dbdd20aSAndroid Build Coastguard Worker "perfetto_py_binary", 331*6dbdd20aSAndroid Build Coastguard Worker "perfetto_py_library", 332*6dbdd20aSAndroid Build Coastguard Worker) 333*6dbdd20aSAndroid Build Coastguard Worker 334*6dbdd20aSAndroid Build Coastguard Workerlicenses(["notice"]) 335*6dbdd20aSAndroid Build Coastguard Worker 336*6dbdd20aSAndroid Build Coastguard Workerpackage(default_visibility = [PERFETTO_CONFIG.root + ":__subpackages__"]) 337*6dbdd20aSAndroid Build Coastguard Worker 338*6dbdd20aSAndroid Build Coastguard Worker'''.format(tool_name).lstrip() 339*6dbdd20aSAndroid Build Coastguard Worker 340*6dbdd20aSAndroid Build Coastguard Worker # Find all the targets in the //python folder. 341*6dbdd20aSAndroid Build Coastguard Worker for target_name in default_python_targets: 342*6dbdd20aSAndroid Build Coastguard Worker target = gn.get_target(target_name) 343*6dbdd20aSAndroid Build Coastguard Worker res += self.gen_target_str(target) 344*6dbdd20aSAndroid Build Coastguard Worker 345*6dbdd20aSAndroid Build Coastguard Worker # Generate all the intermediate targets. 346*6dbdd20aSAndroid Build Coastguard Worker for target in sorted(itervalues(gn.all_targets)): 347*6dbdd20aSAndroid Build Coastguard Worker if target.name in default_python_targets: 348*6dbdd20aSAndroid Build Coastguard Worker continue 349*6dbdd20aSAndroid Build Coastguard Worker res += self.gen_target_str(target) 350*6dbdd20aSAndroid Build Coastguard Worker 351*6dbdd20aSAndroid Build Coastguard Worker return res 352*6dbdd20aSAndroid Build Coastguard Worker 353*6dbdd20aSAndroid Build Coastguard Worker 354*6dbdd20aSAndroid Build Coastguard Workerclass Error(Exception): 355*6dbdd20aSAndroid Build Coastguard Worker pass 356*6dbdd20aSAndroid Build Coastguard Worker 357*6dbdd20aSAndroid Build Coastguard Worker 358*6dbdd20aSAndroid Build Coastguard Workerclass BazelLabel(object): 359*6dbdd20aSAndroid Build Coastguard Worker 360*6dbdd20aSAndroid Build Coastguard Worker def __init__(self, name, type): 361*6dbdd20aSAndroid Build Coastguard Worker self.comment: Optional[str] = None 362*6dbdd20aSAndroid Build Coastguard Worker self.name = name 363*6dbdd20aSAndroid Build Coastguard Worker self.type = type 364*6dbdd20aSAndroid Build Coastguard Worker self.visibility: Union[List[str], str] = [] 365*6dbdd20aSAndroid Build Coastguard Worker self.srcs: Union[List[str], str] = [] 366*6dbdd20aSAndroid Build Coastguard Worker self.win_srcs: Union[List[str], str] = None 367*6dbdd20aSAndroid Build Coastguard Worker self.hdrs = [] 368*6dbdd20aSAndroid Build Coastguard Worker self.defines = [] 369*6dbdd20aSAndroid Build Coastguard Worker self.data = [] 370*6dbdd20aSAndroid Build Coastguard Worker self.deps = [] 371*6dbdd20aSAndroid Build Coastguard Worker self.external_deps = [] 372*6dbdd20aSAndroid Build Coastguard Worker self.tools = [] 373*6dbdd20aSAndroid Build Coastguard Worker self.outs = [] 374*6dbdd20aSAndroid Build Coastguard Worker self.exports = [] 375*6dbdd20aSAndroid Build Coastguard Worker self.main = None 376*6dbdd20aSAndroid Build Coastguard Worker self.cmd: Optional[str] = None 377*6dbdd20aSAndroid Build Coastguard Worker self.python_version: Optional[str] = None 378*6dbdd20aSAndroid Build Coastguard Worker self.root_dir: Optional[str] = None 379*6dbdd20aSAndroid Build Coastguard Worker self.namespace: Optional[str] = None 380*6dbdd20aSAndroid Build Coastguard Worker self.tags: List[str] = [] 381*6dbdd20aSAndroid Build Coastguard Worker 382*6dbdd20aSAndroid Build Coastguard Worker def __lt__(self, other): 383*6dbdd20aSAndroid Build Coastguard Worker if isinstance(other, self.__class__): 384*6dbdd20aSAndroid Build Coastguard Worker return self.name < other.name 385*6dbdd20aSAndroid Build Coastguard Worker raise TypeError( 386*6dbdd20aSAndroid Build Coastguard Worker '\'<\' not supported between instances of \'%s\' and \'%s\'' % 387*6dbdd20aSAndroid Build Coastguard Worker (type(self).__name__, type(other).__name__)) 388*6dbdd20aSAndroid Build Coastguard Worker 389*6dbdd20aSAndroid Build Coastguard Worker def __str__(self): 390*6dbdd20aSAndroid Build Coastguard Worker """Converts the object into a Bazel Starlark label.""" 391*6dbdd20aSAndroid Build Coastguard Worker res = '' 392*6dbdd20aSAndroid Build Coastguard Worker res += ('# GN target: %s\n' % self.comment) if self.comment else '' 393*6dbdd20aSAndroid Build Coastguard Worker res += '%s(\n' % self.type 394*6dbdd20aSAndroid Build Coastguard Worker any_deps = len(self.deps) + len(self.external_deps) > 0 395*6dbdd20aSAndroid Build Coastguard Worker ORD = [ 396*6dbdd20aSAndroid Build Coastguard Worker 'name', 'srcs', 'hdrs', 'defines', 'visibility', 'data', 'deps', 'outs', 397*6dbdd20aSAndroid Build Coastguard Worker 'cmd', 'tools', 'exports', 'main', 'python_version' 398*6dbdd20aSAndroid Build Coastguard Worker ] 399*6dbdd20aSAndroid Build Coastguard Worker hasher = lambda x: sum((99,) + tuple(ord(c) for c in x)) 400*6dbdd20aSAndroid Build Coastguard Worker key_sorter = lambda kv: ORD.index(kv[0]) if kv[0] in ORD else hasher(kv[0]) 401*6dbdd20aSAndroid Build Coastguard Worker for k, v in sorted(iteritems(self.__dict__), key=key_sorter): 402*6dbdd20aSAndroid Build Coastguard Worker if k in ('type', 'comment', 403*6dbdd20aSAndroid Build Coastguard Worker 'external_deps', 'win_srcs') or v is None or (v == [] and 404*6dbdd20aSAndroid Build Coastguard Worker (k != 'deps' or not any_deps)): 405*6dbdd20aSAndroid Build Coastguard Worker continue 406*6dbdd20aSAndroid Build Coastguard Worker res += ' %s = ' % k 407*6dbdd20aSAndroid Build Coastguard Worker if isinstance(v, basestring): 408*6dbdd20aSAndroid Build Coastguard Worker if v.startswith('PERFETTO_CONFIG.') or v.startswith('glob'): 409*6dbdd20aSAndroid Build Coastguard Worker res += '%s,\n' % v 410*6dbdd20aSAndroid Build Coastguard Worker else: 411*6dbdd20aSAndroid Build Coastguard Worker res += '"%s",\n' % v 412*6dbdd20aSAndroid Build Coastguard Worker elif isinstance(v, bool): 413*6dbdd20aSAndroid Build Coastguard Worker res += '%s,\n' % v 414*6dbdd20aSAndroid Build Coastguard Worker elif isinstance(v, list): 415*6dbdd20aSAndroid Build Coastguard Worker res += '[\n' 416*6dbdd20aSAndroid Build Coastguard Worker if k == 'deps' and len(self.external_deps) > 1: 417*6dbdd20aSAndroid Build Coastguard Worker indent = ' ' 418*6dbdd20aSAndroid Build Coastguard Worker else: 419*6dbdd20aSAndroid Build Coastguard Worker indent = ' ' 420*6dbdd20aSAndroid Build Coastguard Worker 421*6dbdd20aSAndroid Build Coastguard Worker non_win_srcs = {} 422*6dbdd20aSAndroid Build Coastguard Worker if k == "srcs" and self.win_srcs is not None: 423*6dbdd20aSAndroid Build Coastguard Worker non_win_srcs = sorted(set(self.srcs) - set(self.win_srcs)) 424*6dbdd20aSAndroid Build Coastguard Worker 425*6dbdd20aSAndroid Build Coastguard Worker for entry in sorted(v): 426*6dbdd20aSAndroid Build Coastguard Worker if entry in non_win_srcs: 427*6dbdd20aSAndroid Build Coastguard Worker continue 428*6dbdd20aSAndroid Build Coastguard Worker if entry.startswith('PERFETTO_CONFIG.'): 429*6dbdd20aSAndroid Build Coastguard Worker res += '%s %s,\n' % (indent, entry) 430*6dbdd20aSAndroid Build Coastguard Worker else: 431*6dbdd20aSAndroid Build Coastguard Worker res += '%s "%s",\n' % (indent, entry) 432*6dbdd20aSAndroid Build Coastguard Worker if non_win_srcs: 433*6dbdd20aSAndroid Build Coastguard Worker res += ' ] + select({\n' 434*6dbdd20aSAndroid Build Coastguard Worker res += ' "@platforms//os:windows": [],\n' 435*6dbdd20aSAndroid Build Coastguard Worker res += ' "//conditions:default": [\n' 436*6dbdd20aSAndroid Build Coastguard Worker for win_src in non_win_srcs: 437*6dbdd20aSAndroid Build Coastguard Worker res += ' "%s",\n' % win_src 438*6dbdd20aSAndroid Build Coastguard Worker res += ' ],\n' 439*6dbdd20aSAndroid Build Coastguard Worker res += ' }),\n' 440*6dbdd20aSAndroid Build Coastguard Worker else: 441*6dbdd20aSAndroid Build Coastguard Worker res += '%s]' % indent 442*6dbdd20aSAndroid Build Coastguard Worker if k == 'deps' and self.external_deps: 443*6dbdd20aSAndroid Build Coastguard Worker res += ' + %s' % self.external_deps[0] 444*6dbdd20aSAndroid Build Coastguard Worker for edep in self.external_deps[1:]: 445*6dbdd20aSAndroid Build Coastguard Worker if isinstance(edep, list): 446*6dbdd20aSAndroid Build Coastguard Worker res += ' + [\n' 447*6dbdd20aSAndroid Build Coastguard Worker for inner_dep in edep: 448*6dbdd20aSAndroid Build Coastguard Worker res += ' "%s",\n' % inner_dep 449*6dbdd20aSAndroid Build Coastguard Worker res += ' ]' 450*6dbdd20aSAndroid Build Coastguard Worker else: 451*6dbdd20aSAndroid Build Coastguard Worker res += ' +\n%s%s' % (indent, edep) 452*6dbdd20aSAndroid Build Coastguard Worker res += ',\n' 453*6dbdd20aSAndroid Build Coastguard Worker else: 454*6dbdd20aSAndroid Build Coastguard Worker raise Error('Unsupported value %s', type(v)) 455*6dbdd20aSAndroid Build Coastguard Worker res += ')\n\n' 456*6dbdd20aSAndroid Build Coastguard Worker return res 457*6dbdd20aSAndroid Build Coastguard Worker 458*6dbdd20aSAndroid Build Coastguard Worker 459*6dbdd20aSAndroid Build Coastguard Workerdef get_bazel_label_name(gn_name: str): 460*6dbdd20aSAndroid Build Coastguard Worker """Converts a GN target name into a Bazel label name. 461*6dbdd20aSAndroid Build Coastguard Worker 462*6dbdd20aSAndroid Build Coastguard Worker If target is in the public target list, returns only the GN target name, 463*6dbdd20aSAndroid Build Coastguard Worker e.g.: //src/ipc:perfetto_ipc -> perfetto_ipc 464*6dbdd20aSAndroid Build Coastguard Worker 465*6dbdd20aSAndroid Build Coastguard Worker Otherwise, in the case of an intermediate target, returns a mangled path. 466*6dbdd20aSAndroid Build Coastguard Worker e.g.: //include/perfetto/base:base -> include_perfetto_base_base. 467*6dbdd20aSAndroid Build Coastguard Worker """ 468*6dbdd20aSAndroid Build Coastguard Worker if gn_name in default_targets: 469*6dbdd20aSAndroid Build Coastguard Worker return gn_utils.label_without_toolchain(gn_name).split(':')[1] 470*6dbdd20aSAndroid Build Coastguard Worker return gn_utils.label_to_target_name_with_path(gn_name) 471*6dbdd20aSAndroid Build Coastguard Worker 472*6dbdd20aSAndroid Build Coastguard Worker 473*6dbdd20aSAndroid Build Coastguard Workerdef get_bazel_python_label_name(gn_name: str): 474*6dbdd20aSAndroid Build Coastguard Worker """Converts a Python GN label into a Bazel label.""" 475*6dbdd20aSAndroid Build Coastguard Worker name = re.sub(r'^//python:?', '', gn_name) 476*6dbdd20aSAndroid Build Coastguard Worker return gn_utils.label_to_target_name_with_path(name) 477*6dbdd20aSAndroid Build Coastguard Worker 478*6dbdd20aSAndroid Build Coastguard Worker 479*6dbdd20aSAndroid Build Coastguard Workerdef get_bazel_proto_sources_label(target_name: str): 480*6dbdd20aSAndroid Build Coastguard Worker """Converts a GN target name into a Bazel proto label name.""" 481*6dbdd20aSAndroid Build Coastguard Worker return re.sub('_(lite|zero|cpp|ipc|source_set|descriptor)$', '', 482*6dbdd20aSAndroid Build Coastguard Worker get_bazel_label_name(target_name)) + '_protos' 483*6dbdd20aSAndroid Build Coastguard Worker 484*6dbdd20aSAndroid Build Coastguard Worker 485*6dbdd20aSAndroid Build Coastguard Workerdef gen_proto_label(target: GnParser.Target): 486*6dbdd20aSAndroid Build Coastguard Worker """ Generates the xx_proto_library label for proto targets.""" 487*6dbdd20aSAndroid Build Coastguard Worker assert (target.type == 'proto_library') 488*6dbdd20aSAndroid Build Coastguard Worker 489*6dbdd20aSAndroid Build Coastguard Worker sources_label_name = get_bazel_proto_sources_label(target.name) 490*6dbdd20aSAndroid Build Coastguard Worker 491*6dbdd20aSAndroid Build Coastguard Worker # For 'source_set' plugins, we don't want to generate any plugin-dependent 492*6dbdd20aSAndroid Build Coastguard Worker # targets so just return the label of the proto sources only. 493*6dbdd20aSAndroid Build Coastguard Worker if target.proto_plugin == 'source_set': 494*6dbdd20aSAndroid Build Coastguard Worker sources_label = BazelLabel(sources_label_name, 'perfetto_proto_library') 495*6dbdd20aSAndroid Build Coastguard Worker sources_label.comment = target.name 496*6dbdd20aSAndroid Build Coastguard Worker assert (all(x.startswith('//') for x in target.sources)) 497*6dbdd20aSAndroid Build Coastguard Worker assert (all(x.endswith('.proto') for x in target.sources)) 498*6dbdd20aSAndroid Build Coastguard Worker sources_label.srcs = sorted([x[2:] for x in target.sources]) # Strip //. 499*6dbdd20aSAndroid Build Coastguard Worker sources_label.deps = sorted([ 500*6dbdd20aSAndroid Build Coastguard Worker ':' + get_bazel_proto_sources_label(x.name) 501*6dbdd20aSAndroid Build Coastguard Worker for x in target.transitive_proto_deps() 502*6dbdd20aSAndroid Build Coastguard Worker ]) 503*6dbdd20aSAndroid Build Coastguard Worker 504*6dbdd20aSAndroid Build Coastguard Worker # In Bazel, proto_paths are not a supported concept becauase strong 505*6dbdd20aSAndroid Build Coastguard Worker # dependency checking is enabled. Instead, we need to depend on the target 506*6dbdd20aSAndroid Build Coastguard Worker # which includes the proto we want to depend on. 507*6dbdd20aSAndroid Build Coastguard Worker # For example, we include the proto_path |buildtools_protobuf_src| because 508*6dbdd20aSAndroid Build Coastguard Worker # we want to depend on the "google/protobuf/descriptor.proto" proto file. 509*6dbdd20aSAndroid Build Coastguard Worker # This will be exposed by the |protobuf_descriptor_proto| dep. 510*6dbdd20aSAndroid Build Coastguard Worker if buildtools_protobuf_src in target.proto_paths: 511*6dbdd20aSAndroid Build Coastguard Worker sources_label.external_deps = [ 512*6dbdd20aSAndroid Build Coastguard Worker 'PERFETTO_CONFIG.deps.protobuf_descriptor_proto' 513*6dbdd20aSAndroid Build Coastguard Worker ] 514*6dbdd20aSAndroid Build Coastguard Worker 515*6dbdd20aSAndroid Build Coastguard Worker sources_label.visibility = ['PERFETTO_CONFIG.proto_library_visibility'] 516*6dbdd20aSAndroid Build Coastguard Worker 517*6dbdd20aSAndroid Build Coastguard Worker sources_label.exports = sorted( 518*6dbdd20aSAndroid Build Coastguard Worker [':' + get_bazel_proto_sources_label(d) for d in target.proto_exports]) 519*6dbdd20aSAndroid Build Coastguard Worker return sources_label 520*6dbdd20aSAndroid Build Coastguard Worker 521*6dbdd20aSAndroid Build Coastguard Worker # For all other types of plugins, we need to generate 522*6dbdd20aSAndroid Build Coastguard Worker if target.proto_plugin == 'proto': 523*6dbdd20aSAndroid Build Coastguard Worker plugin_label_type = 'perfetto_cc_proto_library' 524*6dbdd20aSAndroid Build Coastguard Worker elif target.proto_plugin == 'protozero': 525*6dbdd20aSAndroid Build Coastguard Worker plugin_label_type = 'perfetto_cc_protozero_library' 526*6dbdd20aSAndroid Build Coastguard Worker elif target.proto_plugin == 'cppgen': 527*6dbdd20aSAndroid Build Coastguard Worker plugin_label_type = 'perfetto_cc_protocpp_library' 528*6dbdd20aSAndroid Build Coastguard Worker elif target.proto_plugin == 'ipc': 529*6dbdd20aSAndroid Build Coastguard Worker plugin_label_type = 'perfetto_cc_ipc_library' 530*6dbdd20aSAndroid Build Coastguard Worker elif target.proto_plugin == 'descriptor': 531*6dbdd20aSAndroid Build Coastguard Worker plugin_label_type = 'perfetto_proto_descriptor' 532*6dbdd20aSAndroid Build Coastguard Worker else: 533*6dbdd20aSAndroid Build Coastguard Worker raise Error('Unknown proto plugin: %s' % target.proto_plugin) 534*6dbdd20aSAndroid Build Coastguard Worker plugin_label_name = get_bazel_label_name(target.name) 535*6dbdd20aSAndroid Build Coastguard Worker plugin_label = BazelLabel(plugin_label_name, plugin_label_type) 536*6dbdd20aSAndroid Build Coastguard Worker plugin_label.comment = target.name 537*6dbdd20aSAndroid Build Coastguard Worker 538*6dbdd20aSAndroid Build Coastguard Worker # When using the plugins we need to pass down also the transitive deps. 539*6dbdd20aSAndroid Build Coastguard Worker # For instance consider foo.proto including common.proto. The generated 540*6dbdd20aSAndroid Build Coastguard Worker # foo.cc will #include "common.gen.h". Hence the generated cc_protocpp_library 541*6dbdd20aSAndroid Build Coastguard Worker # rule need to pass down the dependency on the target that generates 542*6dbdd20aSAndroid Build Coastguard Worker # common.gen.{cc,h}. 543*6dbdd20aSAndroid Build Coastguard Worker if target.proto_plugin in ('cppgen', 'ipc', 'protozero'): 544*6dbdd20aSAndroid Build Coastguard Worker plugin_label.deps += [ 545*6dbdd20aSAndroid Build Coastguard Worker ':' + get_bazel_label_name(x.name) 546*6dbdd20aSAndroid Build Coastguard Worker for x in target.transitive_proto_deps() 547*6dbdd20aSAndroid Build Coastguard Worker ] 548*6dbdd20aSAndroid Build Coastguard Worker 549*6dbdd20aSAndroid Build Coastguard Worker # Add any dependencies on source_set targets (i.e. targets containing proto 550*6dbdd20aSAndroid Build Coastguard Worker # files). For descriptors, we will have an explicit edge between the 551*6dbdd20aSAndroid Build Coastguard Worker # descriptor and source set wheras for other plugin types, this edge is 552*6dbdd20aSAndroid Build Coastguard Worker # implicit. 553*6dbdd20aSAndroid Build Coastguard Worker if target.proto_plugin == 'descriptor': 554*6dbdd20aSAndroid Build Coastguard Worker plugin_label.deps += [ 555*6dbdd20aSAndroid Build Coastguard Worker ':' + get_bazel_proto_sources_label(x.name) 556*6dbdd20aSAndroid Build Coastguard Worker for x in target.proto_deps() 557*6dbdd20aSAndroid Build Coastguard Worker ] 558*6dbdd20aSAndroid Build Coastguard Worker else: 559*6dbdd20aSAndroid Build Coastguard Worker plugin_label.deps += [':' + sources_label_name] 560*6dbdd20aSAndroid Build Coastguard Worker 561*6dbdd20aSAndroid Build Coastguard Worker # Since the descriptor generates an explicit output file which can be 562*6dbdd20aSAndroid Build Coastguard Worker # referenced by other targets, we specify a name for it. 563*6dbdd20aSAndroid Build Coastguard Worker if target.proto_plugin == 'descriptor': 564*6dbdd20aSAndroid Build Coastguard Worker plugin_label.outs = [plugin_label_name + '.bin'] 565*6dbdd20aSAndroid Build Coastguard Worker 566*6dbdd20aSAndroid Build Coastguard Worker return plugin_label 567*6dbdd20aSAndroid Build Coastguard Worker 568*6dbdd20aSAndroid Build Coastguard Worker 569*6dbdd20aSAndroid Build Coastguard Workerdef gen_proto_group_target(gn: GnParser, name: str, desc: Dict[str, Any]): 570*6dbdd20aSAndroid Build Coastguard Worker # Get a recursive list of the proto_library targets rooted here which 571*6dbdd20aSAndroid Build Coastguard Worker # have src. 572*6dbdd20aSAndroid Build Coastguard Worker deps_set = set(desc['sources']) 573*6dbdd20aSAndroid Build Coastguard Worker for target_name in desc['sources']: 574*6dbdd20aSAndroid Build Coastguard Worker target = gn.get_target(target_name) 575*6dbdd20aSAndroid Build Coastguard Worker deps_set.update(d.name for d in target.transitive_proto_deps()) 576*6dbdd20aSAndroid Build Coastguard Worker 577*6dbdd20aSAndroid Build Coastguard Worker # First, create a root source set target which references all the child 578*6dbdd20aSAndroid Build Coastguard Worker # source set targets. We publish this as well as depending on this in all 579*6dbdd20aSAndroid Build Coastguard Worker # subsequent targets. 580*6dbdd20aSAndroid Build Coastguard Worker sources_label = BazelLabel(name + '_proto', 'perfetto_proto_library') 581*6dbdd20aSAndroid Build Coastguard Worker sources_label.deps = [ 582*6dbdd20aSAndroid Build Coastguard Worker ':' + get_bazel_proto_sources_label(name) 583*6dbdd20aSAndroid Build Coastguard Worker for name in sorted(list(deps_set)) 584*6dbdd20aSAndroid Build Coastguard Worker ] 585*6dbdd20aSAndroid Build Coastguard Worker sources_label.comment = f'''[{', '.join(desc['sources'])}]''' 586*6dbdd20aSAndroid Build Coastguard Worker 587*6dbdd20aSAndroid Build Coastguard Worker cc_label = BazelLabel(name + '_cc_proto', 'perfetto_cc_proto_library') 588*6dbdd20aSAndroid Build Coastguard Worker cc_label.deps = [':' + sources_label.name] 589*6dbdd20aSAndroid Build Coastguard Worker cc_label.comment = sources_label.comment 590*6dbdd20aSAndroid Build Coastguard Worker 591*6dbdd20aSAndroid Build Coastguard Worker java_label = BazelLabel(name + '_java_proto', 'perfetto_java_proto_library') 592*6dbdd20aSAndroid Build Coastguard Worker java_label.deps = [':' + sources_label.name] 593*6dbdd20aSAndroid Build Coastguard Worker java_label.comment = sources_label.comment 594*6dbdd20aSAndroid Build Coastguard Worker 595*6dbdd20aSAndroid Build Coastguard Worker lite_name = name + '_java_proto_lite' 596*6dbdd20aSAndroid Build Coastguard Worker java_lite_label = BazelLabel(lite_name, 'perfetto_java_lite_proto_library') 597*6dbdd20aSAndroid Build Coastguard Worker java_lite_label.deps = [':' + sources_label.name] 598*6dbdd20aSAndroid Build Coastguard Worker java_lite_label.comment = sources_label.comment 599*6dbdd20aSAndroid Build Coastguard Worker 600*6dbdd20aSAndroid Build Coastguard Worker py_label = BazelLabel(name + '_py_pb2', 'perfetto_py_proto_library') 601*6dbdd20aSAndroid Build Coastguard Worker py_label.deps = [':' + sources_label.name] 602*6dbdd20aSAndroid Build Coastguard Worker py_label.comment = sources_label.comment 603*6dbdd20aSAndroid Build Coastguard Worker 604*6dbdd20aSAndroid Build Coastguard Worker visibility = desc['visibility'] 605*6dbdd20aSAndroid Build Coastguard Worker if visibility: 606*6dbdd20aSAndroid Build Coastguard Worker sources_label.visibility = visibility 607*6dbdd20aSAndroid Build Coastguard Worker cc_label.visibility = visibility 608*6dbdd20aSAndroid Build Coastguard Worker java_label.visibility = visibility 609*6dbdd20aSAndroid Build Coastguard Worker java_lite_label.visibility = visibility 610*6dbdd20aSAndroid Build Coastguard Worker py_label.visibility = visibility 611*6dbdd20aSAndroid Build Coastguard Worker 612*6dbdd20aSAndroid Build Coastguard Worker return [sources_label, cc_label, java_label, java_lite_label, py_label] 613*6dbdd20aSAndroid Build Coastguard Worker 614*6dbdd20aSAndroid Build Coastguard Worker 615*6dbdd20aSAndroid Build Coastguard Workerdef gen_cc_proto_descriptor(target: GnParser.Target): 616*6dbdd20aSAndroid Build Coastguard Worker label = BazelLabel( 617*6dbdd20aSAndroid Build Coastguard Worker get_bazel_label_name(target.name), 'perfetto_cc_proto_descriptor') 618*6dbdd20aSAndroid Build Coastguard Worker label.comment = target.name 619*6dbdd20aSAndroid Build Coastguard Worker label.deps += [ 620*6dbdd20aSAndroid Build Coastguard Worker ':' + get_bazel_label_name(x.name) for x in target.proto_deps() 621*6dbdd20aSAndroid Build Coastguard Worker ] 622*6dbdd20aSAndroid Build Coastguard Worker label.deps += [ 623*6dbdd20aSAndroid Build Coastguard Worker gn_utils.label_to_path(src) 624*6dbdd20aSAndroid Build Coastguard Worker for src in target.inputs 625*6dbdd20aSAndroid Build Coastguard Worker if "tmp.gn_utils" not in src 626*6dbdd20aSAndroid Build Coastguard Worker ] 627*6dbdd20aSAndroid Build Coastguard Worker 628*6dbdd20aSAndroid Build Coastguard Worker label.outs += target.outputs 629*6dbdd20aSAndroid Build Coastguard Worker return [label] 630*6dbdd20aSAndroid Build Coastguard Worker 631*6dbdd20aSAndroid Build Coastguard Worker 632*6dbdd20aSAndroid Build Coastguard Workerdef gen_cc_amalgamated_sql(target: GnParser.Target): 633*6dbdd20aSAndroid Build Coastguard Worker label = BazelLabel( 634*6dbdd20aSAndroid Build Coastguard Worker get_bazel_label_name(target.name), 'perfetto_cc_amalgamated_sql') 635*6dbdd20aSAndroid Build Coastguard Worker 636*6dbdd20aSAndroid Build Coastguard Worker def find_arg(name): 637*6dbdd20aSAndroid Build Coastguard Worker for i, arg in enumerate(target.args): 638*6dbdd20aSAndroid Build Coastguard Worker if arg.startswith(f'--{name}'): 639*6dbdd20aSAndroid Build Coastguard Worker return target.args[i + 1] 640*6dbdd20aSAndroid Build Coastguard Worker 641*6dbdd20aSAndroid Build Coastguard Worker label.comment = target.name 642*6dbdd20aSAndroid Build Coastguard Worker label.namespace = find_arg('namespace') 643*6dbdd20aSAndroid Build Coastguard Worker 644*6dbdd20aSAndroid Build Coastguard Worker label.deps += sorted( 645*6dbdd20aSAndroid Build Coastguard Worker ':' + get_bazel_label_name(x.name) for x in target.transitive_deps) 646*6dbdd20aSAndroid Build Coastguard Worker label.outs += target.outputs 647*6dbdd20aSAndroid Build Coastguard Worker return [label] 648*6dbdd20aSAndroid Build Coastguard Worker 649*6dbdd20aSAndroid Build Coastguard Worker 650*6dbdd20aSAndroid Build Coastguard Workerdef gen_sql_source_set(target: GnParser.Target): 651*6dbdd20aSAndroid Build Coastguard Worker label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_filegroup') 652*6dbdd20aSAndroid Build Coastguard Worker label.comment = target.name 653*6dbdd20aSAndroid Build Coastguard Worker label.srcs += (gn_utils.label_to_path(x) for x in target.inputs) 654*6dbdd20aSAndroid Build Coastguard Worker return [label] 655*6dbdd20aSAndroid Build Coastguard Worker 656*6dbdd20aSAndroid Build Coastguard Worker 657*6dbdd20aSAndroid Build Coastguard Workerdef gen_cc_tp_tables(target: GnParser.Target): 658*6dbdd20aSAndroid Build Coastguard Worker label = BazelLabel(get_bazel_label_name(target.name), 'perfetto_cc_tp_tables') 659*6dbdd20aSAndroid Build Coastguard Worker label.comment = target.name 660*6dbdd20aSAndroid Build Coastguard Worker label.srcs += (gn_utils.label_to_path(x) for x in target.sources) 661*6dbdd20aSAndroid Build Coastguard Worker label.deps += sorted(':' + get_bazel_label_name(x.name) 662*6dbdd20aSAndroid Build Coastguard Worker for x in target.transitive_deps 663*6dbdd20aSAndroid Build Coastguard Worker if x.name not in default_python_targets) 664*6dbdd20aSAndroid Build Coastguard Worker label.outs += target.outputs 665*6dbdd20aSAndroid Build Coastguard Worker return [label] 666*6dbdd20aSAndroid Build Coastguard Worker 667*6dbdd20aSAndroid Build Coastguard Worker 668*6dbdd20aSAndroid Build Coastguard Workerdef gen_target_helper(gn_target: GnParser.Target, win_target: GnParser.Target = None): 669*6dbdd20aSAndroid Build Coastguard Worker if gn_target.type == 'proto_library': 670*6dbdd20aSAndroid Build Coastguard Worker return [gen_proto_label(gn_target)] 671*6dbdd20aSAndroid Build Coastguard Worker elif gn_target.type == 'action': 672*6dbdd20aSAndroid Build Coastguard Worker if gn_target.name in custom_actions: 673*6dbdd20aSAndroid Build Coastguard Worker return custom_actions[gn_target.name](gn_target) 674*6dbdd20aSAndroid Build Coastguard Worker if gn_target.custom_action_type == 'sql_amalgamation': 675*6dbdd20aSAndroid Build Coastguard Worker return gen_cc_amalgamated_sql(gn_target) 676*6dbdd20aSAndroid Build Coastguard Worker if gn_target.custom_action_type == 'sql_source_set': 677*6dbdd20aSAndroid Build Coastguard Worker return gen_sql_source_set(gn_target) 678*6dbdd20aSAndroid Build Coastguard Worker if gn_target.custom_action_type == 'cc_proto_descriptor': 679*6dbdd20aSAndroid Build Coastguard Worker return gen_cc_proto_descriptor(gn_target) 680*6dbdd20aSAndroid Build Coastguard Worker if gn_target.custom_action_type == 'tp_tables': 681*6dbdd20aSAndroid Build Coastguard Worker return gen_cc_tp_tables(gn_target) 682*6dbdd20aSAndroid Build Coastguard Worker return [] 683*6dbdd20aSAndroid Build Coastguard Worker elif gn_target.type == 'group': 684*6dbdd20aSAndroid Build Coastguard Worker return [] 685*6dbdd20aSAndroid Build Coastguard Worker elif gn_target.type == 'executable': 686*6dbdd20aSAndroid Build Coastguard Worker bazel_type = 'perfetto_cc_binary' 687*6dbdd20aSAndroid Build Coastguard Worker elif gn_target.type == 'shared_library': 688*6dbdd20aSAndroid Build Coastguard Worker bazel_type = 'perfetto_cc_library' 689*6dbdd20aSAndroid Build Coastguard Worker elif gn_target.type == 'static_library': 690*6dbdd20aSAndroid Build Coastguard Worker bazel_type = 'perfetto_cc_library' 691*6dbdd20aSAndroid Build Coastguard Worker elif gn_target.type == 'source_set': 692*6dbdd20aSAndroid Build Coastguard Worker bazel_type = 'perfetto_filegroup' 693*6dbdd20aSAndroid Build Coastguard Worker elif gn_target.type == 'generated_file': 694*6dbdd20aSAndroid Build Coastguard Worker return [] 695*6dbdd20aSAndroid Build Coastguard Worker else: 696*6dbdd20aSAndroid Build Coastguard Worker raise Error('target type not supported: %s' % gn_target.type) 697*6dbdd20aSAndroid Build Coastguard Worker 698*6dbdd20aSAndroid Build Coastguard Worker label = BazelLabel(get_bazel_label_name(gn_target.name), bazel_type) 699*6dbdd20aSAndroid Build Coastguard Worker label.comment = gn_target.name 700*6dbdd20aSAndroid Build Coastguard Worker 701*6dbdd20aSAndroid Build Coastguard Worker # Supporting 'public' on source_sets would require not converting them to 702*6dbdd20aSAndroid Build Coastguard Worker # filegroups in bazel. 703*6dbdd20aSAndroid Build Coastguard Worker if gn_target.public_headers: 704*6dbdd20aSAndroid Build Coastguard Worker if bazel_type == 'perfetto_cc_library': 705*6dbdd20aSAndroid Build Coastguard Worker label.hdrs += [x[2:] for x in gn_target.public_headers] 706*6dbdd20aSAndroid Build Coastguard Worker else: 707*6dbdd20aSAndroid Build Coastguard Worker raise Error('%s: \'public\' currently supported only for cc_library' % 708*6dbdd20aSAndroid Build Coastguard Worker gn_target.name) 709*6dbdd20aSAndroid Build Coastguard Worker 710*6dbdd20aSAndroid Build Coastguard Worker raw_srcs = [x[2:] for x in gn_target.sources] 711*6dbdd20aSAndroid Build Coastguard Worker raw_srcs += [x[2:] for x in gn_target.inputs] 712*6dbdd20aSAndroid Build Coastguard Worker if bazel_type == 'perfetto_cc_library': 713*6dbdd20aSAndroid Build Coastguard Worker label.srcs += [x for x in raw_srcs if not x.startswith('include')] 714*6dbdd20aSAndroid Build Coastguard Worker label.hdrs += [x for x in raw_srcs if x.startswith('include')] 715*6dbdd20aSAndroid Build Coastguard Worker 716*6dbdd20aSAndroid Build Coastguard Worker # Most Perfetto libraries cannot be dynamically linked as they would 717*6dbdd20aSAndroid Build Coastguard Worker # cause ODR violations. 718*6dbdd20aSAndroid Build Coastguard Worker label.__dict__['linkstatic'] = True 719*6dbdd20aSAndroid Build Coastguard Worker else: 720*6dbdd20aSAndroid Build Coastguard Worker label.srcs = raw_srcs 721*6dbdd20aSAndroid Build Coastguard Worker 722*6dbdd20aSAndroid Build Coastguard Worker is_public = gn_target.name in public_targets 723*6dbdd20aSAndroid Build Coastguard Worker is_public_for_allowlist = gn_target.name in allowlist_public_targets 724*6dbdd20aSAndroid Build Coastguard Worker if is_public and is_public_for_allowlist: 725*6dbdd20aSAndroid Build Coastguard Worker raise Error('Target %s in both public_targets and allowlist_public_targets', gn.target.name) 726*6dbdd20aSAndroid Build Coastguard Worker elif is_public: 727*6dbdd20aSAndroid Build Coastguard Worker label.visibility = ['//visibility:public'] 728*6dbdd20aSAndroid Build Coastguard Worker elif is_public_for_allowlist: 729*6dbdd20aSAndroid Build Coastguard Worker label.visibility = ALLOWLIST_PUBLIC_VISIBILITY 730*6dbdd20aSAndroid Build Coastguard Worker 731*6dbdd20aSAndroid Build Coastguard Worker if win_target: 732*6dbdd20aSAndroid Build Coastguard Worker label.win_srcs = list(set(label.srcs) & {s[2:] for s in win_target.sources | win_target.inputs}) 733*6dbdd20aSAndroid Build Coastguard Worker 734*6dbdd20aSAndroid Build Coastguard Worker if gn_target.type in gn_utils.LINKER_UNIT_TYPES: 735*6dbdd20aSAndroid Build Coastguard Worker # |source_sets| contains the transitive set of source_set deps. 736*6dbdd20aSAndroid Build Coastguard Worker for trans_dep in gn_target.transitive_source_set_deps(): 737*6dbdd20aSAndroid Build Coastguard Worker name = ':' + get_bazel_label_name(trans_dep.name) 738*6dbdd20aSAndroid Build Coastguard Worker if name.startswith( 739*6dbdd20aSAndroid Build Coastguard Worker ':include_perfetto_') and gn_target.type != 'executable': 740*6dbdd20aSAndroid Build Coastguard Worker label.hdrs += [name] 741*6dbdd20aSAndroid Build Coastguard Worker else: 742*6dbdd20aSAndroid Build Coastguard Worker if win_target: 743*6dbdd20aSAndroid Build Coastguard Worker win_target_names = [target.name for target in win_target.transitive_source_set_deps()] 744*6dbdd20aSAndroid Build Coastguard Worker if trans_dep.name in win_target_names: 745*6dbdd20aSAndroid Build Coastguard Worker label.win_srcs += [name] 746*6dbdd20aSAndroid Build Coastguard Worker 747*6dbdd20aSAndroid Build Coastguard Worker label.srcs += [name] 748*6dbdd20aSAndroid Build Coastguard Worker 749*6dbdd20aSAndroid Build Coastguard Worker # Add defines from all transitive dependencies. 750*6dbdd20aSAndroid Build Coastguard Worker label.defines += trans_dep.defines 751*6dbdd20aSAndroid Build Coastguard Worker 752*6dbdd20aSAndroid Build Coastguard Worker for dep in sorted(gn_target.non_proto_or_source_set_deps()): 753*6dbdd20aSAndroid Build Coastguard Worker dep_name = dep.name 754*6dbdd20aSAndroid Build Coastguard Worker if dep_name.startswith('//gn:'): 755*6dbdd20aSAndroid Build Coastguard Worker assert (dep_name in external_deps), dep 756*6dbdd20aSAndroid Build Coastguard Worker 757*6dbdd20aSAndroid Build Coastguard Worker # tp_tables produces a filegroup not a cc_library so should end up srcs 758*6dbdd20aSAndroid Build Coastguard Worker # not deps. 759*6dbdd20aSAndroid Build Coastguard Worker if dep.custom_action_type == 'tp_tables': 760*6dbdd20aSAndroid Build Coastguard Worker label_name = ':' + get_bazel_label_name(dep_name) 761*6dbdd20aSAndroid Build Coastguard Worker win_target_names = [target.name for target in win_target.non_proto_or_source_set_deps()] 762*6dbdd20aSAndroid Build Coastguard Worker if win_target and dep_name in win_target_names: 763*6dbdd20aSAndroid Build Coastguard Worker label.win_srcs += [label_name] 764*6dbdd20aSAndroid Build Coastguard Worker label.srcs += [label_name] 765*6dbdd20aSAndroid Build Coastguard Worker elif dep_name in external_deps: 766*6dbdd20aSAndroid Build Coastguard Worker assert (isinstance(external_deps[dep_name], list)) 767*6dbdd20aSAndroid Build Coastguard Worker label.external_deps += external_deps[dep_name] 768*6dbdd20aSAndroid Build Coastguard Worker else: 769*6dbdd20aSAndroid Build Coastguard Worker label.deps += [':' + get_bazel_label_name(dep_name)] 770*6dbdd20aSAndroid Build Coastguard Worker 771*6dbdd20aSAndroid Build Coastguard Worker label.deps += [ 772*6dbdd20aSAndroid Build Coastguard Worker ':' + get_bazel_label_name(x.name) 773*6dbdd20aSAndroid Build Coastguard Worker for x in gn_target.transitive_cpp_proto_deps() 774*6dbdd20aSAndroid Build Coastguard Worker ] 775*6dbdd20aSAndroid Build Coastguard Worker 776*6dbdd20aSAndroid Build Coastguard Worker # All items starting with : need to be sorted to the end of the list. 777*6dbdd20aSAndroid Build Coastguard Worker # However, Python makes specifying a comparator function hard so cheat 778*6dbdd20aSAndroid Build Coastguard Worker # instead and make everything start with : sort as if it started with | 779*6dbdd20aSAndroid Build Coastguard Worker # As | > all other normal ASCII characters, this will lead to all : targets 780*6dbdd20aSAndroid Build Coastguard Worker # starting with : to be sorted to the end. 781*6dbdd20aSAndroid Build Coastguard Worker label.srcs = sorted(label.srcs, key=lambda x: x.replace(':', '|')) 782*6dbdd20aSAndroid Build Coastguard Worker if win_target: 783*6dbdd20aSAndroid Build Coastguard Worker label.win_srcs = sorted(label.win_srcs, key=lambda x: x.replace(':', '|')) 784*6dbdd20aSAndroid Build Coastguard Worker 785*6dbdd20aSAndroid Build Coastguard Worker label.deps = sorted(label.deps) 786*6dbdd20aSAndroid Build Coastguard Worker label.hdrs = sorted(label.hdrs) 787*6dbdd20aSAndroid Build Coastguard Worker label.defines = sorted(filter_defines(set(label.defines))) 788*6dbdd20aSAndroid Build Coastguard Worker return [label] 789*6dbdd20aSAndroid Build Coastguard Worker 790*6dbdd20aSAndroid Build Coastguard Worker 791*6dbdd20aSAndroid Build Coastguard Workerdef gen_target(gn_target: GnParser.Target, win_target: GnParser.Target = None): 792*6dbdd20aSAndroid Build Coastguard Worker targets = gen_target_helper(gn_target, win_target) 793*6dbdd20aSAndroid Build Coastguard Worker if gn_target.name not in target_overrides: 794*6dbdd20aSAndroid Build Coastguard Worker return targets 795*6dbdd20aSAndroid Build Coastguard Worker for target in targets: 796*6dbdd20aSAndroid Build Coastguard Worker for key, add_val in target_overrides[gn_target.name].items(): 797*6dbdd20aSAndroid Build Coastguard Worker setattr(target, key, add_val) 798*6dbdd20aSAndroid Build Coastguard Worker return targets 799*6dbdd20aSAndroid Build Coastguard Worker 800*6dbdd20aSAndroid Build Coastguard Worker 801*6dbdd20aSAndroid Build Coastguard Workerdef gen_target_str(gn_target, win_target: GnParser.Target = None): 802*6dbdd20aSAndroid Build Coastguard Worker return ''.join(str(x) for x in gen_target(gn_target, win_target)) 803*6dbdd20aSAndroid Build Coastguard Worker 804*6dbdd20aSAndroid Build Coastguard Worker 805*6dbdd20aSAndroid Build Coastguard Workerdef generate_build(gn_desc, gn_desc_win, targets, extras): 806*6dbdd20aSAndroid Build Coastguard Worker gn = gn_utils.GnParser(gn_desc) 807*6dbdd20aSAndroid Build Coastguard Worker gn_win = gn_utils.GnParser(gn_desc_win) 808*6dbdd20aSAndroid Build Coastguard Worker project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) 809*6dbdd20aSAndroid Build Coastguard Worker tool_name = os.path.relpath(os.path.abspath(__file__), project_root) 810*6dbdd20aSAndroid Build Coastguard Worker tool_name = tool_name.replace('\\', '/') 811*6dbdd20aSAndroid Build Coastguard Worker res = ''' 812*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2019 The Android Open Source Project 813*6dbdd20aSAndroid Build Coastguard Worker# 814*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 815*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 816*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 817*6dbdd20aSAndroid Build Coastguard Worker# 818*6dbdd20aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 819*6dbdd20aSAndroid Build Coastguard Worker# 820*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 821*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 822*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 823*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 824*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License. 825*6dbdd20aSAndroid Build Coastguard Worker# 826*6dbdd20aSAndroid Build Coastguard Worker# This file is automatically generated by {}. Do not edit. 827*6dbdd20aSAndroid Build Coastguard Worker 828*6dbdd20aSAndroid Build Coastguard Workerload("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG") 829*6dbdd20aSAndroid Build Coastguard Workerload( 830*6dbdd20aSAndroid Build Coastguard Worker "@perfetto//bazel:rules.bzl", 831*6dbdd20aSAndroid Build Coastguard Worker "perfetto_build_config_cc_library", 832*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_amalgamated_sql", 833*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_binary", 834*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_ipc_library", 835*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_library", 836*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_proto_descriptor", 837*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_proto_library", 838*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_protocpp_library", 839*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_protozero_library", 840*6dbdd20aSAndroid Build Coastguard Worker "perfetto_cc_tp_tables", 841*6dbdd20aSAndroid Build Coastguard Worker "perfetto_filegroup", 842*6dbdd20aSAndroid Build Coastguard Worker "perfetto_genrule", 843*6dbdd20aSAndroid Build Coastguard Worker "perfetto_go_proto_library", 844*6dbdd20aSAndroid Build Coastguard Worker "perfetto_java_lite_proto_library", 845*6dbdd20aSAndroid Build Coastguard Worker "perfetto_java_proto_library", 846*6dbdd20aSAndroid Build Coastguard Worker "perfetto_proto_descriptor", 847*6dbdd20aSAndroid Build Coastguard Worker "perfetto_proto_library", 848*6dbdd20aSAndroid Build Coastguard Worker "perfetto_py_binary", 849*6dbdd20aSAndroid Build Coastguard Worker "perfetto_py_library", 850*6dbdd20aSAndroid Build Coastguard Worker "perfetto_py_proto_library", 851*6dbdd20aSAndroid Build Coastguard Worker "perfetto_jspb_proto_library", 852*6dbdd20aSAndroid Build Coastguard Worker) 853*6dbdd20aSAndroid Build Coastguard Worker 854*6dbdd20aSAndroid Build Coastguard Workerpackage(default_visibility = [PERFETTO_CONFIG.root + ":__subpackages__"]) 855*6dbdd20aSAndroid Build Coastguard Worker 856*6dbdd20aSAndroid Build Coastguard Workerlicenses(["notice"]) 857*6dbdd20aSAndroid Build Coastguard Worker 858*6dbdd20aSAndroid Build Coastguard Workerexports_files(["NOTICE"]) 859*6dbdd20aSAndroid Build Coastguard Worker 860*6dbdd20aSAndroid Build Coastguard Worker'''.format(tool_name).lstrip() 861*6dbdd20aSAndroid Build Coastguard Worker 862*6dbdd20aSAndroid Build Coastguard Worker # Public targets need to be computed at the beginning (to figure out the 863*6dbdd20aSAndroid Build Coastguard Worker # intermediate deps) but printed at the end (because declaration order matters 864*6dbdd20aSAndroid Build Coastguard Worker # in Bazel). 865*6dbdd20aSAndroid Build Coastguard Worker public_str = '' 866*6dbdd20aSAndroid Build Coastguard Worker 867*6dbdd20aSAndroid Build Coastguard Worker for target_name in sorted(public_targets): 868*6dbdd20aSAndroid Build Coastguard Worker target = gn.get_target(target_name) 869*6dbdd20aSAndroid Build Coastguard Worker public_str += gen_target_str(target, gn_win.get_target(target_name)) 870*6dbdd20aSAndroid Build Coastguard Worker 871*6dbdd20aSAndroid Build Coastguard Worker res += ''' 872*6dbdd20aSAndroid Build Coastguard Worker# ############################################################################## 873*6dbdd20aSAndroid Build Coastguard Worker# Internal targets 874*6dbdd20aSAndroid Build Coastguard Worker# ############################################################################## 875*6dbdd20aSAndroid Build Coastguard Worker 876*6dbdd20aSAndroid Build Coastguard Worker'''.lstrip() 877*6dbdd20aSAndroid Build Coastguard Worker # Generate the other non-public targets. 878*6dbdd20aSAndroid Build Coastguard Worker for target_name in sorted(set(default_targets) - set(public_targets)): 879*6dbdd20aSAndroid Build Coastguard Worker gn_win.get_target(target_name) 880*6dbdd20aSAndroid Build Coastguard Worker 881*6dbdd20aSAndroid Build Coastguard Worker for target_name in sorted(set(default_targets) - set(public_targets)): 882*6dbdd20aSAndroid Build Coastguard Worker target = gn.get_target(target_name) 883*6dbdd20aSAndroid Build Coastguard Worker res += gen_target_str(target, gn_win.get_target(target_name)) 884*6dbdd20aSAndroid Build Coastguard Worker 885*6dbdd20aSAndroid Build Coastguard Worker # Generate all the intermediate targets. 886*6dbdd20aSAndroid Build Coastguard Worker for target in sorted(itervalues(gn.all_targets)): 887*6dbdd20aSAndroid Build Coastguard Worker if target.name in default_targets or target.name in gn.proto_libs: 888*6dbdd20aSAndroid Build Coastguard Worker continue 889*6dbdd20aSAndroid Build Coastguard Worker res += gen_target_str(target, gn_win.get_target(target.name)) 890*6dbdd20aSAndroid Build Coastguard Worker 891*6dbdd20aSAndroid Build Coastguard Worker res += ''' 892*6dbdd20aSAndroid Build Coastguard Worker# ############################################################################## 893*6dbdd20aSAndroid Build Coastguard Worker# Proto libraries 894*6dbdd20aSAndroid Build Coastguard Worker# ############################################################################## 895*6dbdd20aSAndroid Build Coastguard Worker 896*6dbdd20aSAndroid Build Coastguard Worker'''.lstrip() 897*6dbdd20aSAndroid Build Coastguard Worker # Generate targets for proto groups. 898*6dbdd20aSAndroid Build Coastguard Worker for l_name, t_desc in proto_groups.items(): 899*6dbdd20aSAndroid Build Coastguard Worker res += ''.join(str(x) for x in gen_proto_group_target(gn, l_name, t_desc)) 900*6dbdd20aSAndroid Build Coastguard Worker 901*6dbdd20aSAndroid Build Coastguard Worker # For any non-source set and non-descriptor targets, ensure the source set 902*6dbdd20aSAndroid Build Coastguard Worker # associated to that target is discovered. 903*6dbdd20aSAndroid Build Coastguard Worker for target in sorted(itervalues(gn.all_targets)): 904*6dbdd20aSAndroid Build Coastguard Worker plugin = target.proto_plugin 905*6dbdd20aSAndroid Build Coastguard Worker if plugin is None or plugin == 'source_set' or plugin == 'descriptor': 906*6dbdd20aSAndroid Build Coastguard Worker continue 907*6dbdd20aSAndroid Build Coastguard Worker gn.get_target(re.sub('(lite|zero|cpp|ipc)$', 'source_set', target.name)) 908*6dbdd20aSAndroid Build Coastguard Worker 909*6dbdd20aSAndroid Build Coastguard Worker # Generate targets for the transitive set of proto targets. 910*6dbdd20aSAndroid Build Coastguard Worker labels = [ 911*6dbdd20aSAndroid Build Coastguard Worker l for target in sorted(itervalues(gn.proto_libs)) 912*6dbdd20aSAndroid Build Coastguard Worker for l in gen_target(target) 913*6dbdd20aSAndroid Build Coastguard Worker ] 914*6dbdd20aSAndroid Build Coastguard Worker res += ''.join(str(x) for x in sorted(labels)) 915*6dbdd20aSAndroid Build Coastguard Worker 916*6dbdd20aSAndroid Build Coastguard Worker res += ''' 917*6dbdd20aSAndroid Build Coastguard Worker# ############################################################################## 918*6dbdd20aSAndroid Build Coastguard Worker# Public targets 919*6dbdd20aSAndroid Build Coastguard Worker# ############################################################################## 920*6dbdd20aSAndroid Build Coastguard Worker 921*6dbdd20aSAndroid Build Coastguard Worker'''.lstrip() 922*6dbdd20aSAndroid Build Coastguard Worker res += public_str 923*6dbdd20aSAndroid Build Coastguard Worker res += '# Content from BUILD.extras\n\n' 924*6dbdd20aSAndroid Build Coastguard Worker res += extras 925*6dbdd20aSAndroid Build Coastguard Worker 926*6dbdd20aSAndroid Build Coastguard Worker # Check for ODR violations 927*6dbdd20aSAndroid Build Coastguard Worker for target_name in default_targets: 928*6dbdd20aSAndroid Build Coastguard Worker checker = gn_utils.ODRChecker(gn, target_name) 929*6dbdd20aSAndroid Build Coastguard Worker 930*6dbdd20aSAndroid Build Coastguard Worker return res 931*6dbdd20aSAndroid Build Coastguard Worker 932*6dbdd20aSAndroid Build Coastguard Worker 933*6dbdd20aSAndroid Build Coastguard Workerdef main(): 934*6dbdd20aSAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 935*6dbdd20aSAndroid Build Coastguard Worker description='Generate BUILD from a GN description.') 936*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 937*6dbdd20aSAndroid Build Coastguard Worker '--check-only', 938*6dbdd20aSAndroid Build Coastguard Worker help='Don\'t keep the generated files', 939*6dbdd20aSAndroid Build Coastguard Worker action='store_true') 940*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 941*6dbdd20aSAndroid Build Coastguard Worker '--desc', 942*6dbdd20aSAndroid Build Coastguard Worker help='GN description ' + 943*6dbdd20aSAndroid Build Coastguard Worker '(e.g., gn desc out --format=json --all-toolchains "//*"') 944*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 945*6dbdd20aSAndroid Build Coastguard Worker '--repo-root', 946*6dbdd20aSAndroid Build Coastguard Worker help='Standalone Perfetto repository to generate a GN description', 947*6dbdd20aSAndroid Build Coastguard Worker default=gn_utils.repo_root(), 948*6dbdd20aSAndroid Build Coastguard Worker ) 949*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 950*6dbdd20aSAndroid Build Coastguard Worker '--extras', 951*6dbdd20aSAndroid Build Coastguard Worker help='Extra targets to include at the end of the BUILD file', 952*6dbdd20aSAndroid Build Coastguard Worker default=os.path.join(gn_utils.repo_root(), 'BUILD.extras'), 953*6dbdd20aSAndroid Build Coastguard Worker ) 954*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 955*6dbdd20aSAndroid Build Coastguard Worker '--output', 956*6dbdd20aSAndroid Build Coastguard Worker help='BUILD file to create', 957*6dbdd20aSAndroid Build Coastguard Worker default=os.path.join(gn_utils.repo_root(), 'BUILD'), 958*6dbdd20aSAndroid Build Coastguard Worker ) 959*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 960*6dbdd20aSAndroid Build Coastguard Worker '--output-python', 961*6dbdd20aSAndroid Build Coastguard Worker help='Python BUILD file to create', 962*6dbdd20aSAndroid Build Coastguard Worker default=os.path.join(gn_utils.repo_root(), 'python', 'BUILD'), 963*6dbdd20aSAndroid Build Coastguard Worker ) 964*6dbdd20aSAndroid Build Coastguard Worker parser.add_argument( 965*6dbdd20aSAndroid Build Coastguard Worker 'targets', 966*6dbdd20aSAndroid Build Coastguard Worker nargs=argparse.REMAINDER, 967*6dbdd20aSAndroid Build Coastguard Worker help='Targets to include in the BUILD file (e.g., "//:perfetto_tests")') 968*6dbdd20aSAndroid Build Coastguard Worker args = parser.parse_args() 969*6dbdd20aSAndroid Build Coastguard Worker 970*6dbdd20aSAndroid Build Coastguard Worker if args.desc: 971*6dbdd20aSAndroid Build Coastguard Worker with open(args.desc) as f: 972*6dbdd20aSAndroid Build Coastguard Worker desc = json.load(f) 973*6dbdd20aSAndroid Build Coastguard Worker else: 974*6dbdd20aSAndroid Build Coastguard Worker desc = gn_utils.create_build_description(gn_args, args.repo_root) 975*6dbdd20aSAndroid Build Coastguard Worker 976*6dbdd20aSAndroid Build Coastguard Worker desc_win = gn_utils.create_build_description(gn_args_win, args.repo_root) 977*6dbdd20aSAndroid Build Coastguard Worker out_files = [] 978*6dbdd20aSAndroid Build Coastguard Worker 979*6dbdd20aSAndroid Build Coastguard Worker # Generate the main BUILD file. 980*6dbdd20aSAndroid Build Coastguard Worker with open(args.extras, 'r') as extra_f: 981*6dbdd20aSAndroid Build Coastguard Worker extras = extra_f.read() 982*6dbdd20aSAndroid Build Coastguard Worker 983*6dbdd20aSAndroid Build Coastguard Worker contents = generate_build(desc, desc_win, args.targets or default_targets, extras) 984*6dbdd20aSAndroid Build Coastguard Worker out_files.append(args.output + '.swp') 985*6dbdd20aSAndroid Build Coastguard Worker with open(out_files[-1], 'w', newline='\n') as out_f: 986*6dbdd20aSAndroid Build Coastguard Worker out_f.write(contents) 987*6dbdd20aSAndroid Build Coastguard Worker 988*6dbdd20aSAndroid Build Coastguard Worker # Generate the python BUILD file. 989*6dbdd20aSAndroid Build Coastguard Worker python_gen = PythonBuildGenerator() 990*6dbdd20aSAndroid Build Coastguard Worker python_contents = python_gen.generate(desc) 991*6dbdd20aSAndroid Build Coastguard Worker out_files.append(args.output_python + '.swp') 992*6dbdd20aSAndroid Build Coastguard Worker with open(out_files[-1], 'w', newline='\n') as out_f: 993*6dbdd20aSAndroid Build Coastguard Worker out_f.write(python_contents) 994*6dbdd20aSAndroid Build Coastguard Worker 995*6dbdd20aSAndroid Build Coastguard Worker # Generate the build flags file. 996*6dbdd20aSAndroid Build Coastguard Worker out_files.append(os.path.join(buildflags_dir, 'perfetto_build_flags.h.swp')) 997*6dbdd20aSAndroid Build Coastguard Worker gn_utils.gen_buildflags(gn_args, out_files[-1]) 998*6dbdd20aSAndroid Build Coastguard Worker 999*6dbdd20aSAndroid Build Coastguard Worker return gn_utils.check_or_commit_generated_files(out_files, args.check_only) 1000*6dbdd20aSAndroid Build Coastguard Worker 1001*6dbdd20aSAndroid Build Coastguard Worker 1002*6dbdd20aSAndroid Build Coastguard Workerif __name__ == '__main__': 1003*6dbdd20aSAndroid Build Coastguard Worker sys.exit(main()) 1004