blob: 82c2d763192d0ef93c6a29870a7daaf45904b78c [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': {
Kean Mariotti34af6df2024-03-07 10:11:15 +0000125 'types': ['lite'],
Kean Mariotti487a5392024-04-18 06:58:29 +0000126 'targets': [
127 '//protos/perfetto/trace:non_minimal_source_set',
128 '//protos/perfetto/trace:minimal_source_set',
129 ]
130 },
Kean Mariotti34af6df2024-03-07 10:11:15 +0000131 'winscope': {
132 'types': ['filegroup'],
133 'targets': [
134 '//protos/perfetto/trace:non_minimal_source_set',
135 '//protos/perfetto/trace/android:winscope_extensions:source_set',
136 ]
137 },
Kean Mariotti487a5392024-04-18 06:58:29 +0000138 'config': {
139 'types': ['lite'],
140 'targets': [
141 '//protos/perfetto/config:source_set',
142 ]
143 },
Lalit Magantid7afbb12022-03-28 15:12:24 +0100144}
145
Daniele Di Proiettocb426002023-02-16 12:14:38 +0000146needs_libfts = [
147 '//:perfetto_unittests',
148 '//src/trace_processor:trace_processor_shell',
149 '//src/traceconv:traceconv',
150]
151
Sami Kyostila865d1d32017-12-12 18:37:04 +0000152# All module names are prefixed with this string to avoid collisions.
153module_prefix = 'perfetto_'
154
155# Shared libraries which are directly translated to Android system equivalents.
Primiano Tuccia3645202020-08-03 16:28:18 +0200156shared_library_allowlist = [
Hector Dearman64f2e052019-12-04 20:51:14 +0000157 'android',
Hector Dearman92d7d112019-12-05 15:19:57 +0000158 'android.hardware.atrace@1.0',
159 'android.hardware.health@2.0',
Jack Wu40d043b2022-11-24 20:54:45 +0800160 'android.hardware.health-V2-ndk',
Hector Dearman92d7d112019-12-05 15:19:57 +0000161 'android.hardware.power.stats@1.0',
Hector Dearmanae979e02023-03-13 16:13:30 +0000162 'android.hardware.power.stats-V1-cpp',
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100163 'base',
Sami Kyostilab5b71692018-01-12 12:16:44 +0000164 'binder',
Raymond Chiu8c4d9a22021-02-23 19:59:10 +0000165 'binder_ndk',
Hector Dearman92d7d112019-12-05 15:19:57 +0000166 'cutils',
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100167 'hidlbase',
168 'hidltransport',
169 'hwbinder',
Ryan Savitski53ca60b2019-06-03 13:04:40 +0100170 'incident',
Sami Kyostila865d1d32017-12-12 18:37:04 +0000171 'log',
Sami Kyostilab5b71692018-01-12 12:16:44 +0000172 'services',
Hector Dearman92d7d112019-12-05 15:19:57 +0000173 'statssocket',
Hector Dearmanae979e02023-03-13 16:13:30 +0000174 'tracingproxy',
Primiano Tucciedf099c2018-01-08 18:27:56 +0000175 'utils',
Hector Dearmanff7abd42023-03-22 19:11:35 +0000176 'statspull',
Sami Kyostila865d1d32017-12-12 18:37:04 +0000177]
178
Hector Dearman92d7d112019-12-05 15:19:57 +0000179# Static libraries which are directly translated to Android system equivalents.
Primiano Tuccia3645202020-08-03 16:28:18 +0200180static_library_allowlist = [
Hector Dearman92d7d112019-12-05 15:19:57 +0000181 'statslog_perfetto',
182]
183
Sami Kyostila865d1d32017-12-12 18:37:04 +0000184# Name of the module which settings such as compiler flags for all other
185# modules.
186defaults_module = module_prefix + 'defaults'
187
188# Location of the project in the Android source tree.
189tree_path = 'external/perfetto'
190
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100191# Path for the protobuf sources in the standalone build.
192buildtools_protobuf_src = '//buildtools/protobuf/src'
193
194# Location of the protobuf src dir in the Android source tree.
195android_protobuf_src = 'external/protobuf/src'
196
Primiano Tucciedf099c2018-01-08 18:27:56 +0000197# Compiler flags which are passed through to the blueprint.
Primiano Tuccia3645202020-08-03 16:28:18 +0200198cflag_allowlist = r'^-DPERFETTO.*$'
Primiano Tucciedf099c2018-01-08 18:27:56 +0000199
Florian Mayer3d5e7e62018-01-19 15:22:46 +0000200# Compiler defines which are passed through to the blueprint.
Lalit Magantifa957e72023-03-16 18:22:23 +0000201define_allowlist = r'^(GOOGLE_PROTO.*)|(ZLIB_.*)|(USE_MMAP)$'
Florian Mayer3d5e7e62018-01-19 15:22:46 +0000202
Primiano Tucci8e627442019-08-28 07:58:38 +0200203# The directory where the generated perfetto_build_flags.h will be copied into.
204buildflags_dir = 'include/perfetto/base/build_configs/android_tree'
205
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100206def enumerate_data_deps():
207 with open(os.path.join(ROOT_DIR, 'tools', 'test_data.txt')) as f:
208 lines = f.readlines()
209 for line in (line.strip() for line in lines if not line.startswith('#')):
Andrew Shulaev576054d2020-01-23 13:44:51 +0000210 assert os.path.exists(line), 'file %s should exist' % line
Primiano Tucci02691162020-01-21 13:30:13 +0000211 if line.startswith('test/data/'):
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100212 # Skip test data files that require GCS. They are only for benchmarks.
213 # We don't run benchmarks in the android tree.
214 continue
Primiano Tucci17e8ae92021-05-17 17:40:50 +0100215 if line.endswith('/.'):
216 yield line[:-1] + '**/*'
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100217 else:
218 yield line
219
220
Florian Mayerb6a921f2018-10-18 18:55:23 +0100221# Additional arguments to apply to Android.bp rules.
222additional_args = {
Florian Mayer23f79372020-06-16 14:37:06 +0200223 'heapprofd_client_api': [
Florian Mayer23f79372020-06-16 14:37:06 +0200224 ('static_libs', {'libasync_safe'}),
Florian Mayer33159f72020-07-01 13:41:32 +0100225 # heapprofd_client_api MUST NOT have global constructors. Because it
226 # is loaded in an __attribute__((constructor)) of libc, we cannot
227 # guarantee that the global constructors get run before it is used.
228 ('cflags', {'-Wglobal-constructors', '-Werror=global-constructors'}),
Florian Mayer2131e362020-07-15 16:30:35 +0100229 ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
Florian Mayer7ed3a952021-01-08 10:55:25 +0000230 ('stubs', {
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100231 'versions': ['S'],
232 'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
Florian Mayer5d09f5e2021-02-19 14:59:49 +0000233 }),
234 ('export_include_dirs', {'src/profiling/memory/include'}),
235 ],
236 'heapprofd_api_noop': [
237 ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
238 ('stubs', {
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100239 'versions': ['S'],
240 'symbol_file': 'src/profiling/memory/heapprofd_client_api.map.txt',
Florian Mayer5d09f5e2021-02-19 14:59:49 +0000241 }),
242 ('export_include_dirs', {'src/profiling/memory/include'}),
Florian Mayer23f79372020-06-16 14:37:06 +0200243 ],
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100244 'heapprofd_client': [
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100245 ('include_dirs', {'bionic/libc'}),
246 ('static_libs', {'libasync_safe'}),
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100247 ],
Florian Mayer50f07a62020-07-15 17:15:58 +0100248 'heapprofd_standalone_client': [
249 ('static_libs', {'libasync_safe'}),
250 ('version_script', 'src/profiling/memory/heapprofd_client_api.map.txt'),
Florian Mayer5d09f5e2021-02-19 14:59:49 +0000251 ('export_include_dirs', {'src/profiling/memory/include'}),
Florian Mayer23b75a42020-07-30 15:21:25 +0100252 ('stl', 'libc++_static'),
Florian Mayer50f07a62020-07-15 17:15:58 +0100253 ],
Ryan Savitski703bcab2019-12-18 14:38:14 +0000254 'perfetto_unittests': [
255 ('data', set(enumerate_data_deps())),
256 ('include_dirs', {'bionic/libc/kernel'}),
257 ],
Florian Mayerac4f4962020-09-15 10:03:22 +0100258 'perfetto_integrationtests': [
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100259 ('test_suites', {'general-tests'}),
260 ('test_config', 'PerfettoIntegrationTests.xml'),
Florian Mayerac4f4962020-09-15 10:03:22 +0100261 ],
Lalit Magantid7afbb12022-03-28 15:12:24 +0100262 'libperfetto_android_internal': [('static_libs', {'libhealthhalutils'}),],
Lalit Maganticdda9112019-11-27 14:19:49 +0000263 'trace_processor_shell': [
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100264 ('strip', {
265 'all': True
266 }),
267 ('host', {
268 'stl': 'libc++_static',
269 'dist': {
270 'targets': ['sdk_repo']
271 },
272 }),
Lalit Maganticdda9112019-11-27 14:19:49 +0000273 ],
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900274 'libperfetto_client_experimental': [
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100275 ('apex_available', {
Nikita Putikhin94e30a02023-11-22 14:16:47 +0100276 '//apex_available:platform', '//apex_available:anyapex'
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100277 }),
Ryan Zuklie101f1b72022-10-25 16:22:07 -0700278 ('min_sdk_version', '30'),
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100279 ('shared_libs', {'liblog'}),
280 ('export_include_dirs', {'include', buildflags_dir}),
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900281 ],
Daniele Di Proiettoec4864e2022-12-14 17:32:38 +0000282 'libperfetto_c': [
283 ('min_sdk_version', '30'),
284 ('export_include_dirs', {'include'}),
285 ('cflags', {'-DPERFETTO_SHLIB_SDK_IMPLEMENTATION'}),
286 ],
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900287 'perfetto_trace_protos': [
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100288 ('apex_available', {
289 '//apex_available:platform', 'com.android.art',
290 'com.android.art.debug'
291 }),
292 ('min_sdk_version', 'S'),
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900293 ],
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100294 'libperfetto': [('export_include_dirs', {'include', buildflags_dir}),],
Daniele Di Proiettoe8068062024-02-16 17:54:03 +0000295 'perfetto': [('required', {'perfetto_persistent_cfg.pbtxt'}),],
Florian Mayerb6a921f2018-10-18 18:55:23 +0100296}
297
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100298
Lalit Maganti52f13362023-01-23 16:38:01 +0000299def enable_base_platform(module):
300 module.srcs.add(':perfetto_base_default_platform')
301
302
Primiano Tuccifbf4a732019-12-11 00:32:15 +0000303def enable_gtest_and_gmock(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100304 module.static_libs.add('libgmock')
Primiano Tuccifbf4a732019-12-11 00:32:15 +0000305 module.static_libs.add('libgtest')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000306 if module.name != 'perfetto_gtest_logcat_printer':
307 module.whole_static_libs.add('perfetto_gtest_logcat_printer')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100308
Sami Kyostila865d1d32017-12-12 18:37:04 +0000309
Sami Kyostila865d1d32017-12-12 18:37:04 +0000310def enable_protobuf_full(module):
Lalit Magantia97798d2020-09-16 17:40:57 +0100311 if module.type == 'cc_binary_host':
312 module.static_libs.add('libprotobuf-cpp-full')
Lalit Magantie0986f32020-09-17 15:35:47 +0100313 elif module.host_supported:
314 module.host.static_libs.add('libprotobuf-cpp-full')
315 module.android.shared_libs.add('libprotobuf-cpp-full')
Lalit Magantia97798d2020-09-16 17:40:57 +0100316 else:
317 module.shared_libs.add('libprotobuf-cpp-full')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100318
Sami Kyostila865d1d32017-12-12 18:37:04 +0000319
Sami Kyostila865d1d32017-12-12 18:37:04 +0000320def enable_protobuf_lite(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100321 module.shared_libs.add('libprotobuf-cpp-lite')
322
Sami Kyostila865d1d32017-12-12 18:37:04 +0000323
Sami Kyostila865d1d32017-12-12 18:37:04 +0000324def enable_protoc_lib(module):
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100325 if module.type == 'cc_binary_host':
326 module.static_libs.add('libprotoc')
327 else:
328 module.shared_libs.add('libprotoc')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100329
Sami Kyostila865d1d32017-12-12 18:37:04 +0000330
Florian Mayera2fae262018-08-31 12:10:01 -0700331def enable_libunwindstack(module):
Florian Mayer50f07a62020-07-15 17:15:58 +0100332 if module.name != 'heapprofd_standalone_client':
333 module.shared_libs.add('libunwindstack')
334 module.shared_libs.add('libprocinfo')
335 module.shared_libs.add('libbase')
336 else:
337 module.static_libs.add('libunwindstack')
338 module.static_libs.add('libprocinfo')
339 module.static_libs.add('libbase')
340 module.static_libs.add('liblzma')
341 module.static_libs.add('libdexfile_support')
Lalit Magantid7afbb12022-03-28 15:12:24 +0100342 module.runtime_libs.add('libdexfile') # libdexfile_support dependency
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100343
Sami Kyostila865d1d32017-12-12 18:37:04 +0000344
345def enable_libunwind(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100346 # libunwind is disabled on Darwin so we cannot depend on it.
347 pass
348
Sami Kyostila865d1d32017-12-12 18:37:04 +0000349
Lalit Maganti17aa2732019-02-08 15:47:26 +0000350def enable_sqlite(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100351 if module.type == 'cc_binary_host':
Michael Hoisie3e193512023-11-18 08:13:49 +0000352 module.static_libs.add('libsqlite_static_noicu')
Marcin Oczeretko1662f182022-08-18 10:29:46 +0100353 module.static_libs.add('sqlite_ext_percentile')
Lalit Magantie0986f32020-09-17 15:35:47 +0100354 elif module.host_supported:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100355 # Copy what the sqlite3 command line tool does.
356 module.android.shared_libs.add('libsqlite')
Victor Changd0d65902022-03-10 11:54:27 +0000357 module.android.shared_libs.add('libicu')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100358 module.android.shared_libs.add('liblog')
359 module.android.shared_libs.add('libutils')
Marcin Oczeretko1662f182022-08-18 10:29:46 +0100360 module.android.static_libs.add('sqlite_ext_percentile')
Michael Hoisie3e193512023-11-18 08:13:49 +0000361 module.host.static_libs.add('libsqlite_static_noicu')
Marcin Oczeretko1662f182022-08-18 10:29:46 +0100362 module.host.static_libs.add('sqlite_ext_percentile')
Lalit Magantie0986f32020-09-17 15:35:47 +0100363 else:
364 module.shared_libs.add('libsqlite')
Victor Changd0d65902022-03-10 11:54:27 +0000365 module.shared_libs.add('libicu')
Lalit Magantie0986f32020-09-17 15:35:47 +0100366 module.shared_libs.add('liblog')
367 module.shared_libs.add('libutils')
Marcin Oczeretko1662f182022-08-18 10:29:46 +0100368 module.static_libs.add('sqlite_ext_percentile')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100369
Lalit Maganti17aa2732019-02-08 15:47:26 +0000370
Hector Dearmane0b993f2019-05-24 18:48:16 +0100371def enable_zlib(module):
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100372 if module.type == 'cc_binary_host':
373 module.static_libs.add('libz')
Lalit Magantie0986f32020-09-17 15:35:47 +0100374 elif module.host_supported:
375 module.android.shared_libs.add('libz')
376 module.host.static_libs.add('libz')
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100377 else:
378 module.shared_libs.add('libz')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100379
Hector Dearmane0b993f2019-05-24 18:48:16 +0100380
Ryan Savitski56bc0c62020-01-27 13:50:02 +0000381def enable_uapi_headers(module):
382 module.include_dirs.add('bionic/libc/kernel')
383
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100384
Florian Mayer682f05a2020-08-11 10:16:54 +0100385def enable_bionic_libc_platform_headers_on_android(module):
386 module.header_libs.add('bionic_libc_platform_headers')
387
Ryan Savitski56bc0c62020-01-27 13:50:02 +0000388
Sami Kyostila865d1d32017-12-12 18:37:04 +0000389# Android equivalents for third-party libraries that the upstream project
390# depends on.
391builtin_deps = {
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100392 '//gn:default_deps':
393 lambda x: None,
394 '//gn:gtest_main':
395 lambda x: None,
396 '//gn:protoc':
397 lambda x: None,
Lalit Maganti52f13362023-01-23 16:38:01 +0000398 '//gn:base_platform':
399 enable_base_platform,
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100400 '//gn:gtest_and_gmock':
401 enable_gtest_and_gmock,
402 '//gn:libunwind':
403 enable_libunwind,
404 '//gn:protobuf_full':
405 enable_protobuf_full,
406 '//gn:protobuf_lite':
407 enable_protobuf_lite,
408 '//gn:protoc_lib':
409 enable_protoc_lib,
410 '//gn:libunwindstack':
411 enable_libunwindstack,
412 '//gn:sqlite':
413 enable_sqlite,
414 '//gn:zlib':
415 enable_zlib,
416 '//gn:bionic_kernel_uapi_headers':
417 enable_uapi_headers,
Florian Mayer682f05a2020-08-11 10:16:54 +0100418 '//src/profiling/memory:bionic_libc_platform_headers_on_android':
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100419 enable_bionic_libc_platform_headers_on_android,
Sami Kyostila865d1d32017-12-12 18:37:04 +0000420}
421
422# ----------------------------------------------------------------------------
423# End of configuration.
424# ----------------------------------------------------------------------------
425
426
427class Error(Exception):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100428 pass
Sami Kyostila865d1d32017-12-12 18:37:04 +0000429
430
431class ThrowingArgumentParser(argparse.ArgumentParser):
Sami Kyostila865d1d32017-12-12 18:37:04 +0000432
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100433 def __init__(self, context):
434 super(ThrowingArgumentParser, self).__init__()
435 self.context = context
436
437 def error(self, message):
438 raise Error('%s: %s' % (self.context, message))
Sami Kyostila865d1d32017-12-12 18:37:04 +0000439
440
Lalit Magantiedace412019-06-18 13:28:28 +0100441def write_blueprint_key_value(output, name, value, sort=True):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100442 """Writes a Blueprint key-value pair to the output"""
Lalit Magantiedace412019-06-18 13:28:28 +0100443
Lalit Magantid7afbb12022-03-28 15:12:24 +0100444 if isinstance(value, bool):
445 if value:
446 output.append(' %s: true,' % name)
447 else:
448 output.append(' %s: false,' % name)
449 return
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100450 if not value:
451 return
452 if isinstance(value, set):
453 value = sorted(value)
454 if isinstance(value, list):
Colin Cross84172332021-09-14 16:41:33 -0700455 output.append(' %s: [' % name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100456 for item in sorted(value) if sort else value:
Colin Cross84172332021-09-14 16:41:33 -0700457 output.append(' "%s",' % item)
458 output.append(' ],')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100459 return
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100460 if isinstance(value, Target):
461 value.to_string(output)
462 return
Lalit Maganticdda9112019-11-27 14:19:49 +0000463 if isinstance(value, dict):
464 kv_output = []
465 for k, v in value.items():
466 write_blueprint_key_value(kv_output, k, v)
467
Colin Cross84172332021-09-14 16:41:33 -0700468 output.append(' %s: {' % name)
Lalit Maganticdda9112019-11-27 14:19:49 +0000469 for line in kv_output:
Colin Cross84172332021-09-14 16:41:33 -0700470 output.append(' %s' % line)
471 output.append(' },')
Lalit Maganticdda9112019-11-27 14:19:49 +0000472 return
Colin Cross84172332021-09-14 16:41:33 -0700473 output.append(' %s: "%s",' % (name, value))
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100474
Lalit Magantiedace412019-06-18 13:28:28 +0100475
476class Target(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100477 """A target-scoped part of a module"""
Lalit Magantiedace412019-06-18 13:28:28 +0100478
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100479 def __init__(self, name):
480 self.name = name
481 self.shared_libs = set()
482 self.static_libs = set()
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000483 self.whole_static_libs = set()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100484 self.cflags = set()
Florian Mayer637513a2020-12-04 19:15:49 +0000485 self.dist = dict()
486 self.strip = dict()
Lalit Magantie0986f32020-09-17 15:35:47 +0100487 self.stl = None
Lalit Magantiedace412019-06-18 13:28:28 +0100488
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100489 def to_string(self, output):
490 nested_out = []
491 self._output_field(nested_out, 'shared_libs')
492 self._output_field(nested_out, 'static_libs')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000493 self._output_field(nested_out, 'whole_static_libs')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100494 self._output_field(nested_out, 'cflags')
Lalit Magantie0986f32020-09-17 15:35:47 +0100495 self._output_field(nested_out, 'stl')
Florian Mayer637513a2020-12-04 19:15:49 +0000496 self._output_field(nested_out, 'dist')
497 self._output_field(nested_out, 'strip')
Lalit Magantiedace412019-06-18 13:28:28 +0100498
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100499 if nested_out:
Colin Cross84172332021-09-14 16:41:33 -0700500 output.append(' %s: {' % self.name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100501 for line in nested_out:
Colin Cross84172332021-09-14 16:41:33 -0700502 output.append(' %s' % line)
503 output.append(' },')
Lalit Magantiedace412019-06-18 13:28:28 +0100504
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100505 def _output_field(self, output, name, sort=True):
506 value = getattr(self, name)
507 return write_blueprint_key_value(output, name, value, sort)
508
Lalit Magantiedace412019-06-18 13:28:28 +0100509
Sami Kyostila865d1d32017-12-12 18:37:04 +0000510class Module(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100511 """A single module (e.g., cc_binary, cc_test) in a blueprint."""
Sami Kyostila865d1d32017-12-12 18:37:04 +0000512
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100513 def __init__(self, mod_type, name, gn_target):
Lalit Maganti01f9b052022-12-17 01:21:13 +0000514 assert (gn_target)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100515 self.type = mod_type
516 self.gn_target = gn_target
517 self.name = name
518 self.srcs = set()
Lalit Maganti921a3d62022-12-17 14:28:50 +0000519 self.main: Optional[str] = None
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100520 self.comment = 'GN: ' + gn_utils.label_without_toolchain(gn_target)
521 self.shared_libs = set()
522 self.static_libs = set()
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000523 self.whole_static_libs = set()
Martin Stjernholmbe2411d2021-08-26 21:15:10 +0100524 self.runtime_libs = set()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100525 self.tools = set()
Lalit Maganti921a3d62022-12-17 14:28:50 +0000526 self.cmd: Optional[str] = None
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100527 self.host_supported = False
Michael Eastwood6cbbff12021-12-09 15:34:35 -0800528 self.vendor_available = False
Nikita Putikhin94e30a02023-11-22 14:16:47 +0100529 self.product_available = False
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100530 self.init_rc = set()
531 self.out = set()
532 self.export_include_dirs = set()
533 self.generated_headers = set()
534 self.export_generated_headers = set()
535 self.defaults = set()
536 self.cflags = set()
537 self.include_dirs = set()
538 self.header_libs = set()
539 self.required = set()
540 self.user_debug_flag = False
Lalit Maganti921a3d62022-12-17 14:28:50 +0000541 self.tool_files: Optional[List[str]] = None
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100542 self.android = Target('android')
543 self.host = Target('host')
Daniele Di Proiettocb426002023-02-16 12:14:38 +0000544 self.musl = Target('musl')
Lalit Maganti921a3d62022-12-17 14:28:50 +0000545 self.lto: Optional[bool] = None
Lalit Maganticdda9112019-11-27 14:19:49 +0000546 self.stl = None
547 self.dist = dict()
Lalit Magantiaccd64b2020-03-16 19:54:10 +0000548 self.strip = dict()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100549 self.data = set()
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900550 self.apex_available = set()
Primiano Tucci39097c52021-03-04 09:58:06 +0000551 self.min_sdk_version = None
Lalit Magantid7afbb12022-03-28 15:12:24 +0100552 self.proto = dict()
Pablo Gamito40e6e682023-12-04 12:04:33 +0000553 self.output_extension: Optional[str] = None
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100554 # The genrule_XXX below are properties that must to be propagated back
555 # on the module(s) that depend on the genrule.
556 self.genrule_headers = set()
557 self.genrule_srcs = set()
558 self.genrule_shared_libs = set()
Florian Mayer2131e362020-07-15 16:30:35 +0100559 self.version_script = None
Florian Mayerac4f4962020-09-15 10:03:22 +0100560 self.test_suites = set()
Florian Mayerab23f442021-02-09 15:37:45 +0000561 self.test_config = None
Florian Mayer7ed3a952021-01-08 10:55:25 +0000562 self.stubs = {}
Sami Kyostila865d1d32017-12-12 18:37:04 +0000563
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100564 def to_string(self, output):
565 if self.comment:
566 output.append('// %s' % self.comment)
567 output.append('%s {' % self.type)
568 self._output_field(output, 'name')
569 self._output_field(output, 'srcs')
570 self._output_field(output, 'shared_libs')
571 self._output_field(output, 'static_libs')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000572 self._output_field(output, 'whole_static_libs')
Martin Stjernholmbe2411d2021-08-26 21:15:10 +0100573 self._output_field(output, 'runtime_libs')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100574 self._output_field(output, 'tools')
575 self._output_field(output, 'cmd', sort=False)
Lalit Magantid7afbb12022-03-28 15:12:24 +0100576 if self.host_supported:
577 self._output_field(output, 'host_supported')
578 if self.vendor_available:
579 self._output_field(output, 'vendor_available')
Nikita Putikhin94e30a02023-11-22 14:16:47 +0100580 if self.product_available:
581 self._output_field(output, 'product_available')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100582 self._output_field(output, 'init_rc')
583 self._output_field(output, 'out')
584 self._output_field(output, 'export_include_dirs')
585 self._output_field(output, 'generated_headers')
586 self._output_field(output, 'export_generated_headers')
587 self._output_field(output, 'defaults')
588 self._output_field(output, 'cflags')
589 self._output_field(output, 'include_dirs')
590 self._output_field(output, 'header_libs')
591 self._output_field(output, 'required')
Lalit Maganticdda9112019-11-27 14:19:49 +0000592 self._output_field(output, 'dist')
Lalit Magantiaccd64b2020-03-16 19:54:10 +0000593 self._output_field(output, 'strip')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100594 self._output_field(output, 'tool_files')
595 self._output_field(output, 'data')
Lalit Maganticdda9112019-11-27 14:19:49 +0000596 self._output_field(output, 'stl')
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900597 self._output_field(output, 'apex_available')
Primiano Tucci39097c52021-03-04 09:58:06 +0000598 self._output_field(output, 'min_sdk_version')
Florian Mayer2131e362020-07-15 16:30:35 +0100599 self._output_field(output, 'version_script')
Florian Mayerac4f4962020-09-15 10:03:22 +0100600 self._output_field(output, 'test_suites')
Florian Mayerab23f442021-02-09 15:37:45 +0000601 self._output_field(output, 'test_config')
Florian Mayer7ed3a952021-01-08 10:55:25 +0000602 self._output_field(output, 'stubs')
Lalit Magantid7afbb12022-03-28 15:12:24 +0100603 self._output_field(output, 'proto')
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000604 self._output_field(output, 'main')
Pablo Gamito40e6e682023-12-04 12:04:33 +0000605 self._output_field(output, 'output_extension')
Lalit Magantid8b1a1d2018-05-23 14:41:43 +0100606
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100607 target_out = []
608 self._output_field(target_out, 'android')
609 self._output_field(target_out, 'host')
Daniele Di Proiettocb426002023-02-16 12:14:38 +0000610 self._output_field(target_out, 'musl')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100611 if target_out:
Colin Cross84172332021-09-14 16:41:33 -0700612 output.append(' target: {')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100613 for line in target_out:
Colin Cross84172332021-09-14 16:41:33 -0700614 output.append(' %s' % line)
615 output.append(' },')
Lalit Magantiedace412019-06-18 13:28:28 +0100616
Colin Cross162b48e2021-09-14 17:01:50 -0700617 if self.user_debug_flag:
Colin Cross84172332021-09-14 16:41:33 -0700618 output.append(' product_variables: {')
Colin Cross162b48e2021-09-14 17:01:50 -0700619 output.append(' debuggable: {')
620 output.append(
621 ' cflags: ["-DPERFETTO_BUILD_WITH_ANDROID_USERDEBUG"],')
622 output.append(' },')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100623 output.append(' },')
Colin Cross84172332021-09-14 16:41:33 -0700624 if self.lto is not None:
625 output.append(' target: {')
626 output.append(' android: {')
627 output.append(' lto: {')
Lalit Magantid7afbb12022-03-28 15:12:24 +0100628 output.append(' thin: %s,' %
629 'true' if self.lto else 'false')
Colin Cross84172332021-09-14 16:41:33 -0700630 output.append(' },')
631 output.append(' },')
632 output.append(' },')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100633 output.append('}')
634 output.append('')
Sami Kyostila865d1d32017-12-12 18:37:04 +0000635
Lalit Magantie0986f32020-09-17 15:35:47 +0100636 def add_android_static_lib(self, lib):
637 if self.type == 'cc_binary_host':
638 raise Exception('Adding Android static lib for host tool is unsupported')
639 elif self.host_supported:
640 self.android.static_libs.add(lib)
641 else:
642 self.static_libs.add(lib)
643
Lalit Magantie0986f32020-09-17 15:35:47 +0100644 def add_android_shared_lib(self, lib):
645 if self.type == 'cc_binary_host':
646 raise Exception('Adding Android shared lib for host tool is unsupported')
647 elif self.host_supported:
648 self.android.shared_libs.add(lib)
649 else:
650 self.shared_libs.add(lib)
651
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100652 def _output_field(self, output, name, sort=True):
653 value = getattr(self, name)
654 return write_blueprint_key_value(output, name, value, sort)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000655
656
657class Blueprint(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100658 """In-memory representation of an Android.bp file."""
Sami Kyostila865d1d32017-12-12 18:37:04 +0000659
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100660 def __init__(self):
Lalit Maganti27b00af2022-12-17 01:20:38 +0000661 self.modules: Dict[str, Module] = {}
662 self.gn_target_to_module: Dict[str, Module] = {}
Sami Kyostila865d1d32017-12-12 18:37:04 +0000663
Lalit Maganti27b00af2022-12-17 01:20:38 +0000664 def add_module(self, module: Module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100665 """Adds a new module to the blueprint, replacing any existing module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000666 with the same name.
667
668 Args:
669 module: Module instance.
670 """
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100671 self.modules[module.name] = module
Lalit Maganti27b00af2022-12-17 01:20:38 +0000672 self.gn_target_to_module[module.gn_target] = module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000673
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100674 def to_string(self, output):
675 for m in sorted(itervalues(self.modules), key=lambda m: m.name):
676 m.to_string(output)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000677
678
Lalit Maganti921a3d62022-12-17 14:28:50 +0000679def label_to_module_name(label: str):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100680 """Turn a GN label (e.g., //:perfetto_tests) into a module name."""
681 # If the label is explicibly listed in the default target list, don't prefix
682 # its name and return just the target name. This is so tools like
Hector Dearmana9545e52022-05-17 12:23:25 +0100683 # "traceconv" stay as such in the Android tree.
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100684 label_without_toolchain = gn_utils.label_without_toolchain(label)
685 if label in default_targets or label_without_toolchain in default_targets:
686 return label_without_toolchain.split(':')[-1]
Primiano Tucci02c11762019-08-30 00:57:59 +0200687
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100688 module = re.sub(r'^//:?', '', label_without_toolchain)
689 module = re.sub(r'[^a-zA-Z0-9_]', '_', module)
690 if not module.startswith(module_prefix):
691 return module_prefix + module
692 return module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000693
694
Lalit Maganti921a3d62022-12-17 14:28:50 +0000695def is_supported_source_file(name: str):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100696 """Returns True if |name| can appear in a 'srcs' list."""
697 return os.path.splitext(name)[1] in ['.c', '.cc', '.proto']
Sami Kyostila865d1d32017-12-12 18:37:04 +0000698
699
Lalit Maganti921a3d62022-12-17 14:28:50 +0000700def create_proto_modules(blueprint: Blueprint, gn: GnParser,
701 target: GnParser.Target):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100702 """Generate genrules for a proto GN target.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000703
704 GN actions are used to dynamically generate files during the build. The
705 Soong equivalent is a genrule. This function turns a specific kind of
706 genrule which turns .proto files into source and header files into a pair
Sami Kyostila71625d72017-12-18 10:29:49 +0000707 equivalent genrules.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000708
709 Args:
710 blueprint: Blueprint instance which is being generated.
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100711 target: gn_utils.Target object.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000712
713 Returns:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100714 The source_genrule module.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000715 """
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100716 assert (target.type == 'proto_library')
Lalit Maganti117272f2020-09-11 14:01:18 +0100717
Lalit Maganti921a3d62022-12-17 14:28:50 +0000718 # We don't generate any targets for source_set proto modules because
719 # they will be inlined into other modules if required.
720 if target.proto_plugin == 'source_set':
721 return None
722
Lalit Maganti117272f2020-09-11 14:01:18 +0100723 tools = {'aprotoc'}
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100724 cpp_out_dir = '$(genDir)/%s/' % tree_path
Lalit Maganti117272f2020-09-11 14:01:18 +0100725 target_module_name = label_to_module_name(target.name)
726
727 # In GN builds the proto path is always relative to the output directory
728 # (out/tmp.xxx).
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000729 cmd = ['mkdir -p %s &&' % cpp_out_dir, '$(location aprotoc)']
Lalit Maganti117272f2020-09-11 14:01:18 +0100730 cmd += ['--proto_path=%s' % tree_path]
731
Spandan Das34f1b982023-10-13 23:24:01 +0000732 tool_files = set()
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100733 if buildtools_protobuf_src in target.proto_paths:
734 cmd += ['--proto_path=%s' % android_protobuf_src]
Spandan Das34f1b982023-10-13 23:24:01 +0000735 # Add `google/protobuf/descriptor.proto` to implicit deps
736 tool_files.add(':libprotobuf-internal-descriptor-proto')
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100737
Lalit Maganti117272f2020-09-11 14:01:18 +0100738 # Descriptor targets only generate a single target.
739 if target.proto_plugin == 'descriptor':
740 out = '{}.bin'.format(target_module_name)
741
Lalit Magantife422eb2020-11-12 14:00:09 +0000742 cmd += ['--descriptor_set_out=$(out)']
Lalit Maganti117272f2020-09-11 14:01:18 +0100743 cmd += ['$(in)']
744
745 descriptor_module = Module('genrule', target_module_name, target.name)
746 descriptor_module.cmd = ' '.join(cmd)
Lalit Maganti921a3d62022-12-17 14:28:50 +0000747 descriptor_module.out.add(out)
Lalit Maganti117272f2020-09-11 14:01:18 +0100748 descriptor_module.tools = tools
749 blueprint.add_module(descriptor_module)
750
Lalit Magantife422eb2020-11-12 14:00:09 +0000751 # Recursively extract the .proto files of all the dependencies and
752 # add them to srcs.
Lalit Magantid7afbb12022-03-28 15:12:24 +0100753 descriptor_module.srcs.update(
754 gn_utils.label_to_path(src) for src in target.sources)
Spandan Das34f1b982023-10-13 23:24:01 +0000755 # Add the tool_files to srcs so that they get copied if this action is
756 # sandboxed in Soong.
757 # Add to `srcs` instead of `tool_files` (the latter will require a
758 # --proto_path that depends on Soong's sandbox implementation.)
759 descriptor_module.srcs.update(
760 src for src in tool_files)
Lalit Maganti01f9b052022-12-17 01:21:13 +0000761 for dep in target.transitive_proto_deps():
762 current_target = gn.get_target(dep.name)
Lalit Magantife422eb2020-11-12 14:00:09 +0000763 descriptor_module.srcs.update(
764 gn_utils.label_to_path(src) for src in current_target.sources)
Lalit Magantife422eb2020-11-12 14:00:09 +0000765
Lalit Maganti117272f2020-09-11 14:01:18 +0100766 return descriptor_module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000767
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100768 # We create two genrules for each proto target: one for the headers and
769 # another for the sources. This is because the module that depends on the
770 # generated files needs to declare two different types of dependencies --
771 # source files in 'srcs' and headers in 'generated_headers' -- and it's not
772 # valid to generate .h files from a source dependency and vice versa.
Spandan Das34f1b982023-10-13 23:24:01 +0000773 #
774 # We create an additional filegroup for .proto
775 # The .proto filegroup will be added to `tool_files` of rdeps so that the
776 # genrules can be sandboxed.
777
Spandan Das34f1b982023-10-13 23:24:01 +0000778 for proto_dep in target.proto_deps().union(target.transitive_proto_deps()):
779 tool_files.add(":" + label_to_module_name(proto_dep.name))
780
781 filegroup_module = Module('filegroup', target_module_name, target.name)
782 filegroup_module.srcs.update(
783 gn_utils.label_to_path(src) for src in target.sources)
784 blueprint.add_module(filegroup_module)
785
Lalit Maganti117272f2020-09-11 14:01:18 +0100786 source_module_name = target_module_name + '_gen'
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100787 source_module = Module('genrule', source_module_name, target.name)
Spandan Das34f1b982023-10-13 23:24:01 +0000788 # Add the "root" .proto filegroup to srcs
789 source_module.srcs = set([':' + target_module_name])
790 # Add the tool_files to srcs so that they get copied if this action is
791 # sandboxed in Soong.
792 # Add to `srcs` instead of `tool_files` (the latter will require a
793 # --proto_path that depends on Soong's sandbox implementation.)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100794 source_module.srcs.update(
Spandan Das34f1b982023-10-13 23:24:01 +0000795 src for src in tool_files)
796 blueprint.add_module(source_module)
Primiano Tucci20b760c2018-01-19 12:36:12 +0000797
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100798 header_module = Module('genrule', source_module_name + '_headers',
799 target.name)
800 blueprint.add_module(header_module)
801 header_module.srcs = set(source_module.srcs)
Primiano Tucci20b760c2018-01-19 12:36:12 +0000802
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100803 # TODO(primiano): at some point we should remove this. This was introduced
804 # by aosp/1108421 when adding "protos/" to .proto include paths, in order to
805 # avoid doing multi-repo changes and allow old clients in the android tree
806 # to still do the old #include "perfetto/..." rather than
807 # #include "protos/perfetto/...".
808 header_module.export_include_dirs = {'.', 'protos'}
Sami Kyostila865d1d32017-12-12 18:37:04 +0000809
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100810 source_module.genrule_srcs.add(':' + source_module.name)
811 source_module.genrule_headers.add(header_module.name)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000812
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100813 if target.proto_plugin == 'proto':
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000814 suffixes = ['pb']
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100815 source_module.genrule_shared_libs.add('libprotobuf-cpp-lite')
Primiano Tucci7b6a7882020-01-20 22:34:31 +0000816 cmd += ['--cpp_out=lite=true:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100817 elif target.proto_plugin == 'protozero':
818 suffixes = ['pbzero']
819 plugin = create_modules_from_target(blueprint, gn, protozero_plugin)
Lalit Maganti921a3d62022-12-17 14:28:50 +0000820 assert (plugin)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100821 tools.add(plugin.name)
822 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
823 cmd += ['--plugin_out=wrapper_namespace=pbzero:' + cpp_out_dir]
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100824 elif target.proto_plugin == 'cppgen':
825 suffixes = ['gen']
826 plugin = create_modules_from_target(blueprint, gn, cppgen_plugin)
Lalit Maganti921a3d62022-12-17 14:28:50 +0000827 assert (plugin)
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100828 tools.add(plugin.name)
829 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
Primiano Tuccie8020f92019-11-26 13:24:01 +0000830 cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100831 elif target.proto_plugin == 'ipc':
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000832 suffixes = ['ipc']
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100833 plugin = create_modules_from_target(blueprint, gn, ipc_plugin)
Lalit Maganti921a3d62022-12-17 14:28:50 +0000834 assert (plugin)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100835 tools.add(plugin.name)
836 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
Primiano Tuccie8020f92019-11-26 13:24:01 +0000837 cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100838 else:
839 raise Error('Unsupported proto plugin: %s' % target.proto_plugin)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000840
Spandan Das34f1b982023-10-13 23:24:01 +0000841 cmd += ['$(locations :%s)' % target_module_name]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100842 source_module.cmd = ' '.join(cmd)
843 header_module.cmd = source_module.cmd
844 source_module.tools = tools
845 header_module.tools = tools
Primiano Tucci20b760c2018-01-19 12:36:12 +0000846
Spandan Das34f1b982023-10-13 23:24:01 +0000847
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100848 for sfx in suffixes:
Matthew Clarkson63028d62019-10-10 15:48:23 +0100849 source_module.out.update('%s/%s' %
850 (tree_path, src.replace('.proto', '.%s.cc' % sfx))
Spandan Das34f1b982023-10-13 23:24:01 +0000851 for src in filegroup_module.srcs)
Matthew Clarkson63028d62019-10-10 15:48:23 +0100852 header_module.out.update('%s/%s' %
853 (tree_path, src.replace('.proto', '.%s.h' % sfx))
Spandan Das34f1b982023-10-13 23:24:01 +0000854 for src in filegroup_module.srcs)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100855 return source_module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000856
Sami Kyostila3c88a1d2019-05-22 18:29:42 +0100857
Lalit Maganti921a3d62022-12-17 14:28:50 +0000858def create_tp_tables_module(blueprint: Blueprint, gn: GnParser,
859 target: GnParser.Target):
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000860 bp_module_name = label_to_module_name(target.name)
861 bp_binary_module_name = f'{bp_module_name}_binary'
862 srcs = [gn_utils.label_to_path(src) for src in target.sources]
863
Lalit Maganti921a3d62022-12-17 14:28:50 +0000864 binary_module = Module('python_binary_host', bp_binary_module_name,
865 target.name)
Lalit Maganti01f9b052022-12-17 01:21:13 +0000866 for dep in target.non_proto_or_source_set_deps():
867 binary_module.srcs.update([
868 gn_utils.label_to_path(src) for src in gn.get_target(dep.name).sources
869 ])
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000870 binary_module.srcs.update(srcs)
871 binary_module.srcs.add('tools/gen_tp_table_headers.py')
872 binary_module.main = 'tools/gen_tp_table_headers.py'
873 blueprint.add_module(binary_module)
874
875 module = Module('genrule', bp_module_name, target.name)
876 module.tools = set([
877 bp_binary_module_name,
878 ])
879 module.cmd = ' '.join([
880 f'$(location {bp_binary_module_name})',
881 '--gen-dir=$(genDir)',
Lalit Maganti3df8a7e2023-04-25 14:18:17 +0100882 '--relative-input-dir=external/perfetto',
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000883 '--inputs',
884 '$(in)',
Lalit Maganti3dc8e302022-12-01 20:32:46 +0000885 ])
886 module.out.update(target.outputs)
887 module.genrule_headers.add(module.name)
888 module.srcs.update(srcs)
889 blueprint.add_module(module)
890
891 return module
892
893
Lalit Maganti01f9b052022-12-17 01:21:13 +0000894def create_amalgamated_sql_module(blueprint: Blueprint, gn: GnParser,
895 target: GnParser.Target):
Anna Mayznercc18bfd2022-11-03 14:05:19 +0000896 bp_module_name = label_to_module_name(target.name)
Lalit Maganti358a7e42022-11-09 15:16:21 +0000897
898 def find_arg(name):
899 for i, arg in enumerate(target.args):
900 if arg.startswith(f'--{name}'):
901 return target.args[i + 1]
902
903 namespace = find_arg('namespace')
Lalit Maganti358a7e42022-11-09 15:16:21 +0000904
Anna Mayznercc18bfd2022-11-03 14:05:19 +0000905 module = Module('genrule', bp_module_name, target.name)
906 module.tool_files = [
907 'tools/gen_amalgamated_sql.py',
908 ]
909 module.cmd = ' '.join([
910 '$(location tools/gen_amalgamated_sql.py)',
Lalit Maganti358a7e42022-11-09 15:16:21 +0000911 f'--namespace={namespace}',
Lalit Maganti358a7e42022-11-09 15:16:21 +0000912 '--cpp-out=$(out)',
Anna Mayznercc18bfd2022-11-03 14:05:19 +0000913 '$(in)',
914 ])
915 module.genrule_headers.add(module.name)
916 module.out.update(target.outputs)
Lalit Maganti358a7e42022-11-09 15:16:21 +0000917
Lalit Maganti33619852022-12-17 01:22:36 +0000918 for dep in target.transitive_deps:
Rasika Navarangec3634b42023-11-14 19:45:04 +0000919 # Use globs for the chrome stdlib so the file does not need to be
920 # regenerated in autoroll CLs.
921 if dep.name.startswith(
922 '//src/trace_processor/perfetto_sql/stdlib/chrome:chrome_sql'):
923 module.srcs.add('src/trace_processor/perfetto_sql/stdlib/chrome/**/*.sql')
924 continue
Lalit Maganti358a7e42022-11-09 15:16:21 +0000925 module.srcs.update(
Lalit Maganti01f9b052022-12-17 01:21:13 +0000926 [gn_utils.label_to_path(src) for src in gn.get_target(dep.name).inputs])
Anna Mayznercc18bfd2022-11-03 14:05:19 +0000927 blueprint.add_module(module)
928 return module
Sami Kyostila3c88a1d2019-05-22 18:29:42 +0100929
Lalit Maganti358a7e42022-11-09 15:16:21 +0000930
Lalit Maganti921a3d62022-12-17 14:28:50 +0000931def create_cc_proto_descriptor_module(blueprint: Blueprint,
932 target: GnParser.Target):
Lalit Maganti3b09a3f2020-09-14 13:28:44 +0100933 bp_module_name = label_to_module_name(target.name)
934 module = Module('genrule', bp_module_name, target.name)
Lalit Maganti117272f2020-09-11 14:01:18 +0100935 module.tool_files = [
936 'tools/gen_cc_proto_descriptor.py',
937 ]
938 module.cmd = ' '.join([
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100939 '$(location tools/gen_cc_proto_descriptor.py)', '--gen_dir=$(genDir)',
940 '--cpp_out=$(out)', '$(in)'
Lalit Maganti117272f2020-09-11 14:01:18 +0100941 ])
942 module.genrule_headers.add(module.name)
943 module.srcs.update(
Lalit Maganti01f9b052022-12-17 01:21:13 +0000944 ':' + label_to_module_name(dep.name) for dep in target.proto_deps())
Hector Dearman24838932022-07-06 21:57:58 +0100945 module.srcs.update(
946 gn_utils.label_to_path(src)
947 for src in target.inputs
948 if "tmp.gn_utils" not in src)
Lalit Maganti117272f2020-09-11 14:01:18 +0100949 module.out.update(target.outputs)
950 blueprint.add_module(module)
951 return module
952
953
Lalit Maganti01f9b052022-12-17 01:21:13 +0000954def create_gen_version_module(blueprint: Blueprint, target: GnParser.Target,
955 bp_module_name: str):
Primiano Tucciec590132020-11-16 14:16:44 +0100956 module = Module('genrule', bp_module_name, gn_utils.GEN_VERSION_TARGET)
957 script_path = gn_utils.label_to_path(target.script)
958 module.genrule_headers.add(bp_module_name)
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100959 module.tool_files = [script_path]
Primiano Tucciec590132020-11-16 14:16:44 +0100960 module.out.update(target.outputs)
961 module.srcs.update(gn_utils.label_to_path(src) for src in target.inputs)
962 module.cmd = ' '.join([
Lalit Maganti9c2318c2021-05-20 16:21:41 +0100963 'python3 $(location %s)' % script_path, '--no_git',
964 '--changelog=$(location CHANGELOG)', '--cpp_out=$(out)'
Primiano Tucciec590132020-11-16 14:16:44 +0100965 ])
966 blueprint.add_module(module)
967 return module
968
969
Lalit Maganti01f9b052022-12-17 01:21:13 +0000970def create_proto_group_modules(blueprint, gn: GnParser, module_name: str,
Kean Mariotti487a5392024-04-18 06:58:29 +0000971 group):
972 target_names = group['targets']
973 module_types = group['types']
974 module_sources = set()
Lalit Magantid7afbb12022-03-28 15:12:24 +0100975
976 for name in target_names:
977 target = gn.get_target(name)
Kean Mariotti487a5392024-04-18 06:58:29 +0000978 module_sources.update(gn_utils.label_to_path(src) for src in target.sources)
Lalit Maganti01f9b052022-12-17 01:21:13 +0000979 for dep_label in target.transitive_proto_deps():
980 dep = gn.get_target(dep_label.name)
Kean Mariotti487a5392024-04-18 06:58:29 +0000981 module_sources.update(gn_utils.label_to_path(src) for src in dep.sources)
Lalit Magantid7afbb12022-03-28 15:12:24 +0100982
Kean Mariotti487a5392024-04-18 06:58:29 +0000983 for type in module_types:
984 if type == 'filegroup':
985 name = label_to_module_name(module_name) + '_filegroup_proto'
986 module = Module('filegroup', name, name)
987 module.comment = f'''GN: [{', '.join(target_names)}]'''
988 module.srcs = module_sources
989 blueprint.add_module(module)
990 elif type == 'lite':
991 name = label_to_module_name(module_name) + '_java_protos'
992 module = Module('java_library', name, name)
993 module.comment = f'''GN: [{', '.join(target_names)}]'''
994 module.proto = {'type': 'lite', 'canonical_path_from_root': False}
995 module.srcs = module_sources
996 blueprint.add_module(module)
997 else:
998 raise Error('Unhandled proto group type: {}'.format(group.type))
Lalit Magantid7afbb12022-03-28 15:12:24 +0100999
1000
Lalit Maganti921a3d62022-12-17 14:28:50 +00001001def _get_cflags(target: GnParser.Target):
Primiano Tuccia3645202020-08-03 16:28:18 +02001002 cflags = {flag for flag in target.cflags if re.match(cflag_allowlist, flag)}
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001003 cflags |= set("-D%s" % define
1004 for define in target.defines
Primiano Tuccia3645202020-08-03 16:28:18 +02001005 if re.match(define_allowlist, define))
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001006 return cflags
Florian Mayer3d5e7e62018-01-19 15:22:46 +00001007
1008
Lalit Maganti921a3d62022-12-17 14:28:50 +00001009def create_modules_from_target(blueprint: Blueprint, gn: GnParser,
1010 gn_target_name: str) -> Optional[Module]:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001011 """Generate module(s) for a given GN target.
Sami Kyostila865d1d32017-12-12 18:37:04 +00001012
1013 Given a GN target name, generate one or more corresponding modules into a
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001014 blueprint. The only case when this generates >1 module is proto libraries.
Sami Kyostila865d1d32017-12-12 18:37:04 +00001015
1016 Args:
1017 blueprint: Blueprint instance which is being generated.
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001018 gn: gn_utils.GnParser object.
1019 gn_target_name: GN target for module generation.
Sami Kyostila865d1d32017-12-12 18:37:04 +00001020 """
Lalit Maganti27b00af2022-12-17 01:20:38 +00001021 if gn_target_name in blueprint.gn_target_to_module:
1022 return blueprint.gn_target_to_module[gn_target_name]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001023
Lalit Maganti27b00af2022-12-17 01:20:38 +00001024 target = gn.get_target(gn_target_name)
1025 bp_module_name = label_to_module_name(gn_target_name)
Lalit Maganti9c2318c2021-05-20 16:21:41 +01001026 name_without_toolchain = gn_utils.label_without_toolchain(target.name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001027 if target.type == 'executable':
1028 if target.toolchain == gn_utils.HOST_TOOLCHAIN:
1029 module_type = 'cc_binary_host'
1030 elif target.testonly:
1031 module_type = 'cc_test'
Sami Kyostila865d1d32017-12-12 18:37:04 +00001032 else:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001033 module_type = 'cc_binary'
1034 module = Module(module_type, bp_module_name, gn_target_name)
1035 elif target.type == 'static_library':
1036 module = Module('cc_library_static', bp_module_name, gn_target_name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001037 elif target.type == 'shared_library':
1038 module = Module('cc_library_shared', bp_module_name, gn_target_name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001039 elif target.type == 'source_set':
1040 module = Module('filegroup', bp_module_name, gn_target_name)
1041 elif target.type == 'group':
1042 # "group" targets are resolved recursively by gn_utils.get_target().
1043 # There's nothing we need to do at this level for them.
1044 return None
1045 elif target.type == 'proto_library':
1046 module = create_proto_modules(blueprint, gn, target)
Lalit Maganti117272f2020-09-11 14:01:18 +01001047 if module is None:
1048 return None
1049 elif target.type == 'action':
Lalit Maganti358a7e42022-11-09 15:16:21 +00001050 if target.custom_action_type == 'sql_amalgamation':
1051 return create_amalgamated_sql_module(blueprint, gn, target)
Lalit Maganti3dc8e302022-12-01 20:32:46 +00001052 if target.custom_action_type == 'tp_tables':
1053 return create_tp_tables_module(blueprint, gn, target)
Lalit Maganti358a7e42022-11-09 15:16:21 +00001054
Lalit Magantib417ff22022-11-09 15:45:02 +00001055 if target.custom_action_type == 'cc_proto_descriptor':
Lalit Maganti3b09a3f2020-09-14 13:28:44 +01001056 module = create_cc_proto_descriptor_module(blueprint, target)
Lalit Maganti358a7e42022-11-09 15:16:21 +00001057 elif name_without_toolchain == gn_utils.GEN_VERSION_TARGET:
Primiano Tucciec590132020-11-16 14:16:44 +01001058 module = create_gen_version_module(blueprint, target, bp_module_name)
Hector Dearmana1d75242020-10-02 09:47:24 +01001059 else:
1060 raise Error('Unhandled action: {}'.format(target.name))
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001061 else:
1062 raise Error('Unknown target %s (%s)' % (target.name, target.type))
Sami Kyostila865d1d32017-12-12 18:37:04 +00001063
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001064 blueprint.add_module(module)
Lalit Maganti9c2318c2021-05-20 16:21:41 +01001065 module.host_supported = (name_without_toolchain in target_host_supported)
Michael Eastwood6cbbff12021-12-09 15:34:35 -08001066 module.vendor_available = (name_without_toolchain in target_vendor_available)
Nikita Putikhin94e30a02023-11-22 14:16:47 +01001067 module.product_available = (name_without_toolchain in target_product_available)
Lalit Maganti921a3d62022-12-17 14:28:50 +00001068 module.init_rc.update(target_initrc.get(target.name, []))
Spandan Das34f1b982023-10-13 23:24:01 +00001069 if target.type != 'proto_library':
1070 # proto_library embeds a "root" filegroup in its srcs.
1071 # Skip to prevent adding dups
1072 module.srcs.update(
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001073 gn_utils.label_to_path(src)
1074 for src in target.sources
1075 if is_supported_source_file(src))
Primiano Tucci6067e732018-01-08 16:19:40 +00001076
Daniele Di Proiettocb426002023-02-16 12:14:38 +00001077 if name_without_toolchain in needs_libfts:
1078 module.musl.static_libs.add('libfts')
1079
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001080 if target.type in gn_utils.LINKER_UNIT_TYPES:
1081 module.cflags.update(_get_cflags(target))
Sami Kyostila865d1d32017-12-12 18:37:04 +00001082
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001083 module_is_compiled = module.type not in ('genrule', 'filegroup')
1084 if module_is_compiled:
1085 # Don't try to inject library/source dependencies into genrules or
1086 # filegroups because they are not compiled in the traditional sense.
Lalit Maganti921a3d62022-12-17 14:28:50 +00001087 module.defaults.update([defaults_module])
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001088 for lib in target.libs:
1089 # Generally library names should be mangled as 'libXXX', unless they
Yifan Hong0011c632021-12-02 18:37:21 -08001090 # are HAL libraries (e.g., android.hardware.health@2.0) or AIDL c++ / NDK
Raymond Chiu8c4d9a22021-02-23 19:59:10 +00001091 # libraries (e.g. "android.hardware.power.stats-V1-cpp")
Yifan Hong0011c632021-12-02 18:37:21 -08001092 android_lib = lib if '@' in lib or "-cpp" in lib or "-ndk" in lib \
1093 else 'lib' + lib
Primiano Tuccia3645202020-08-03 16:28:18 +02001094 if lib in shared_library_allowlist:
Lalit Magantie0986f32020-09-17 15:35:47 +01001095 module.add_android_shared_lib(android_lib)
Primiano Tuccia3645202020-08-03 16:28:18 +02001096 if lib in static_library_allowlist:
Lalit Magantie0986f32020-09-17 15:35:47 +01001097 module.add_android_static_lib(android_lib)
Lalit Magantic5bcd792018-01-12 18:38:11 +00001098
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001099 # If the module is a static library, export all the generated headers.
1100 if module.type == 'cc_library_static':
1101 module.export_generated_headers = module.generated_headers
Ryan Savitskie65beca2019-01-29 18:29:13 +00001102
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001103 # Merge in additional hardcoded arguments.
1104 for key, add_val in additional_args.get(module.name, []):
1105 curr = getattr(module, key)
1106 if add_val and isinstance(add_val, set) and isinstance(curr, set):
1107 curr.update(add_val)
Lalit Maganticdda9112019-11-27 14:19:49 +00001108 elif isinstance(add_val, str) and (not curr or isinstance(curr, str)):
Lalit Maganti3d415ec2019-10-23 17:53:17 +01001109 setattr(module, key, add_val)
Florian Mayerac4f4962020-09-15 10:03:22 +01001110 elif isinstance(add_val, bool) and (not curr or isinstance(curr, bool)):
1111 setattr(module, key, add_val)
Lalit Maganticdda9112019-11-27 14:19:49 +00001112 elif isinstance(add_val, dict) and isinstance(curr, dict):
1113 curr.update(add_val)
Lalit Magantie0986f32020-09-17 15:35:47 +01001114 elif isinstance(add_val, dict) and isinstance(curr, Target):
1115 curr.__dict__.update(add_val)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001116 else:
Florian Mayer5d09f5e2021-02-19 14:59:49 +00001117 raise Error('Unimplemented type %r of additional_args: %r' %
1118 (type(add_val), key))
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001119
1120 # dep_name is an unmangled GN target name (e.g. //foo:bar(toolchain)).
Lalit Maganti01f9b052022-12-17 01:21:13 +00001121 all_deps = target.non_proto_or_source_set_deps()
1122 all_deps |= target.transitive_source_set_deps()
1123 all_deps |= target.transitive_proto_deps()
1124 for dep in all_deps:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001125 # If the dependency refers to a library which we can replace with an
1126 # Android equivalent, stop recursing and patch the dependency in.
1127 # Don't recurse into //buildtools, builtin_deps are intercepted at
1128 # the //gn:xxx level.
Lalit Maganti01f9b052022-12-17 01:21:13 +00001129 dep_name = dep.name
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001130 if dep_name.startswith('//buildtools'):
1131 continue
1132
1133 # Ignore the dependency on the gen_buildflags genrule. That is run
1134 # separately in this generator and the generated file is copied over
1135 # into the repo (see usage of |buildflags_dir| in this script).
1136 if dep_name.startswith(gn_utils.BUILDFLAGS_TARGET):
1137 continue
1138
1139 dep_module = create_modules_from_target(blueprint, gn, dep_name)
1140
1141 # For filegroups and genrule, recurse but don't apply the deps.
1142 if not module_is_compiled:
1143 continue
1144
1145 # |builtin_deps| override GN deps with Android-specific ones. See the
1146 # config in the top of this file.
1147 if gn_utils.label_without_toolchain(dep_name) in builtin_deps:
1148 builtin_deps[gn_utils.label_without_toolchain(dep_name)](module)
1149 continue
1150
1151 # Don't recurse in any other //gn dep if not handled by builtin_deps.
1152 if dep_name.startswith('//gn:'):
1153 continue
1154
1155 if dep_module is None:
1156 continue
1157 if dep_module.type == 'cc_library_shared':
1158 module.shared_libs.add(dep_module.name)
1159 elif dep_module.type == 'cc_library_static':
1160 module.static_libs.add(dep_module.name)
1161 elif dep_module.type == 'filegroup':
1162 module.srcs.add(':' + dep_module.name)
1163 elif dep_module.type == 'genrule':
1164 module.generated_headers.update(dep_module.genrule_headers)
1165 module.srcs.update(dep_module.genrule_srcs)
1166 module.shared_libs.update(dep_module.genrule_shared_libs)
Primiano Tuccie094eec2020-03-18 16:58:21 +00001167 elif dep_module.type == 'cc_binary':
1168 continue # Ignore executables deps (used by cmdline integration tests).
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001169 else:
1170 raise Error('Unknown dep %s (%s) for target %s' %
1171 (dep_module.name, dep_module.type, module.name))
1172
1173 return module
Sami Kyostila865d1d32017-12-12 18:37:04 +00001174
1175
Lalit Maganti921a3d62022-12-17 14:28:50 +00001176def create_blueprint_for_targets(gn: GnParser, targets: List[str]):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001177 """Generate a blueprint for a list of GN targets."""
1178 blueprint = Blueprint()
Sami Kyostila865d1d32017-12-12 18:37:04 +00001179
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001180 # Default settings used by all modules.
1181 defaults = Module('cc_defaults', defaults_module, '//gn:default_deps')
Sami Kyostila865d1d32017-12-12 18:37:04 +00001182
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001183 # We have to use include_dirs passing the path relative to the android tree.
1184 # This is because: (i) perfetto_cc_defaults is used also by
1185 # test/**/Android.bp; (ii) if we use local_include_dirs instead, paths
1186 # become relative to the Android.bp that *uses* cc_defaults (not the one
1187 # that defines it).s
1188 defaults.include_dirs = {
Florian Mayer5d09f5e2021-02-19 14:59:49 +00001189 tree_path, tree_path + '/include', tree_path + '/' + buildflags_dir,
1190 tree_path + '/src/profiling/memory/include'
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001191 }
Lalit Maganti921a3d62022-12-17 14:28:50 +00001192 defaults.cflags.update([
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001193 '-Wno-error=return-type',
1194 '-Wno-sign-compare',
1195 '-Wno-sign-promo',
1196 '-Wno-unused-parameter',
1197 '-fvisibility=hidden',
1198 '-O2',
Lalit Maganti921a3d62022-12-17 14:28:50 +00001199 ])
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001200 defaults.user_debug_flag = True
1201 defaults.lto = True
Sami Kyostila865d1d32017-12-12 18:37:04 +00001202
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001203 blueprint.add_module(defaults)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001204 for target in targets:
1205 create_modules_from_target(blueprint, gn, target)
1206 return blueprint
Sami Kyostila865d1d32017-12-12 18:37:04 +00001207
1208
1209def main():
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001210 parser = argparse.ArgumentParser(
1211 description='Generate Android.bp from a GN description.')
1212 parser.add_argument(
1213 '--check-only',
1214 help='Don\'t keep the generated files',
1215 action='store_true')
1216 parser.add_argument(
1217 '--desc',
Matthew Clarkson63028d62019-10-10 15:48:23 +01001218 help='GN description (e.g., gn desc out --format=json --all-toolchains "//*"'
1219 )
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001220 parser.add_argument(
1221 '--extras',
1222 help='Extra targets to include at the end of the Blueprint file',
1223 default=os.path.join(gn_utils.repo_root(), 'Android.bp.extras'),
1224 )
1225 parser.add_argument(
1226 '--output',
1227 help='Blueprint file to create',
1228 default=os.path.join(gn_utils.repo_root(), 'Android.bp'),
1229 )
1230 parser.add_argument(
1231 'targets',
1232 nargs=argparse.REMAINDER,
1233 help='Targets to include in the blueprint (e.g., "//:perfetto_tests")')
1234 args = parser.parse_args()
Sami Kyostila865d1d32017-12-12 18:37:04 +00001235
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001236 if args.desc:
1237 with open(args.desc) as f:
1238 desc = json.load(f)
1239 else:
1240 desc = gn_utils.create_build_description(gn_args)
Sami Kyostila865d1d32017-12-12 18:37:04 +00001241
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001242 gn = gn_utils.GnParser(desc)
Lalit Maganti921a3d62022-12-17 14:28:50 +00001243 blueprint = create_blueprint_for_targets(gn, args.targets or default_targets)
Alexander Timin129c37c2021-04-08 19:17:59 +00001244 project_root = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
1245 tool_name = os.path.relpath(os.path.abspath(__file__), project_root)
Primiano Tucci916f4e52020-10-16 20:40:33 +02001246
1247 # TODO(primiano): enable this on Android after the TODO in
1248 # perfetto_component.gni is fixed.
1249 # Check for ODR violations
1250 # for target_name in default_targets:
Lalit Maganti9c2318c2021-05-20 16:21:41 +01001251 # checker = gn_utils.ODRChecker(gn, target_name)
Primiano Tucci916f4e52020-10-16 20:40:33 +02001252
Lalit Magantid7afbb12022-03-28 15:12:24 +01001253 # Add any proto groups to the blueprint.
Kean Mariotti487a5392024-04-18 06:58:29 +00001254 for name, group in proto_groups.items():
1255 create_proto_group_modules(blueprint, gn, name, group)
Lalit Magantid7afbb12022-03-28 15:12:24 +01001256
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001257 output = [
1258 """// Copyright (C) 2017 The Android Open Source Project
Sami Kyostila865d1d32017-12-12 18:37:04 +00001259//
1260// Licensed under the Apache License, Version 2.0 (the "License");
1261// you may not use this file except in compliance with the License.
1262// You may obtain a copy of the License at
1263//
1264// http://www.apache.org/licenses/LICENSE-2.0
1265//
1266// Unless required by applicable law or agreed to in writing, software
1267// distributed under the License is distributed on an "AS IS" BASIS,
1268// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1269// See the License for the specific language governing permissions and
1270// limitations under the License.
1271//
1272// This file is automatically generated by %s. Do not edit.
Alexander Timin129c37c2021-04-08 19:17:59 +00001273""" % (tool_name)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001274 ]
1275 blueprint.to_string(output)
1276 with open(args.extras, 'r') as r:
1277 for line in r:
1278 output.append(line.rstrip("\n\r"))
Primiano Tucci9c411652019-08-27 07:13:59 +02001279
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001280 out_files = []
Primiano Tucci9c411652019-08-27 07:13:59 +02001281
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001282 # Generate the Android.bp file.
1283 out_files.append(args.output + '.swp')
1284 with open(out_files[-1], 'w') as f:
1285 f.write('\n'.join(output))
Florian Mayerbbbd1ff2020-10-23 13:25:13 +01001286 # Text files should have a trailing EOL.
1287 f.write('\n')
Sami Kyostila865d1d32017-12-12 18:37:04 +00001288
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001289 # Generate the perfetto_build_flags.h file.
1290 out_files.append(os.path.join(buildflags_dir, 'perfetto_build_flags.h.swp'))
1291 gn_utils.gen_buildflags(gn_args, out_files[-1])
Sami Kyostila865d1d32017-12-12 18:37:04 +00001292
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001293 # Either check the contents or move the files to their final destination.
1294 return gn_utils.check_or_commit_generated_files(out_files, args.check_only)
Primiano Tucci9c411652019-08-27 07:13:59 +02001295
1296
Sami Kyostila865d1d32017-12-12 18:37:04 +00001297if __name__ == '__main__':
Primiano Tuccif0d7ef82019-10-04 15:35:24 +01001298 sys.exit(main())