blob: d71b0dcc4b94c288b913cd80bd75dd7b39c9c826 [file] [log] [blame]
Primiano Tucci34bc5592021-02-19 17:53:36 +01001#!/usr/bin/env python3
Sami Kyostila865d1d32017-12-12 18:37:04 +00002# Copyright (C) 2017 The Android Open Source Project
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16# This tool translates a collection of BUILD.gn files into a mostly equivalent
17# Android.bp file for the Android Soong build system. The input to the tool is a
18# JSON description of the GN build definition generated with the following
19# command:
20#
21# gn desc out --format=json --all-toolchains "//*" > desc.json
22#
23# The tool is then given a list of GN labels for which to generate Android.bp
24# build rules. The dependencies for the GN labels are squashed to the generated
25# Android.bp target, except for actions which get their own genrule. Some
26# libraries are also mapped to their Android equivalents -- see |builtin_deps|.
27
28import argparse
29import json
30import os
31import re
32import sys
Lalit Maganti27b00af2022-12-17 01:20:38 +000033from typing import Dict
Lalit Maganti921a3d62022-12-17 14:28:50 +000034from typing import List
35from typing import Optional
Sami Kyostila865d1d32017-12-12 18:37:04 +000036
Sami Kyostila3c88a1d2019-05-22 18:29:42 +010037import gn_utils
Lalit Maganti921a3d62022-12-17 14:28:50 +000038from gn_utils import GnParser
Sami Kyostila3c88a1d2019-05-22 18:29:42 +010039
Matthew Clarkson9a5dfa52019-10-03 09:54:04 +010040from compat import itervalues
41
Florian Mayer246c1422019-09-18 15:40:38 +010042ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
43
Sami Kyostilab27619f2017-12-13 19:22:16 +000044# Arguments for the GN output directory.
Primiano Tucci9c411652019-08-27 07:13:59 +020045gn_args = ' '.join([
46 'is_debug=false',
Primiano Tucci7e05fc12019-08-27 17:29:47 +020047 'is_perfetto_build_generator=true',
Primiano Tucci9c411652019-08-27 07:13:59 +020048 'perfetto_build_with_android=true',
49 'target_cpu="arm"',
50 'target_os="android"',
51])
Sami Kyostilab27619f2017-12-13 19:22:16 +000052
Primiano Tucci02c11762019-08-30 00:57:59 +020053# Default targets to translate to the blueprint file.
54default_targets = [
55 '//:libperfetto_client_experimental',
56 '//:libperfetto',
57 '//:perfetto_integrationtests',
58 '//:perfetto_unittests',
59 '//protos/perfetto/trace:perfetto_trace_protos',
60 '//src/android_internal:libperfetto_android_internal',
Lalit Maganti52f13362023-01-23 16:38:01 +000061 '//src/base:perfetto_base_default_platform',
Daniele Di Proiettoec4864e2022-12-14 17:32:38 +000062 '//src/shared_lib:libperfetto_c',
Primiano Tucci02c11762019-08-30 00:57:59 +020063 '//src/perfetto_cmd:perfetto',
64 '//src/perfetto_cmd:trigger_perfetto',
65 '//src/profiling/memory:heapprofd_client',
Florian Mayer23f79372020-06-16 14:37:06 +020066 '//src/profiling/memory:heapprofd_client_api',
Florian Mayer72e87362020-12-11 19:37:25 +000067 '//src/profiling/memory:heapprofd_api_noop',
Primiano Tucci02c11762019-08-30 00:57:59 +020068 '//src/profiling/memory:heapprofd',
Florian Mayer50f07a62020-07-15 17:15:58 +010069 '//src/profiling/memory:heapprofd_standalone_client',
Ryan Savitski462b5db2019-11-20 19:06:46 +000070 '//src/profiling/perf:traced_perf',
Primiano Tucci02c11762019-08-30 00:57:59 +020071 '//src/traced/probes:traced_probes',
72 '//src/traced/service:traced',
Lalit Magantie0986f32020-09-17 15:35:47 +010073 '//src/trace_processor:trace_processor_shell',
Steven Terrell3137bbe2024-03-22 18:55:56 +000074 '//src/trace_redaction:trace_redactor',
Primiano Tuccifbf4a732019-12-11 00:32:15 +000075 '//test/cts:perfetto_cts_deps',
Lalit Maganti9782f492020-01-10 18:13:13 +000076 '//test/cts:perfetto_cts_jni_deps',
Primiano Tuccicbbe4802020-02-20 13:19:11 +000077 '//test:perfetto_gtest_logcat_printer',
Daniele Di Proietto55674432023-06-02 10:46:53 +000078 '//test:perfetto_end_to_end_integrationtests',
Daniele Di Proietto2e6c1062022-09-14 13:52:19 +000079 '//test/vts:perfetto_vts_deps',
Primiano Tuccif0d7ef82019-10-04 15:35:24 +010080]
81
82# Host targets
83ipc_plugin = '//src/ipc/protoc_plugin:ipc_plugin(%s)' % gn_utils.HOST_TOOLCHAIN
84protozero_plugin = '//src/protozero/protoc_plugin:protozero_plugin(%s)' % (
85 gn_utils.HOST_TOOLCHAIN)
Primiano Tucci57dd66b2019-10-15 23:09:04 +010086cppgen_plugin = '//src/protozero/protoc_plugin:cppgen_plugin(%s)' % (
87 gn_utils.HOST_TOOLCHAIN)
88
Primiano Tuccif0d7ef82019-10-04 15:35:24 +010089default_targets += [
Hector Dearmana9545e52022-05-17 12:23:25 +010090 '//src/traceconv:traceconv(%s)' % gn_utils.HOST_TOOLCHAIN,
Primiano Tuccif0d7ef82019-10-04 15:35:24 +010091 protozero_plugin,
92 ipc_plugin,
Primiano Tucci02c11762019-08-30 00:57:59 +020093]
94
Primiano Tucci02c11762019-08-30 00:57:59 +020095# Defines a custom init_rc argument to be applied to the corresponding output
96# blueprint target.
97target_initrc = {
Primiano Tuccif0d7ef82019-10-04 15:35:24 +010098 '//src/traced/service:traced': {'perfetto.rc'},
99 '//src/profiling/memory:heapprofd': {'heapprofd.rc'},
Ryan Savitski29082bf2020-02-12 15:13:51 +0000100 '//src/profiling/perf:traced_perf': {'traced_perf.rc'},
Primiano Tucci02c11762019-08-30 00:57:59 +0200101}
102
103target_host_supported = [
Hector Dearman04cfac72019-09-24 22:05:55 +0100104 '//:libperfetto',
Michael Eastwood6cbbff12021-12-09 15:34:35 -0800105 '//:libperfetto_client_experimental',
Lalit Magantie0986f32020-09-17 15:35:47 +0100106 '//protos/perfetto/trace:perfetto_trace_protos',
Daniele Di Proiettoec4864e2022-12-14 17:32:38 +0000107 '//src/shared_lib:libperfetto_c',
Ryan Savitskie65c4052022-03-24 18:22:19 +0000108 '//src/trace_processor:demangle',
Lalit Magantie0986f32020-09-17 15:35:47 +0100109 '//src/trace_processor:trace_processor_shell',
A. Cody Schuffelen3c82a542023-05-22 20:11:25 -0700110 '//src/traced/probes:traced_probes',
A. Cody Schuffelenbf636942023-05-17 18:34:33 -0700111 '//src/traced/service:traced',
Primiano Tucci02c11762019-08-30 00:57:59 +0200112]
113
Michael Eastwood6cbbff12021-12-09 15:34:35 -0800114target_vendor_available = [
115 '//:libperfetto_client_experimental',
116]
117
Nikita Putikhin94e30a02023-11-22 14:16:47 +0100118target_product_available = [
119 '//:libperfetto_client_experimental',
120]
121
Lalit Magantid7afbb12022-03-28 15:12:24 +0100122# Proto target groups which will be made public.
123proto_groups = {
Kean Mariotti487a5392024-04-18 06:58:29 +0000124 'trace': {
125 'types': ['filegroup', 'lite'],
126 'targets': [
127 '//protos/perfetto/trace:non_minimal_source_set',
128 '//protos/perfetto/trace:minimal_source_set',
129 ]
130 },
131 'config': {
132 'types': ['lite'],
133 'targets': [
134 '//protos/perfetto/config:source_set',
135 ]
136 },
Lalit Magantid7afbb12022-03-28 15:12:24 +0100137}
138
Daniele Di Proiettocb426002023-02-16 12:14:38 +0000139needs_libfts = [
140 '//:perfetto_unittests',
141 '//src/trace_processor:trace_processor_shell',
142 '//src/traceconv:traceconv',
143]
144
Sami Kyostila865d1d32017-12-12 18:37:04 +0000145# All module names are prefixed with this string to avoid collisions.
146module_prefix = 'perfetto_'
147
148# Shared libraries which are directly translated to Android system equivalents.
Primiano Tuccia3645202020-08-03 16:28:18 +0200149shared_library_allowlist = [
Hector Dearman64f2e052019-12-04 20:51:14 +0000150 'android',
Hector Dearman92d7d112019-12-05 15:19:57 +0000151 'android.hardware.atrace@1.0',
152 'android.hardware.health@2.0',
Jack Wu40d043b2022-11-24 20:54:45 +0800153 'android.hardware.health-V2-ndk',
Hector Dearman92d7d112019-12-05 15:19:57 +0000154 'android.hardware.power.stats@1.0',
Hector Dearmanae979e02023-03-13 16:13:30 +0000155 'android.hardware.power.stats-V1-cpp',
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100156 'base',
Sami Kyostilab5b71692018-01-12 12:16:44 +0000157 'binder',
Raymond Chiu8c4d9a22021-02-23 19:59:10 +0000158 'binder_ndk',
Hector Dearman92d7d112019-12-05 15:19:57 +0000159 'cutils',
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100160 'hidlbase',
161 'hidltransport',
162 'hwbinder',
Ryan Savitski53ca60b2019-06-03 13:04:40 +0100163 'incident',
Sami Kyostila865d1d32017-12-12 18:37:04 +0000164 'log',
Sami Kyostilab5b71692018-01-12 12:16:44 +0000165 'services',
Hector Dearman92d7d112019-12-05 15:19:57 +0000166 'statssocket',
Hector Dearmanae979e02023-03-13 16:13:30 +0000167 'tracingproxy',
Primiano Tucciedf099c2018-01-08 18:27:56 +0000168 'utils',
Hector Dearmanff7abd42023-03-22 19:11:35 +0000169 'statspull',
Sami Kyostila865d1d32017-12-12 18:37:04 +0000170]
171
Hector Dearman92d7d112019-12-05 15:19:57 +0000172# Static libraries which are directly translated to Android system equivalents.
Primiano Tuccia3645202020-08-03 16:28:18 +0200173static_library_allowlist = [
Hector Dearman92d7d112019-12-05 15:19:57 +0000174 'statslog_perfetto',
175]
176
Sami Kyostila865d1d32017-12-12 18:37:04 +0000177# Name of the module which settings such as compiler flags for all other
178# modules.
179defaults_module = module_prefix + 'defaults'
180
181# Location of the project in the Android source tree.
182tree_path = 'external/perfetto'
183
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100184# Path for the protobuf sources in the standalone build.
185buildtools_protobuf_src = '//buildtools/protobuf/src'
186
187# Location of the protobuf src dir in the Android source tree.
188android_protobuf_src = 'external/protobuf/src'
189
Primiano Tucciedf099c2018-01-08 18:27:56 +0000190# Compiler flags which are passed through to the blueprint.
Primiano Tuccia3645202020-08-03 16:28:18 +0200191cflag_allowlist = r'^-DPERFETTO.*$'
Primiano Tucciedf099c2018-01-08 18:27:56 +0000192
Florian Mayer3d5e7e62018-01-19 15:22:46 +0000193# Compiler defines which are passed through to the blueprint.
Lalit Magantifa957e72023-03-16 18:22:23 +0000194define_allowlist = r'^(GOOGLE_PROTO.*)|(ZLIB_.*)|(USE_MMAP)$'
Florian Mayer3d5e7e62018-01-19 15:22:46 +0000195
Primiano Tucci8e627442019-08-28 07:58:38 +0200196# The directory where the generated perfetto_build_flags.h will be copied into.
197buildflags_dir = 'include/perfetto/base/build_configs/android_tree'
198
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100199def enumerate_data_deps():
200 with open(os.path.join(ROOT_DIR, 'tools', 'test_data.txt')) as f:
201 lines = f.readlines()
202 for line in (line.strip() for line in lines if not line.startswith('#')):
Andrew Shulaev576054d2020-01-23 13:44:51 +0000203 assert os.path.exists(line), 'file %s should exist' % line
Primiano Tucci02691162020-01-21 13:30:13 +0000204 if line.startswith('test/data/'):
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100205 # Skip test data files that require GCS. They are only for benchmarks.
206 # We don't run benchmarks in the android tree.
207 continue
Primiano Tucci17e8ae92021-05-17 17:40:50 +0100208 if line.endswith('/.'):
209 yield line[:-1] + '**/*'
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100210 else:
211 yield line
212
213
Florian Mayerb6a921f2018-10-18 18:55:23 +0100214# Additional arguments to apply to Android.bp rules.
215additional_args = {
Florian Mayer23f79372020-06-16 14:37:06 +0200216 'heapprofd_client_api': [
Florian Mayer23f79372020-06-16 14:37:06 +0200217 ('static_libs', {'libasync_safe'}),
Florian Mayer33159f72020-07-01 13:41:32 +0100218 # heapprofd_client_api MUST NOT have global constructors. Because it
219 # is loaded in an __attribute__((constructor)) of libc, we cannot
220 # guarantee that the global constructors get run before it is used.
221 ('cflags', {'-Wglobal-constructors', '-Werror=global-constructors'}),
Florian Mayer2131e362020-07-15 16:30:35 +0100222 ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
Florian Mayer7ed3a952021-01-08 10:55:25 +0000223 ('stubs', {
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100224 'versions': ['S'],
225 'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
Florian Mayer5d09f5e2021-02-19 14:59:49 +0000226 }),
227 ('export_include_dirs', {'src/profiling/memory/include'}),
228 ],
229 'heapprofd_api_noop': [
230 ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
231 ('stubs', {
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100232 'versions': ['S'],
233 'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
Florian Mayer5d09f5e2021-02-19 14:59:49 +0000234 }),
235 ('export_include_dirs', {'src/profiling/memory/include'}),
Florian Mayer23f79372020-06-16 14:37:06 +0200236 ],
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100237 'heapprofd_client': [
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100238 ('include_dirs', {'bionic/libc'}),
239 ('static_libs', {'libasync_safe'}),
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100240 ],
Florian Mayer50f07a62020-07-15 17:15:58 +0100241 'heapprofd_standalone_client': [
242 ('static_libs', {'libasync_safe'}),
243 ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
Florian Mayer5d09f5e2021-02-19 14:59:49 +0000244 ('export_include_dirs', {'src/profiling/memory/include'}),
Florian Mayer23b75a42020-07-30 15:21:25 +0100245 ('stl', 'libc++_static'),
Florian Mayer50f07a62020-07-15 17:15:58 +0100246 ],
Ryan Savitski703bcab2019-12-18 14:38:14 +0000247 'perfetto_unittests': [
248 ('data', set(enumerate_data_deps())),
249 ('include_dirs', {'bionic/libc/kernel'}),
250 ],
Florian Mayerac4f4962020-09-15 10:03:22 +0100251 'perfetto_integrationtests': [
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100252 ('test_suites', {'general-tests'}),
253 ('test_config', 'PerfettoIntegrationTests.xml'),
Florian Mayerac4f4962020-09-15 10:03:22 +0100254 ],
Lalit Magantid7afbb12022-03-28 15:12:24 +0100255 'libperfetto_android_internal': [('static_libs', {'libhealthhalutils'}),],
Lalit Maganticdda9112019-11-27 14:19:49 +0000256 'trace_processor_shell': [
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100257 ('strip', {
258 'all': True
259 }),
260 ('host', {
261 'stl': 'libc++_static',
262 'dist': {
263 'targets': ['sdk_repo']
264 },
265 }),
Lalit Maganticdda9112019-11-27 14:19:49 +0000266 ],
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900267 'libperfetto_client_experimental': [
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100268 ('apex_available', {
Nikita Putikhin94e30a02023-11-22 14:16:47 +0100269 '//apex_available:platform', '//apex_available:anyapex'
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100270 }),
Ryan Zuklie101f1b72022-10-25 16:22:07 -0700271 ('min_sdk_version', '30'),
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100272 ('shared_libs', {'liblog'}),
273 ('export_include_dirs', {'include', buildflags_dir}),
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900274 ],
Daniele Di Proiettoec4864e2022-12-14 17:32:38 +0000275 'libperfetto_c': [
276 ('min_sdk_version', '30'),
277 ('export_include_dirs', {'include'}),
278 ('cflags', {'-DPERFETTO_SHLIB_SDK_IMPLEMENTATION'}),
279 ],
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900280 'perfetto_trace_protos': [
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100281 ('apex_available', {
282 '//apex_available:platform', 'com.android.art',
283 'com.android.art.debug'
284 }),
285 ('min_sdk_version', 'S'),
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900286 ],
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100287 'libperfetto': [('export_include_dirs', {'include', buildflags_dir}),],
Daniele Di Proiettoe8068062024-02-16 17:54:03 +0000288 'perfetto': [('required', {'perfetto_persistent_cfg.pbtxt'}),],
Florian Mayerb6a921f2018-10-18 18:55:23 +0100289}
290
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100291
Lalit Maganti52f13362023-01-23 16:38:01 +0000292def enable_base_platform(module):
293 module.srcs.add(':perfetto_base_default_platform')
294
295
Primiano Tuccifbf4a732019-12-11 00:32:15 +0000296def enable_gtest_and_gmock(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100297 module.static_libs.add('libgmock')
Primiano Tuccifbf4a732019-12-11 00:32:15 +0000298 module.static_libs.add('libgtest')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000299 if module.name != 'perfetto_gtest_logcat_printer':
300 module.whole_static_libs.add('perfetto_gtest_logcat_printer')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100301
Sami Kyostila865d1d32017-12-12 18:37:04 +0000302
Sami Kyostila865d1d32017-12-12 18:37:04 +0000303def enable_protobuf_full(module):
Lalit Magantia97798d2020-09-16 17:40:57 +0100304 if module.type == 'cc_binary_host':
305 module.static_libs.add('libprotobuf-cpp-full')
Lalit Magantie0986f32020-09-17 15:35:47 +0100306 elif module.host_supported:
307 module.host.static_libs.add('libprotobuf-cpp-full')
308 module.android.shared_libs.add('libprotobuf-cpp-full')
Lalit Magantia97798d2020-09-16 17:40:57 +0100309 else:
310 module.shared_libs.add('libprotobuf-cpp-full')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100311
Sami Kyostila865d1d32017-12-12 18:37:04 +0000312
Sami Kyostila865d1d32017-12-12 18:37:04 +0000313def enable_protobuf_lite(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100314 module.shared_libs.add('libprotobuf-cpp-lite')
315
Sami Kyostila865d1d32017-12-12 18:37:04 +0000316
Sami Kyostila865d1d32017-12-12 18:37:04 +0000317def enable_protoc_lib(module):
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100318 if module.type == 'cc_binary_host':
319 module.static_libs.add('libprotoc')
320 else:
321 module.shared_libs.add('libprotoc')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100322
Sami Kyostila865d1d32017-12-12 18:37:04 +0000323
Florian Mayera2fae262018-08-31 12:10:01 -0700324def enable_libunwindstack(module):
Florian Mayer50f07a62020-07-15 17:15:58 +0100325 if module.name != 'heapprofd_standalone_client':
326 module.shared_libs.add('libunwindstack')
327 module.shared_libs.add('libprocinfo')
328 module.shared_libs.add('libbase')
329 else:
330 module.static_libs.add('libunwindstack')
331 module.static_libs.add('libprocinfo')
332 module.static_libs.add('libbase')
333 module.static_libs.add('liblzma')
334 module.static_libs.add('libdexfile_support')
Lalit Magantid7afbb12022-03-28 15:12:24 +0100335 module.runtime_libs.add('libdexfile') # libdexfile_support dependency
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100336
Sami Kyostila865d1d32017-12-12 18:37:04 +0000337
338def enable_libunwind(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100339 # libunwind is disabled on Darwin so we cannot depend on it.
340 pass
341
Sami Kyostila865d1d32017-12-12 18:37:04 +0000342
Lalit Maganti17aa2732019-02-08 15:47:26 +0000343def enable_sqlite(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100344 if module.type == 'cc_binary_host':
Michael Hoisie3e193512023-11-18 08:13:49 +0000345 module.static_libs.add('libsqlite_static_noicu')
Marcin Oczeretko1662f182022-08-18 10:29:46 +0100346 module.static_libs.add('sqlite_ext_percentile')
Lalit Magantie0986f32020-09-17 15:35:47 +0100347 elif module.host_supported:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100348 # Copy what the sqlite3 command line tool does.
349 module.android.shared_libs.add('libsqlite')
Victor Changd0d65902022-03-10 11:54:27 +0000350 module.android.shared_libs.add('libicu')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100351 module.android.shared_libs.add('liblog')
352 module.android.shared_libs.add('libutils')
Marcin Oczeretko1662f182022-08-18 10:29:46 +0100353 module.android.static_libs.add('sqlite_ext_percentile')
Michael Hoisie3e193512023-11-18 08:13:49 +0000354 module.host.static_libs.add('libsqlite_static_noicu')
Marcin Oczeretko1662f182022-08-18 10:29:46 +0100355 module.host.static_libs.add('sqlite_ext_percentile')
Lalit Magantie0986f32020-09-17 15:35:47 +0100356 else:
357 module.shared_libs.add('libsqlite')
Victor Changd0d65902022-03-10 11:54:27 +0000358 module.shared_libs.add('libicu')
Lalit Magantie0986f32020-09-17 15:35:47 +0100359 module.shared_libs.add('liblog')
360 module.shared_libs.add('libutils')
Marcin Oczeretko1662f182022-08-18 10:29:46 +0100361 module.static_libs.add('sqlite_ext_percentile')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100362
Lalit Maganti17aa2732019-02-08 15:47:26 +0000363
Hector Dearmane0b993f2019-05-24 18:48:16 +0100364def enable_zlib(module):
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100365 if module.type == 'cc_binary_host':
366 module.static_libs.add('libz')
Lalit Magantie0986f32020-09-17 15:35:47 +0100367 elif module.host_supported:
368 module.android.shared_libs.add('libz')
369 module.host.static_libs.add('libz')
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100370 else:
371 module.shared_libs.add('libz')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100372
Hector Dearmane0b993f2019-05-24 18:48:16 +0100373
Ryan Savitski56bc0c62020-01-27 13:50:02 +0000374def enable_uapi_headers(module):
375 module.include_dirs.add('bionic/libc/kernel')
376
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100377
Florian Mayer682f05a2020-08-11 10:16:54 +0100378def enable_bionic_libc_platform_headers_on_android(module):
379 module.header_libs.add('bionic_libc_platform_headers')
380
Ryan Savitski56bc0c62020-01-27 13:50:02 +0000381
Sami Kyostila865d1d32017-12-12 18:37:04 +0000382# Android equivalents for third-party libraries that the upstream project
383# depends on.
384builtin_deps = {
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100385 '//gn:default_deps':
386 lambda x: None,
387 '//gn:gtest_main':
388 lambda x: None,
389 '//gn:protoc':
390 lambda x: None,
Lalit Maganti52f13362023-01-23 16:38:01 +0000391 '//gn:base_platform':
392 enable_base_platform,
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100393 '//gn:gtest_and_gmock':
394 enable_gtest_and_gmock,
395 '//gn:libunwind':
396 enable_libunwind,
397 '//gn:protobuf_full':
398 enable_protobuf_full,
399 '//gn:protobuf_lite':
400 enable_protobuf_lite,
401 '//gn:protoc_lib':
402 enable_protoc_lib,
403 '//gn:libunwindstack':
404 enable_libunwindstack,
405 '//gn:sqlite':
406 enable_sqlite,
407 '//gn:zlib':
408 enable_zlib,
409 '//gn:bionic_kernel_uapi_headers':
410 enable_uapi_headers,
Florian Mayer682f05a2020-08-11 10:16:54 +0100411 '//src/profiling/memory:bionic_libc_platform_headers_on_android':
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100412 enable_bionic_libc_platform_headers_on_android,
Sami Kyostila865d1d32017-12-12 18:37:04 +0000413}
414
415# ----------------------------------------------------------------------------
416# End of configuration.
417# ----------------------------------------------------------------------------
418
419
420class Error(Exception):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100421 pass
Sami Kyostila865d1d32017-12-12 18:37:04 +0000422
423
424class ThrowingArgumentParser(argparse.ArgumentParser):
Sami Kyostila865d1d32017-12-12 18:37:04 +0000425
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100426 def __init__(self, context):
427 super(ThrowingArgumentParser, self).__init__()
428 self.context = context
429
430 def error(self, message):
431 raise Error('%s: %s' % (self.context, message))
Sami Kyostila865d1d32017-12-12 18:37:04 +0000432
433
Lalit Magantiedace412019-06-18 13:28:28 +0100434def write_blueprint_key_value(output, name, value, sort=True):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100435 """Writes a Blueprint key-value pair to the output"""
Lalit Magantiedace412019-06-18 13:28:28 +0100436
Lalit Magantid7afbb12022-03-28 15:12:24 +0100437 if isinstance(value, bool):
438 if value:
439 output.append(' %s: true,' % name)
440 else:
441 output.append(' %s: false,' % name)
442 return
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100443 if not value:
444 return
445 if isinstance(value, set):
446 value = sorted(value)
447 if isinstance(value, list):
Colin Cross84172332021-09-14 16:41:33 -0700448 output.append(' %s: [' % name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100449 for item in sorted(value) if sort else value:
Colin Cross84172332021-09-14 16:41:33 -0700450 output.append(' "%s",' % item)
451 output.append(' ],')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100452 return
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100453 if isinstance(value, Target):
454 value.to_string(output)
455 return
Lalit Maganticdda9112019-11-27 14:19:49 +0000456 if isinstance(value, dict):
457 kv_output = []
458 for k, v in value.items():
459 write_blueprint_key_value(kv_output, k, v)
460
Colin Cross84172332021-09-14 16:41:33 -0700461 output.append(' %s: {' % name)
Lalit Maganticdda9112019-11-27 14:19:49 +0000462 for line in kv_output:
Colin Cross84172332021-09-14 16:41:33 -0700463 output.append(' %s' % line)
464 output.append(' },')
Lalit Maganticdda9112019-11-27 14:19:49 +0000465 return
Colin Cross84172332021-09-14 16:41:33 -0700466 output.append(' %s: "%s",' % (name, value))
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100467
Lalit Magantiedace412019-06-18 13:28:28 +0100468
469class Target(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100470 """A target-scoped part of a module"""
Lalit Magantiedace412019-06-18 13:28:28 +0100471
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100472 def __init__(self, name):
473 self.name = name
474 self.shared_libs = set()
475 self.static_libs = set()
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000476 self.whole_static_libs = set()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100477 self.cflags = set()
Florian Mayer637513a2020-12-04 19:15:49 +0000478 self.dist = dict()
479 self.strip = dict()
Lalit Magantie0986f32020-09-17 15:35:47 +0100480 self.stl = None
Lalit Magantiedace412019-06-18 13:28:28 +0100481
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100482 def to_string(self, output):
483 nested_out = []
484 self._output_field(nested_out, 'shared_libs')
485 self._output_field(nested_out, 'static_libs')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000486 self._output_field(nested_out, 'whole_static_libs')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100487 self._output_field(nested_out, 'cflags')
Lalit Magantie0986f32020-09-17 15:35:47 +0100488 self._output_field(nested_out, 'stl')
Florian Mayer637513a2020-12-04 19:15:49 +0000489 self._output_field(nested_out, 'dist')
490 self._output_field(nested_out, 'strip')
Lalit Magantiedace412019-06-18 13:28:28 +0100491
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100492 if nested_out:
Colin Cross84172332021-09-14 16:41:33 -0700493 output.append(' %s: {' % self.name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100494 for line in nested_out:
Colin Cross84172332021-09-14 16:41:33 -0700495 output.append(' %s' % line)
496 output.append(' },')
Lalit Magantiedace412019-06-18 13:28:28 +0100497
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100498 def _output_field(self, output, name, sort=True):
499 value = getattr(self, name)
500 return write_blueprint_key_value(output, name, value, sort)
501
Lalit Magantiedace412019-06-18 13:28:28 +0100502
Sami Kyostila865d1d32017-12-12 18:37:04 +0000503class Module(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100504 """A single module (e.g., cc_binary, cc_test) in a blueprint."""
Sami Kyostila865d1d32017-12-12 18:37:04 +0000505
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100506 def __init__(self, mod_type, name, gn_target):
Lalit Maganti01f9b052022-12-17 01:21:13 +0000507 assert (gn_target)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100508 self.type = mod_type
509 self.gn_target = gn_target
510 self.name = name
511 self.srcs = set()
Lalit Maganti921a3d62022-12-17 14:28:50 +0000512 self.main: Optional[str] = None
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100513 self.comment = 'GN: ' + gn_utils.label_without_toolchain(gn_target)
514 self.shared_libs = set()
515 self.static_libs = set()
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000516 self.whole_static_libs = set()
Martin Stjernholmbe2411d2021-08-26 21:15:10 +0100517 self.runtime_libs = set()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100518 self.tools = set()
Lalit Maganti921a3d62022-12-17 14:28:50 +0000519 self.cmd: Optional[str] = None
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100520 self.host_supported = False
Michael Eastwood6cbbff12021-12-09 15:34:35 -0800521 self.vendor_available = False
Nikita Putikhin94e30a02023-11-22 14:16:47 +0100522 self.product_available = False
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100523 self.init_rc = set()
524 self.out = set()
525 self.export_include_dirs = set()
526 self.generated_headers = set()
527 self.export_generated_headers = set()
528 self.defaults = set()
529 self.cflags = set()
530 self.include_dirs = set()
531 self.header_libs = set()
532 self.required = set()
533 self.user_debug_flag = False
Lalit Maganti921a3d62022-12-17 14:28:50 +0000534 self.tool_files: Optional[List[str]] = None
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100535 self.android = Target('android')
536 self.host = Target('host')
Daniele Di Proiettocb426002023-02-16 12:14:38 +0000537 self.musl = Target('musl')
Lalit Maganti921a3d62022-12-17 14:28:50 +0000538 self.lto: Optional[bool] = None
Lalit Maganticdda9112019-11-27 14:19:49 +0000539 self.stl = None
540 self.dist = dict()
Lalit Magantiaccd64b2020-03-16 19:54:10 +0000541 self.strip = dict()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100542 self.data = set()
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900543 self.apex_available = set()
Primiano Tucci39097c52021-03-04 09:58:06 +0000544 self.min_sdk_version = None
Lalit Magantid7afbb12022-03-28 15:12:24 +0100545 self.proto = dict()
Pablo Gamito40e6e682023-12-04 12:04:33 +0000546 self.output_extension: Optional[str] = None
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100547 # The genrule_XXX below are properties that must to be propagated back
548 # on the module(s) that depend on the genrule.
549 self.genrule_headers = set()
550 self.genrule_srcs = set()
551 self.genrule_shared_libs = set()
Florian Mayer2131e362020-07-15 16:30:35 +0100552 self.version_script = None
Florian Mayerac4f4962020-09-15 10:03:22 +0100553 self.test_suites = set()
Florian Mayerab23f442021-02-09 15:37:45 +0000554 self.test_config = None
Florian Mayer7ed3a952021-01-08 10:55:25 +0000555 self.stubs = {}
Sami Kyostila865d1d32017-12-12 18:37:04 +0000556
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100557 def to_string(self, output):
558 if self.comment:
559 output.append('// %s' % self.comment)
560 output.append('%s {' % self.type)
561 self._output_field(output, 'name')
562 self._output_field(output, 'srcs')
563 self._output_field(output, 'shared_libs')
564 self._output_field(output, 'static_libs')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000565 self._output_field(output, 'whole_static_libs')
Martin Stjernholmbe2411d2021-08-26 21:15:10 +0100566 self._output_field(output, 'runtime_libs')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100567 self._output_field(output, 'tools')
568 self._output_field(output, 'cmd', sort=False)
Lalit Magantid7afbb12022-03-28 15:12:24 +0100569 if self.host_supported:
570 self._output_field(output, 'host_supported')
571 if self.vendor_available:
572 self._output_field(output, 'vendor_available')
Nikita Putikhin94e30a02023-11-22 14:16:47 +0100573 if self.product_available:
574 self._output_field(output, 'product_available')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100575 self._output_field(output, 'init_rc')
576 self._output_field(output, 'out')
577 self._output_field(output, 'export_include_dirs')
578 self._output_field(output, 'generated_headers')
579 self._output_field(output, 'export_generated_headers')
580 self._output_field(output, 'defaults')
581 self._output_field(output, 'cflags')
582 self._output_field(output, 'include_dirs')
583 self._output_field(output, 'header_libs')
584 self._output_field(output, 'required')
Lalit Maganticdda9112019-11-27 14:19:49 +0000585 self._output_field(output, 'dist')
Lalit Magantiaccd64b2020-03-16 19:54:10 +0000586 self._output_field(output, 'strip')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100587 self._output_field(output, 'tool_files')
588 self._output_field(output, 'data')
Lalit Maganticdda9112019-11-27 14:19:49 +0000589 self._output_field(output, 'stl')
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900590 self._output_field(output, 'apex_available')
Primiano Tucci39097c52021-03-04 09:58:06 +0000591 self._output_field(output, 'min_sdk_version')
Florian Mayer2131e362020-07-15 16:30:35 +0100592 self._output_field(output, 'version_script')
Florian Mayerac4f4962020-09-15 10:03:22 +0100593 self._output_field(output, 'test_suites')
Florian Mayerab23f442021-02-09 15:37:45 +0000594 self._output_field(output, 'test_config')
Florian Mayer7ed3a952021-01-08 10:55:25 +0000595 self._output_field(output, 'stubs')
Lalit Magantid7afbb12022-03-28 15:12:24 +0100596 self._output_field(output, 'proto')
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000597 self._output_field(output, 'main')
Pablo Gamito40e6e682023-12-04 12:04:33 +0000598 self._output_field(output, 'output_extension')
Lalit Magantid8b1a1d2018-05-23 14:41:43 +0100599
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100600 target_out = []
601 self._output_field(target_out, 'android')
602 self._output_field(target_out, 'host')
Daniele Di Proiettocb426002023-02-16 12:14:38 +0000603 self._output_field(target_out, 'musl')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100604 if target_out:
Colin Cross84172332021-09-14 16:41:33 -0700605 output.append(' target: {')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100606 for line in target_out:
Colin Cross84172332021-09-14 16:41:33 -0700607 output.append(' %s' % line)
608 output.append(' },')
Lalit Magantiedace412019-06-18 13:28:28 +0100609
Colin Cross162b48e2021-09-14 17:01:50 -0700610 if self.user_debug_flag:
Colin Cross84172332021-09-14 16:41:33 -0700611 output.append(' product_variables: {')
Colin Cross162b48e2021-09-14 17:01:50 -0700612 output.append(' debuggable: {')
613 output.append(
614 ' cflags: ["-DPERFETTO_BUILD_WITH_ANDROID_USERDEBUG"],')
615 output.append(' },')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100616 output.append(' },')
Colin Cross84172332021-09-14 16:41:33 -0700617 if self.lto is not None:
618 output.append(' target: {')
619 output.append(' android: {')
620 output.append(' lto: {')
Lalit Magantid7afbb12022-03-28 15:12:24 +0100621 output.append(' thin: %s,' %
622 'true' if self.lto else 'false')
Colin Cross84172332021-09-14 16:41:33 -0700623 output.append(' },')
624 output.append(' },')
625 output.append(' },')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100626 output.append('}')
627 output.append('')
Sami Kyostila865d1d32017-12-12 18:37:04 +0000628
Lalit Magantie0986f32020-09-17 15:35:47 +0100629 def add_android_static_lib(self, lib):
630 if self.type == 'cc_binary_host':
631 raise Exception('Adding Android static lib for host tool is unsupported')
632 elif self.host_supported:
633 self.android.static_libs.add(lib)
634 else:
635 self.static_libs.add(lib)
636
Lalit Magantie0986f32020-09-17 15:35:47 +0100637 def add_android_shared_lib(self, lib):
638 if self.type == 'cc_binary_host':
639 raise Exception('Adding Android shared lib for host tool is unsupported')
640 elif self.host_supported:
641 self.android.shared_libs.add(lib)
642 else:
643 self.shared_libs.add(lib)
644
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100645 def _output_field(self, output, name, sort=True):
646 value = getattr(self, name)
647 return write_blueprint_key_value(output, name, value, sort)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000648
649
650class Blueprint(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100651 """In-memory representation of an Android.bp file."""
Sami Kyostila865d1d32017-12-12 18:37:04 +0000652
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100653 def __init__(self):
Lalit Maganti27b00af2022-12-17 01:20:38 +0000654 self.modules: Dict[str, Module] = {}
655 self.gn_target_to_module: Dict[str, Module] = {}
Sami Kyostila865d1d32017-12-12 18:37:04 +0000656
Lalit Maganti27b00af2022-12-17 01:20:38 +0000657 def add_module(self, module: Module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100658 """Adds a new module to the blueprint, replacing any existing module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000659 with the same name.
660
661 Args:
662 module: Module instance.
663 """
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100664 self.modules[module.name] = module
Lalit Maganti27b00af2022-12-17 01:20:38 +0000665 self.gn_target_to_module[module.gn_target] = module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000666
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100667 def to_string(self, output):
668 for m in sorted(itervalues(self.modules), key=lambda m: m.name):
669 m.to_string(output)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000670
671
Lalit Maganti921a3d62022-12-17 14:28:50 +0000672def label_to_module_name(label: str):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100673 """Turn a GN label (e.g., //:perfetto_tests) into a module name."""
674 # If the label is explicibly listed in the default target list, don't prefix
675 # its name and return just the target name. This is so tools like
Hector Dearmana9545e52022-05-17 12:23:25 +0100676 # "traceconv" stay as such in the Android tree.
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100677 label_without_toolchain = gn_utils.label_without_toolchain(label)
678 if label in default_targets or label_without_toolchain in default_targets:
679 return label_without_toolchain.split(':')[-1]
Primiano Tucci02c11762019-08-30 00:57:59 +0200680
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100681 module = re.sub(r'^//:?', '', label_without_toolchain)
682 module = re.sub(r'[^a-zA-Z0-9_]', '_', module)
683 if not module.startswith(module_prefix):
684 return module_prefix + module
685 return module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000686
687
Lalit Maganti921a3d62022-12-17 14:28:50 +0000688def is_supported_source_file(name: str):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100689 """Returns True if |name| can appear in a 'srcs' list."""
690 return os.path.splitext(name)[1] in ['.c', '.cc', '.proto']
Sami Kyostila865d1d32017-12-12 18:37:04 +0000691
692
Lalit Maganti921a3d62022-12-17 14:28:50 +0000693def create_proto_modules(blueprint: Blueprint, gn: GnParser,
694 target: GnParser.Target):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100695 """Generate genrules for a proto GN target.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000696
697 GN actions are used to dynamically generate files during the build. The
698 Soong equivalent is a genrule. This function turns a specific kind of
699 genrule which turns .proto files into source and header files into a pair
Sami Kyostila71625d72017-12-18 10:29:49 +0000700 equivalent genrules.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000701
702 Args:
703 blueprint: Blueprint instance which is being generated.
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100704 target: gn_utils.Target object.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000705
706 Returns:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100707 The source_genrule module.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000708 """
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100709 assert (target.type == 'proto_library')
Lalit Maganti117272f2020-09-11 14:01:18 +0100710
Lalit Maganti921a3d62022-12-17 14:28:50 +0000711 # We don't generate any targets for source_set proto modules because
712 # they will be inlined into other modules if required.
713 if target.proto_plugin == 'source_set':
714 return None
715
Lalit Maganti117272f2020-09-11 14:01:18 +0100716 tools = {'aprotoc'}
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100717 cpp_out_dir = '$(genDir)/%s/' % tree_path
Lalit Maganti117272f2020-09-11 14:01:18 +0100718 target_module_name = label_to_module_name(target.name)
719
720 # In GN builds the proto path is always relative to the output directory
721 # (out/tmp.xxx).
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000722 cmd = ['mkdir -p %s &&' % cpp_out_dir, '$(location aprotoc)']
Lalit Maganti117272f2020-09-11 14:01:18 +0100723 cmd += ['--proto_path=%s' % tree_path]
724
Spandan Das34f1b982023-10-13 23:24:01 +0000725 tool_files = set()
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100726 if buildtools_protobuf_src in target.proto_paths:
727 cmd += ['--proto_path=%s' % android_protobuf_src]
Spandan Das34f1b982023-10-13 23:24:01 +0000728 # Add `google/protobuf/descriptor.proto` to implicit deps
729 tool_files.add(':libprotobuf-internal-descriptor-proto')
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100730
Lalit Maganti117272f2020-09-11 14:01:18 +0100731 # Descriptor targets only generate a single target.
732 if target.proto_plugin == 'descriptor':
733 out = '{}.bin'.format(target_module_name)
734
Lalit Magantife422eb2020-11-12 14:00:09 +0000735 cmd += ['--descriptor_set_out=$(out)']
Lalit Maganti117272f2020-09-11 14:01:18 +0100736 cmd += ['$(in)']
737
738 descriptor_module = Module('genrule', target_module_name, target.name)
739 descriptor_module.cmd = ' '.join(cmd)
Lalit Maganti921a3d62022-12-17 14:28:50 +0000740 descriptor_module.out.add(out)
Lalit Maganti117272f2020-09-11 14:01:18 +0100741 descriptor_module.tools = tools
742 blueprint.add_module(descriptor_module)
743
Lalit Magantife422eb2020-11-12 14:00:09 +0000744 # Recursively extract the .proto files of all the dependencies and
745 # add them to srcs.
Lalit Magantid7afbb12022-03-28 15:12:24 +0100746 descriptor_module.srcs.update(
747 gn_utils.label_to_path(src) for src in target.sources)
Spandan Das34f1b982023-10-13 23:24:01 +0000748 # Add the tool_files to srcs so that they get copied if this action is
749 # sandboxed in Soong.
750 # Add to `srcs` instead of `tool_files` (the latter will require a
751 # --proto_path that depends on Soong's sandbox implementation.)
752 descriptor_module.srcs.update(
753 src for src in tool_files)
Lalit Maganti01f9b052022-12-17 01:21:13 +0000754 for dep in target.transitive_proto_deps():
755 current_target = gn.get_target(dep.name)
Lalit Magantife422eb2020-11-12 14:00:09 +0000756 descriptor_module.srcs.update(
757 gn_utils.label_to_path(src) for src in current_target.sources)
Lalit Magantife422eb2020-11-12 14:00:09 +0000758
Lalit Maganti117272f2020-09-11 14:01:18 +0100759 return descriptor_module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000760
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100761 # We create two genrules for each proto target: one for the headers and
762 # another for the sources. This is because the module that depends on the
763 # generated files needs to declare two different types of dependencies --
764 # source files in 'srcs' and headers in 'generated_headers' -- and it's not
765 # valid to generate .h files from a source dependency and vice versa.
Spandan Das34f1b982023-10-13 23:24:01 +0000766 #
767 # We create an additional filegroup for .proto
768 # The .proto filegroup will be added to `tool_files` of rdeps so that the
769 # genrules can be sandboxed.
770
771 tool_files = set()
772 for proto_dep in target.proto_deps().union(target.transitive_proto_deps()):
773 tool_files.add(":" + label_to_module_name(proto_dep.name))
774
775 filegroup_module = Module('filegroup', target_module_name, target.name)
776 filegroup_module.srcs.update(
777 gn_utils.label_to_path(src) for src in target.sources)
778 blueprint.add_module(filegroup_module)
779
Lalit Maganti117272f2020-09-11 14:01:18 +0100780 source_module_name = target_module_name + '_gen'
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100781 source_module = Module('genrule', source_module_name, target.name)
Spandan Das34f1b982023-10-13 23:24:01 +0000782 # Add the "root" .proto filegroup to srcs
783 source_module.srcs = set([':' + target_module_name])
784 # Add the tool_files to srcs so that they get copied if this action is
785 # sandboxed in Soong.
786 # Add to `srcs` instead of `tool_files` (the latter will require a
787 # --proto_path that depends on Soong's sandbox implementation.)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100788 source_module.srcs.update(
Spandan Das34f1b982023-10-13 23:24:01 +0000789 src for src in tool_files)
790 blueprint.add_module(source_module)
Primiano Tucci20b760c2018-01-19 12:36:12 +0000791
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100792 header_module = Module('genrule', source_module_name + '_headers',
793 target.name)
794 blueprint.add_module(header_module)
795 header_module.srcs = set(source_module.srcs)
Primiano Tucci20b760c2018-01-19 12:36:12 +0000796
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100797 # TODO(primiano): at some point we should remove this. This was introduced
798 # by aosp/1108421 when adding "protos/" to .proto include paths, in order to
799 # avoid doing multi-repo changes and allow old clients in the android tree
800 # to still do the old #include "perfetto/..." rather than
801 # #include "protos/perfetto/...".
802 header_module.export_include_dirs = {'.', 'protos'}
Sami Kyostila865d1d32017-12-12 18:37:04 +0000803
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100804 source_module.genrule_srcs.add(':' + source_module.name)
805 source_module.genrule_headers.add(header_module.name)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000806
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100807 if target.proto_plugin == 'proto':
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000808 suffixes = ['pb']
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100809 source_module.genrule_shared_libs.add('libprotobuf-cpp-lite')
Primiano Tucci7b6a7882020-01-20 22:34:31 +0000810 cmd += ['--cpp_out=lite=true:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100811 elif target.proto_plugin == 'protozero':
812 suffixes = ['pbzero']
813 plugin = create_modules_from_target(blueprint, gn, protozero_plugin)
Lalit Maganti921a3d62022-12-17 14:28:50 +0000814 assert (plugin)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100815 tools.add(plugin.name)
816 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
817 cmd += ['--plugin_out=wrapper_namespace=pbzero:' + cpp_out_dir]
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100818 elif target.proto_plugin == 'cppgen':
819 suffixes = ['gen']
820 plugin = create_modules_from_target(blueprint, gn, cppgen_plugin)
Lalit Maganti921a3d62022-12-17 14:28:50 +0000821 assert (plugin)
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100822 tools.add(plugin.name)
823 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
Primiano Tuccie8020f92019-11-26 13:24:01 +0000824 cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100825 elif target.proto_plugin == 'ipc':
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000826 suffixes = ['ipc']
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100827 plugin = create_modules_from_target(blueprint, gn, ipc_plugin)
Lalit Maganti921a3d62022-12-17 14:28:50 +0000828 assert (plugin)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100829 tools.add(plugin.name)
830 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
Primiano Tuccie8020f92019-11-26 13:24:01 +0000831 cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100832 else:
833 raise Error('Unsupported proto plugin: %s' % target.proto_plugin)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000834
Spandan Das34f1b982023-10-13 23:24:01 +0000835 cmd += ['$(locations :%s)' % target_module_name]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100836 source_module.cmd = ' '.join(cmd)
837 header_module.cmd = source_module.cmd
838 source_module.tools = tools
839 header_module.tools = tools
Primiano Tucci20b760c2018-01-19 12:36:12 +0000840
Spandan Das34f1b982023-10-13 23:24:01 +0000841
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100842 for sfx in suffixes:
Matthew Clarkson63028d62019-10-10 15:48:23 +0100843 source_module.out.update('%s/%s' %
844 (tree_path, src.replace('.proto', '.%s.cc' % sfx))
Spandan Das34f1b982023-10-13 23:24:01 +0000845 for src in filegroup_module.srcs)
Matthew Clarkson63028d62019-10-10 15:48:23 +0100846 header_module.out.update('%s/%s' %
847 (tree_path, src.replace('.proto', '.%s.h' % sfx))
Spandan Das34f1b982023-10-13 23:24:01 +0000848 for src in filegroup_module.srcs)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100849 return source_module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000850
Sami Kyostila3c88a1d2019-05-22 18:29:42 +0100851
Lalit Maganti921a3d62022-12-17 14:28:50 +0000852def create_tp_tables_module(blueprint: Blueprint, gn: GnParser,
853 target: GnParser.Target):
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000854 bp_module_name = label_to_module_name(target.name)
855 bp_binary_module_name = f'{bp_module_name}_binary'
856 srcs = [gn_utils.label_to_path(src) for src in target.sources]
857
Lalit Maganti921a3d62022-12-17 14:28:50 +0000858 binary_module = Module('python_binary_host', bp_binary_module_name,
859 target.name)
Lalit Maganti01f9b052022-12-17 01:21:13 +0000860 for dep in target.non_proto_or_source_set_deps():
861 binary_module.srcs.update([
862 gn_utils.label_to_path(src) for src in gn.get_target(dep.name).sources
863 ])
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000864 binary_module.srcs.update(srcs)
865 binary_module.srcs.add('tools/gen_tp_table_headers.py')
866 binary_module.main = 'tools/gen_tp_table_headers.py'
867 blueprint.add_module(binary_module)
868
869 module = Module('genrule', bp_module_name, target.name)
870 module.tools = set([
871 bp_binary_module_name,
872 ])
873 module.cmd = ' '.join([
874 f'$(location {bp_binary_module_name})',
875 '--gen-dir=$(genDir)',
Lalit Maganti3df8a7e2023-04-25 14:18:17 +0100876 '--relative-input-dir=external/perfetto',
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000877 '--inputs',
878 '$(in)',
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000879 ])
880 module.out.update(target.outputs)
881 module.genrule_headers.add(module.name)
882 module.srcs.update(srcs)
883 blueprint.add_module(module)
884
885 return module
886
887
Lalit Maganti01f9b052022-12-17 01:21:13 +0000888def create_amalgamated_sql_module(blueprint: Blueprint, gn: GnParser,
889 target: GnParser.Target):
Anna Mayznercc18bfd2022-11-03 14:05:19 +0000890 bp_module_name = label_to_module_name(target.name)
Lalit Maganti358a7e42022-11-09 15:16:21 +0000891
892 def find_arg(name):
893 for i, arg in enumerate(target.args):
894 if arg.startswith(f'--{name}'):
895 return target.args[i + 1]
896
897 namespace = find_arg('namespace')
Lalit Maganti358a7e42022-11-09 15:16:21 +0000898
Anna Mayznercc18bfd2022-11-03 14:05:19 +0000899 module = Module('genrule', bp_module_name, target.name)
900 module.tool_files = [
901 'tools/gen_amalgamated_sql.py',
902 ]
903 module.cmd = ' '.join([
904 '$(location tools/gen_amalgamated_sql.py)',
Lalit Maganti358a7e42022-11-09 15:16:21 +0000905 f'--namespace={namespace}',
Lalit Maganti358a7e42022-11-09 15:16:21 +0000906 '--cpp-out=$(out)',
Anna Mayznercc18bfd2022-11-03 14:05:19 +0000907 '$(in)',
908 ])
909 module.genrule_headers.add(module.name)
910 module.out.update(target.outputs)
Lalit Maganti358a7e42022-11-09 15:16:21 +0000911
Lalit Maganti33619852022-12-17 01:22:36 +0000912 for dep in target.transitive_deps:
Rasika Navarangec3634b42023-11-14 19:45:04 +0000913 # Use globs for the chrome stdlib so the file does not need to be
914 # regenerated in autoroll CLs.
915 if dep.name.startswith(
916 '//src/trace_processor/perfetto_sql/stdlib/chrome:chrome_sql'):
917 module.srcs.add('src/trace_processor/perfetto_sql/stdlib/chrome/**/*.sql')
918 continue
Lalit Maganti358a7e42022-11-09 15:16:21 +0000919 module.srcs.update(
Lalit Maganti01f9b052022-12-17 01:21:13 +0000920 [gn_utils.label_to_path(src) for src in gn.get_target(dep.name).inputs])
Anna Mayznercc18bfd2022-11-03 14:05:19 +0000921 blueprint.add_module(module)
922 return module
Sami Kyostila3c88a1d2019-05-22 18:29:42 +0100923
Lalit Maganti358a7e42022-11-09 15:16:21 +0000924
Lalit Maganti921a3d62022-12-17 14:28:50 +0000925def create_cc_proto_descriptor_module(blueprint: Blueprint,
926 target: GnParser.Target):
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100927 bp_module_name = label_to_module_name(target.name)
928 module = Module('genrule', bp_module_name, target.name)
Lalit Maganti117272f2020-09-11 14:01:18 +0100929 module.tool_files = [
930 'tools/gen_cc_proto_descriptor.py',
931 ]
932 module.cmd = ' '.join([
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100933 '$(location tools/gen_cc_proto_descriptor.py)', '--gen_dir=$(genDir)',
934 '--cpp_out=$(out)', '$(in)'
Lalit Maganti117272f2020-09-11 14:01:18 +0100935 ])
936 module.genrule_headers.add(module.name)
937 module.srcs.update(
Lalit Maganti01f9b052022-12-17 01:21:13 +0000938 ':' + label_to_module_name(dep.name) for dep in target.proto_deps())
Hector Dearman24838932022-07-06 21:57:58 +0100939 module.srcs.update(
940 gn_utils.label_to_path(src)
941 for src in target.inputs
942 if "tmp.gn_utils" not in src)
Lalit Maganti117272f2020-09-11 14:01:18 +0100943 module.out.update(target.outputs)
944 blueprint.add_module(module)
945 return module
946
947
Lalit Maganti01f9b052022-12-17 01:21:13 +0000948def create_gen_version_module(blueprint: Blueprint, target: GnParser.Target,
949 bp_module_name: str):
Primiano Tucciec590132020-11-16 14:16:44 +0100950 module = Module('genrule', bp_module_name, gn_utils.GEN_VERSION_TARGET)
951 script_path = gn_utils.label_to_path(target.script)
952 module.genrule_headers.add(bp_module_name)
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100953 module.tool_files = [script_path]
Primiano Tucciec590132020-11-16 14:16:44 +0100954 module.out.update(target.outputs)
955 module.srcs.update(gn_utils.label_to_path(src) for src in target.inputs)
956 module.cmd = ' '.join([
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100957 'python3 $(location %s)' % script_path, '--no_git',
958 '--changelog=$(location CHANGELOG)', '--cpp_out=$(out)'
Primiano Tucciec590132020-11-16 14:16:44 +0100959 ])
960 blueprint.add_module(module)
961 return module
962
963
Lalit Maganti01f9b052022-12-17 01:21:13 +0000964def create_proto_group_modules(blueprint, gn: GnParser, module_name: str,
Kean Mariotti487a5392024-04-18 06:58:29 +0000965 group):
966 target_names = group['targets']
967 module_types = group['types']
968 module_sources = set()
Lalit Magantid7afbb12022-03-28 15:12:24 +0100969
970 for name in target_names:
971 target = gn.get_target(name)
Kean Mariotti487a5392024-04-18 06:58:29 +0000972 module_sources.update(gn_utils.label_to_path(src) for src in target.sources)
Lalit Maganti01f9b052022-12-17 01:21:13 +0000973 for dep_label in target.transitive_proto_deps():
974 dep = gn.get_target(dep_label.name)
Kean Mariotti487a5392024-04-18 06:58:29 +0000975 module_sources.update(gn_utils.label_to_path(src) for src in dep.sources)
Lalit Magantid7afbb12022-03-28 15:12:24 +0100976
Kean Mariotti487a5392024-04-18 06:58:29 +0000977 for type in module_types:
978 if type == 'filegroup':
979 name = label_to_module_name(module_name) + '_filegroup_proto'
980 module = Module('filegroup', name, name)
981 module.comment = f'''GN: [{', '.join(target_names)}]'''
982 module.srcs = module_sources
983 blueprint.add_module(module)
984 elif type == 'lite':
985 name = label_to_module_name(module_name) + '_java_protos'
986 module = Module('java_library', name, name)
987 module.comment = f'''GN: [{', '.join(target_names)}]'''
988 module.proto = {'type': 'lite', 'canonical_path_from_root': False}
989 module.srcs = module_sources
990 blueprint.add_module(module)
991 else:
992 raise Error('Unhandled proto group type: {}'.format(group.type))
Lalit Magantid7afbb12022-03-28 15:12:24 +0100993
994
Lalit Maganti921a3d62022-12-17 14:28:50 +0000995def _get_cflags(target: GnParser.Target):
Primiano Tuccia3645202020-08-03 16:28:18 +0200996 cflags = {flag for flag in target.cflags if re.match(cflag_allowlist, flag)}
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100997 cflags |= set("-D%s" % define
998 for define in target.defines
Primiano Tuccia3645202020-08-03 16:28:18 +0200999 if re.match(define_allowlist, define))
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001000 return cflags
Florian Mayer3d5e7e62018-01-19 15:22:46 +00001001
1002
Lalit Maganti921a3d62022-12-17 14:28:50 +00001003def create_modules_from_target(blueprint: Blueprint, gn: GnParser,
1004 gn_target_name: str) -> Optional[Module]:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001005 """Generate module(s) for a given GN target.
Sami Kyostila865d1d32017-12-12 18:37:04 +00001006
1007 Given a GN target name, generate one or more corresponding modules into a
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001008 blueprint. The only case when this generates >1 module is proto libraries.
Sami Kyostila865d1d32017-12-12 18:37:04 +00001009
1010 Args:
1011 blueprint: Blueprint instance which is being generated.
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001012 gn: gn_utils.GnParser object.
1013 gn_target_name: GN target for module generation.
Sami Kyostila865d1d32017-12-12 18:37:04 +00001014 """
Lalit Maganti27b00af2022-12-17 01:20:38 +00001015 if gn_target_name in blueprint.gn_target_to_module:
1016 return blueprint.gn_target_to_module[gn_target_name]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001017
Lalit Maganti27b00af2022-12-17 01:20:38 +00001018 target = gn.get_target(gn_target_name)
1019 bp_module_name = label_to_module_name(gn_target_name)
Lalit Maganti9c2318c2021-05-20 16:21:41 +01001020 name_without_toolchain = gn_utils.label_without_toolchain(target.name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001021 if target.type == 'executable':
1022 if target.toolchain == gn_utils.HOST_TOOLCHAIN:
1023 module_type = 'cc_binary_host'
1024 elif target.testonly:
1025 module_type = 'cc_test'
Sami Kyostila865d1d32017-12-12 18:37:04 +00001026 else:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001027 module_type = 'cc_binary'
1028 module = Module(module_type, bp_module_name, gn_target_name)
1029 elif target.type == 'static_library':
1030 module = Module('cc_library_static', bp_module_name, gn_target_name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001031 elif target.type == 'shared_library':
1032 module = Module('cc_library_shared', bp_module_name, gn_target_name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001033 elif target.type == 'source_set':
1034 module = Module('filegroup', bp_module_name, gn_target_name)
1035 elif target.type == 'group':
1036 # "group" targets are resolved recursively by gn_utils.get_target().
1037 # There's nothing we need to do at this level for them.
1038 return None
1039 elif target.type == 'proto_library':
1040 module = create_proto_modules(blueprint, gn, target)
Lalit Maganti117272f2020-09-11 14:01:18 +01001041 if module is None:
1042 return None
1043 elif target.type == 'action':
Lalit Maganti358a7e42022-11-09 15:16:21 +00001044 if target.custom_action_type == 'sql_amalgamation':
1045 return create_amalgamated_sql_module(blueprint, gn, target)
Lalit Maganti3dc8e302022-12-01 20:32:46 +00001046 if target.custom_action_type == 'tp_tables':
1047 return create_tp_tables_module(blueprint, gn, target)
Lalit Maganti358a7e42022-11-09 15:16:21 +00001048
Lalit Magantib417ff22022-11-09 15:45:02 +00001049 if target.custom_action_type == 'cc_proto_descriptor':
Lalit Maganti3b09a3f2020-09-14 13:28:44 +01001050 module = create_cc_proto_descriptor_module(blueprint, target)
Lalit Maganti358a7e42022-11-09 15:16:21 +00001051 elif name_without_toolchain == gn_utils.GEN_VERSION_TARGET:
Primiano Tucciec590132020-11-16 14:16:44 +01001052 module = create_gen_version_module(blueprint, target, bp_module_name)
Hector Dearmana1d75242020-10-02 09:47:24 +01001053 else:
1054 raise Error('Unhandled action: {}'.format(target.name))
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001055 else:
1056 raise Error('Unknown target %s (%s)' % (target.name, target.type))
Sami Kyostila865d1d32017-12-12 18:37:04 +00001057
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001058 blueprint.add_module(module)
Lalit Maganti9c2318c2021-05-20 16:21:41 +01001059 module.host_supported = (name_without_toolchain in target_host_supported)
Michael Eastwood6cbbff12021-12-09 15:34:35 -08001060 module.vendor_available = (name_without_toolchain in target_vendor_available)
Nikita Putikhin94e30a02023-11-22 14:16:47 +01001061 module.product_available = (name_without_toolchain in target_product_available)
Lalit Maganti921a3d62022-12-17 14:28:50 +00001062 module.init_rc.update(target_initrc.get(target.name, []))
Spandan Das34f1b982023-10-13 23:24:01 +00001063 if target.type != 'proto_library':
1064 # proto_library embeds a "root" filegroup in its srcs.
1065 # Skip to prevent adding dups
1066 module.srcs.update(
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001067 gn_utils.label_to_path(src)
1068 for src in target.sources
1069 if is_supported_source_file(src))
Primiano Tucci6067e732018-01-08 16:19:40 +00001070
Daniele Di Proiettocb426002023-02-16 12:14:38 +00001071 if name_without_toolchain in needs_libfts:
1072 module.musl.static_libs.add('libfts')
1073
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001074 if target.type in gn_utils.LINKER_UNIT_TYPES:
1075 module.cflags.update(_get_cflags(target))
Sami Kyostila865d1d32017-12-12 18:37:04 +00001076
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001077 module_is_compiled = module.type not in ('genrule', 'filegroup')
1078 if module_is_compiled:
1079 # Don't try to inject library/source dependencies into genrules or
1080 # filegroups because they are not compiled in the traditional sense.
Lalit Maganti921a3d62022-12-17 14:28:50 +00001081 module.defaults.update([defaults_module])
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001082 for lib in target.libs:
1083 # Generally library names should be mangled as 'libXXX', unless they
Yifan Hong0011c632021-12-02 18:37:21 -08001084 # are HAL libraries (e.g., android.hardware.health@2.0) or AIDL c++ / NDK
Raymond Chiu8c4d9a22021-02-23 19:59:10 +00001085 # libraries (e.g. "android.hardware.power.stats-V1-cpp")
Yifan Hong0011c632021-12-02 18:37:21 -08001086 android_lib = lib if '@' in lib or "-cpp" in lib or "-ndk" in lib \
1087 else 'lib' + lib
Primiano Tuccia3645202020-08-03 16:28:18 +02001088 if lib in shared_library_allowlist:
Lalit Magantie0986f32020-09-17 15:35:47 +01001089 module.add_android_shared_lib(android_lib)
Primiano Tuccia3645202020-08-03 16:28:18 +02001090 if lib in static_library_allowlist:
Lalit Magantie0986f32020-09-17 15:35:47 +01001091 module.add_android_static_lib(android_lib)
Lalit Magantic5bcd792018-01-12 18:38:11 +00001092
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001093 # If the module is a static library, export all the generated headers.
1094 if module.type == 'cc_library_static':
1095 module.export_generated_headers = module.generated_headers
Ryan Savitskie65beca2019-01-29 18:29:13 +00001096
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001097 # Merge in additional hardcoded arguments.
1098 for key, add_val in additional_args.get(module.name, []):
1099 curr = getattr(module, key)
1100 if add_val and isinstance(add_val, set) and isinstance(curr, set):
1101 curr.update(add_val)
Lalit Maganticdda9112019-11-27 14:19:49 +00001102 elif isinstance(add_val, str) and (not curr or isinstance(curr, str)):
Lalit Maganti3d415ec2019-10-23 17:53:17 +01001103 setattr(module, key, add_val)
Florian Mayerac4f4962020-09-15 10:03:22 +01001104 elif isinstance(add_val, bool) and (not curr or isinstance(curr, bool)):
1105 setattr(module, key, add_val)
Lalit Maganticdda9112019-11-27 14:19:49 +00001106 elif isinstance(add_val, dict) and isinstance(curr, dict):
1107 curr.update(add_val)
Lalit Magantie0986f32020-09-17 15:35:47 +01001108 elif isinstance(add_val, dict) and isinstance(curr, Target):
1109 curr.__dict__.update(add_val)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001110 else:
Florian Mayer5d09f5e2021-02-19 14:59:49 +00001111 raise Error('Unimplemented type %r of additional_args: %r' %
1112 (type(add_val), key))
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001113
1114 # dep_name is an unmangled GN target name (e.g. //foo:bar(toolchain)).
Lalit Maganti01f9b052022-12-17 01:21:13 +00001115 all_deps = target.non_proto_or_source_set_deps()
1116 all_deps |= target.transitive_source_set_deps()
1117 all_deps |= target.transitive_proto_deps()
1118 for dep in all_deps:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001119 # If the dependency refers to a library which we can replace with an
1120 # Android equivalent, stop recursing and patch the dependency in.
1121 # Don't recurse into //buildtools, builtin_deps are intercepted at
1122 # the //gn:xxx level.
Lalit Maganti01f9b052022-12-17 01:21:13 +00001123 dep_name = dep.name
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001124 if dep_name.startswith('//buildtools'):
1125 continue
1126
1127 # Ignore the dependency on the gen_buildflags genrule. That is run
1128 # separately in this generator and the generated file is copied over
1129 # into the repo (see usage of |buildflags_dir| in this script).
1130 if dep_name.startswith(gn_utils.BUILDFLAGS_TARGET):
1131 continue
1132
1133 dep_module = create_modules_from_target(blueprint, gn, dep_name)
1134
1135 # For filegroups and genrule, recurse but don't apply the deps.
1136 if not module_is_compiled:
1137 continue
1138
1139 # |builtin_deps| override GN deps with Android-specific ones. See the
1140 # config in the top of this file.
1141 if gn_utils.label_without_toolchain(dep_name) in builtin_deps:
1142 builtin_deps[gn_utils.label_without_toolchain(dep_name)](module)
1143 continue
1144
1145 # Don't recurse in any other //gn dep if not handled by builtin_deps.
1146 if dep_name.startswith('//gn:'):
1147 continue
1148
1149 if dep_module is None:
1150 continue
1151 if dep_module.type == 'cc_library_shared':
1152 module.shared_libs.add(dep_module.name)
1153 elif dep_module.type == 'cc_library_static':
1154 module.static_libs.add(dep_module.name)
1155 elif dep_module.type == 'filegroup':
1156 module.srcs.add(':' + dep_module.name)
1157 elif dep_module.type == 'genrule':
1158 module.generated_headers.update(dep_module.genrule_headers)
1159 module.srcs.update(dep_module.genrule_srcs)
1160 module.shared_libs.update(dep_module.genrule_shared_libs)
Primiano Tuccie094eec2020-03-18 16:58:21 +00001161 elif dep_module.type == 'cc_binary':
1162 continue # Ignore executables deps (used by cmdline integration tests).
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001163 else:
1164 raise Error('Unknown dep %s (%s) for target %s' %
1165 (dep_module.name, dep_module.type, module.name))
1166
1167 return module
Sami Kyostila865d1d32017-12-12 18:37:04 +00001168
1169
Lalit Maganti921a3d62022-12-17 14:28:50 +00001170def create_blueprint_for_targets(gn: GnParser, targets: List[str]):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001171 """Generate a blueprint for a list of GN targets."""
1172 blueprint = Blueprint()
Sami Kyostila865d1d32017-12-12 18:37:04 +00001173
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001174 # Default settings used by all modules.
1175 defaults = Module('cc_defaults', defaults_module, '//gn:default_deps')
Sami Kyostila865d1d32017-12-12 18:37:04 +00001176
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001177 # We have to use include_dirs passing the path relative to the android tree.
1178 # This is because: (i) perfetto_cc_defaults is used also by
1179 # test/**/Android.bp; (ii) if we use local_include_dirs instead, paths
1180 # become relative to the Android.bp that *uses* cc_defaults (not the one
1181 # that defines it).s
1182 defaults.include_dirs = {
Florian Mayer5d09f5e2021-02-19 14:59:49 +00001183 tree_path, tree_path + '/include', tree_path + '/' + buildflags_dir,
1184 tree_path + '/src/profiling/memory/include'
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001185 }
Lalit Maganti921a3d62022-12-17 14:28:50 +00001186 defaults.cflags.update([
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001187 '-Wno-error=return-type',
1188 '-Wno-sign-compare',
1189 '-Wno-sign-promo',
1190 '-Wno-unused-parameter',
1191 '-fvisibility=hidden',
1192 '-O2',
Lalit Maganti921a3d62022-12-17 14:28:50 +00001193 ])
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001194 defaults.user_debug_flag = True
1195 defaults.lto = True
Sami Kyostila865d1d32017-12-12 18:37:04 +00001196
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001197 blueprint.add_module(defaults)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001198 for target in targets:
1199 create_modules_from_target(blueprint, gn, target)
1200 return blueprint
Sami Kyostila865d1d32017-12-12 18:37:04 +00001201
1202
1203def main():
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001204 parser = argparse.ArgumentParser(
1205 description='Generate Android.bp from a GN description.')
1206 parser.add_argument(
1207 '--check-only',
1208 help='Don\'t keep the generated files',
1209 action='store_true')
1210 parser.add_argument(
1211 '--desc',
Matthew Clarkson63028d62019-10-10 15:48:23 +01001212 help='GN description (e.g., gn desc out --format=json --all-toolchains "//*"'
1213 )
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001214 parser.add_argument(
1215 '--extras',
1216 help='Extra targets to include at the end of the Blueprint file',
1217 default=os.path.join(gn_utils.repo_root(), 'Android.bp.extras'),
1218 )
1219 parser.add_argument(
1220 '--output',
1221 help='Blueprint file to create',
1222 default=os.path.join(gn_utils.repo_root(), 'Android.bp'),
1223 )
1224 parser.add_argument(
1225 'targets',
1226 nargs=argparse.REMAINDER,
1227 help='Targets to include in the blueprint (e.g., "//:perfetto_tests")')
1228 args = parser.parse_args()
Sami Kyostila865d1d32017-12-12 18:37:04 +00001229
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001230 if args.desc:
1231 with open(args.desc) as f:
1232 desc = json.load(f)
1233 else:
1234 desc = gn_utils.create_build_description(gn_args)
Sami Kyostila865d1d32017-12-12 18:37:04 +00001235
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001236 gn = gn_utils.GnParser(desc)
Lalit Maganti921a3d62022-12-17 14:28:50 +00001237 blueprint = create_blueprint_for_targets(gn, args.targets or default_targets)
Alexander Timin129c37c2021-04-08 19:17:59 +00001238 project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
1239 tool_name = os.path.relpath(os.path.abspath(__file__), project_root)
Primiano Tucci916f4e52020-10-16 20:40:33 +02001240
1241 # TODO(primiano): enable this on Android after the TODO in
1242 # perfetto_component.gni is fixed.
1243 # Check for ODR violations
1244 # for target_name in default_targets:
Lalit Maganti9c2318c2021-05-20 16:21:41 +01001245 # checker = gn_utils.ODRChecker(gn, target_name)
Primiano Tucci916f4e52020-10-16 20:40:33 +02001246
Lalit Magantid7afbb12022-03-28 15:12:24 +01001247 # Add any proto groups to the blueprint.
Kean Mariotti487a5392024-04-18 06:58:29 +00001248 for name, group in proto_groups.items():
1249 create_proto_group_modules(blueprint, gn, name, group)
Lalit Magantid7afbb12022-03-28 15:12:24 +01001250
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001251 output = [
1252 """// Copyright (C) 2017 The Android Open Source Project
Sami Kyostila865d1d32017-12-12 18:37:04 +00001253//
1254// Licensed under the Apache License, Version 2.0 (the "License");
1255// you may not use this file except in compliance with the License.
1256// You may obtain a copy of the License at
1257//
1258// http://www.apache.org/licenses/LICENSE-2.0
1259//
1260// Unless required by applicable law or agreed to in writing, software
1261// distributed under the License is distributed on an "AS IS" BASIS,
1262// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1263// See the License for the specific language governing permissions and
1264// limitations under the License.
1265//
1266// This file is automatically generated by %s. Do not edit.
Alexander Timin129c37c2021-04-08 19:17:59 +00001267""" % (tool_name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001268 ]
1269 blueprint.to_string(output)
1270 with open(args.extras, 'r') as r:
1271 for line in r:
1272 output.append(line.rstrip("\n\r"))
Primiano Tucci9c411652019-08-27 07:13:59 +02001273
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001274 out_files = []
Primiano Tucci9c411652019-08-27 07:13:59 +02001275
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001276 # Generate the Android.bp file.
1277 out_files.append(args.output + '.swp')
1278 with open(out_files[-1], 'w') as f:
1279 f.write('\n'.join(output))
Florian Mayerbbbd1ff2020-10-23 13:25:13 +01001280 # Text files should have a trailing EOL.
1281 f.write('\n')
Sami Kyostila865d1d32017-12-12 18:37:04 +00001282
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001283 # Generate the perfetto_build_flags.h file.
1284 out_files.append(os.path.join(buildflags_dir, 'perfetto_build_flags.h.swp'))
1285 gn_utils.gen_buildflags(gn_args, out_files[-1])
Sami Kyostila865d1d32017-12-12 18:37:04 +00001286
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001287 # Either check the contents or move the files to their final destination.
1288 return gn_utils.check_or_commit_generated_files(out_files, args.check_only)
Primiano Tucci9c411652019-08-27 07:13:59 +02001289
1290
Sami Kyostila865d1d32017-12-12 18:37:04 +00001291if __name__ == '__main__':
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001292 sys.exit(main())