blob: 099c384cb89d656357f39cf6a8d5fb7e81a0cc70 [file] [log] [blame]
Sami Kyostila865d1d32017-12-12 18:37:04 +00001#!/usr/bin/env python
2# 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
33
Sami Kyostila3c88a1d2019-05-22 18:29:42 +010034import gn_utils
35
Matthew Clarkson9a5dfa52019-10-03 09:54:04 +010036from compat import itervalues
37
Florian Mayer246c1422019-09-18 15:40:38 +010038ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
39
Sami Kyostilab27619f2017-12-13 19:22:16 +000040# Arguments for the GN output directory.
Primiano Tucci9c411652019-08-27 07:13:59 +020041gn_args = ' '.join([
42 'is_debug=false',
Primiano Tucci7e05fc12019-08-27 17:29:47 +020043 'is_perfetto_build_generator=true',
Primiano Tucci9c411652019-08-27 07:13:59 +020044 'perfetto_build_with_android=true',
45 'target_cpu="arm"',
46 'target_os="android"',
47])
Sami Kyostilab27619f2017-12-13 19:22:16 +000048
Primiano Tucci02c11762019-08-30 00:57:59 +020049# Default targets to translate to the blueprint file.
50default_targets = [
51 '//:libperfetto_client_experimental',
52 '//:libperfetto',
53 '//:perfetto_integrationtests',
54 '//:perfetto_unittests',
55 '//protos/perfetto/trace:perfetto_trace_protos',
56 '//src/android_internal:libperfetto_android_internal',
57 '//src/perfetto_cmd:perfetto',
58 '//src/perfetto_cmd:trigger_perfetto',
59 '//src/profiling/memory:heapprofd_client',
60 '//src/profiling/memory:heapprofd',
Ryan Savitski462b5db2019-11-20 19:06:46 +000061 '//src/profiling/perf:traced_perf',
Primiano Tucci02c11762019-08-30 00:57:59 +020062 '//src/traced/probes:traced_probes',
63 '//src/traced/service:traced',
Primiano Tuccifbf4a732019-12-11 00:32:15 +000064 '//test/cts:perfetto_cts_deps',
Lalit Maganti9782f492020-01-10 18:13:13 +000065 '//test/cts:perfetto_cts_jni_deps',
Primiano Tuccicbbe4802020-02-20 13:19:11 +000066 '//test:perfetto_gtest_logcat_printer',
Primiano Tuccif0d7ef82019-10-04 15:35:24 +010067]
68
69# Host targets
70ipc_plugin = '//src/ipc/protoc_plugin:ipc_plugin(%s)' % gn_utils.HOST_TOOLCHAIN
71protozero_plugin = '//src/protozero/protoc_plugin:protozero_plugin(%s)' % (
72 gn_utils.HOST_TOOLCHAIN)
Primiano Tucci57dd66b2019-10-15 23:09:04 +010073cppgen_plugin = '//src/protozero/protoc_plugin:cppgen_plugin(%s)' % (
74 gn_utils.HOST_TOOLCHAIN)
75
Primiano Tuccif0d7ef82019-10-04 15:35:24 +010076default_targets += [
77 '//src/trace_processor:trace_processor_shell(%s)' % gn_utils.HOST_TOOLCHAIN,
78 '//tools/trace_to_text:trace_to_text(%s)' % gn_utils.HOST_TOOLCHAIN,
79 protozero_plugin,
80 ipc_plugin,
Primiano Tucci02c11762019-08-30 00:57:59 +020081]
82
Primiano Tucci02c11762019-08-30 00:57:59 +020083# Defines a custom init_rc argument to be applied to the corresponding output
84# blueprint target.
85target_initrc = {
Primiano Tuccif0d7ef82019-10-04 15:35:24 +010086 '//src/traced/service:traced': {'perfetto.rc'},
87 '//src/profiling/memory:heapprofd': {'heapprofd.rc'},
Ryan Savitski29082bf2020-02-12 15:13:51 +000088 '//src/profiling/perf:traced_perf': {'traced_perf.rc'},
Primiano Tucci02c11762019-08-30 00:57:59 +020089}
90
91target_host_supported = [
92 '//protos/perfetto/trace:perfetto_trace_protos',
Hector Dearman04cfac72019-09-24 22:05:55 +010093 '//:libperfetto',
Primiano Tucci02c11762019-08-30 00:57:59 +020094]
95
Sami Kyostila865d1d32017-12-12 18:37:04 +000096# All module names are prefixed with this string to avoid collisions.
97module_prefix = 'perfetto_'
98
99# Shared libraries which are directly translated to Android system equivalents.
Hector Dearman92d7d112019-12-05 15:19:57 +0000100shared_library_whitelist = [
Hector Dearman64f2e052019-12-04 20:51:14 +0000101 'android',
Hector Dearman92d7d112019-12-05 15:19:57 +0000102 'android.hardware.atrace@1.0',
103 'android.hardware.health@2.0',
104 'android.hardware.power.stats@1.0',
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100105 'base',
Sami Kyostilab5b71692018-01-12 12:16:44 +0000106 'binder',
Hector Dearman92d7d112019-12-05 15:19:57 +0000107 'cutils',
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100108 'hidlbase',
109 'hidltransport',
110 'hwbinder',
Ryan Savitski53ca60b2019-06-03 13:04:40 +0100111 'incident',
Sami Kyostila865d1d32017-12-12 18:37:04 +0000112 'log',
Sami Kyostilab5b71692018-01-12 12:16:44 +0000113 'services',
Hector Dearman92d7d112019-12-05 15:19:57 +0000114 'statssocket',
Primiano Tucciedf099c2018-01-08 18:27:56 +0000115 'utils',
Sami Kyostila865d1d32017-12-12 18:37:04 +0000116]
117
Hector Dearman92d7d112019-12-05 15:19:57 +0000118# Static libraries which are directly translated to Android system equivalents.
119static_library_whitelist = [
120 'statslog_perfetto',
121]
122
Sami Kyostila865d1d32017-12-12 18:37:04 +0000123# Name of the module which settings such as compiler flags for all other
124# modules.
125defaults_module = module_prefix + 'defaults'
126
127# Location of the project in the Android source tree.
128tree_path = 'external/perfetto'
129
Primiano Tucciedf099c2018-01-08 18:27:56 +0000130# Compiler flags which are passed through to the blueprint.
131cflag_whitelist = r'^-DPERFETTO.*$'
132
Florian Mayer3d5e7e62018-01-19 15:22:46 +0000133# Compiler defines which are passed through to the blueprint.
Primiano Tucci8e627442019-08-28 07:58:38 +0200134define_whitelist = r'^(GOOGLE_PROTO.*)|(ZLIB_.*)|(USE_MMAP)|(HAVE_HIDDEN)$'
Florian Mayer3d5e7e62018-01-19 15:22:46 +0000135
Logan Chien9bfaaf92018-02-13 18:49:24 +0800136# Shared libraries which are not in PDK.
137library_not_in_pdk = {
138 'libandroid',
139 'libservices',
140}
141
Primiano Tucci8e627442019-08-28 07:58:38 +0200142# The directory where the generated perfetto_build_flags.h will be copied into.
143buildflags_dir = 'include/perfetto/base/build_configs/android_tree'
144
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100145
146def enumerate_data_deps():
147 with open(os.path.join(ROOT_DIR, 'tools', 'test_data.txt')) as f:
148 lines = f.readlines()
149 for line in (line.strip() for line in lines if not line.startswith('#')):
Andrew Shulaev576054d2020-01-23 13:44:51 +0000150 assert os.path.exists(line), 'file %s should exist' % line
Primiano Tucci02691162020-01-21 13:30:13 +0000151 if line.startswith('test/data/'):
152 # Skip test data files that require GCS. They are only for benchmarks.
153 # We don't run benchmarks in the android tree.
154 continue
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100155 if line.endswith('/'):
156 yield line + '**/*'
157 else:
158 yield line
159
160
Florian Mayerb6a921f2018-10-18 18:55:23 +0100161# Additional arguments to apply to Android.bp rules.
162additional_args = {
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100163 'heapprofd_client': [
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100164 ('include_dirs', {'bionic/libc'}),
165 ('static_libs', {'libasync_safe'}),
166 ('header_libs', {'bionic_libc_platform_headers'}),
Primiano Tucci676f0cc2018-12-03 20:03:26 +0100167 ],
Ryan Savitski703bcab2019-12-18 14:38:14 +0000168 'perfetto_unittests': [
169 ('data', set(enumerate_data_deps())),
170 ('include_dirs', {'bionic/libc/kernel'}),
171 ],
Matthew Clarkson63028d62019-10-10 15:48:23 +0100172 'traced_probes': [
Ryan Savitski29082bf2020-02-12 15:13:51 +0000173 ('required', {'libperfetto_android_internal',
174 'trigger_perfetto',
175 'traced_perf'}),
Matthew Clarkson63028d62019-10-10 15:48:23 +0100176 ],
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100177 'libperfetto_android_internal': [('static_libs', {'libhealthhalutils'}),],
Lalit Maganticdda9112019-11-27 14:19:49 +0000178 'trace_processor_shell': [
Lalit Maganticdda9112019-11-27 14:19:49 +0000179 ('stl', 'libc++_static'),
180 ],
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900181 'libperfetto_client_experimental': [
182 ('apex_available', {
183 '//apex_available:platform',
184 'com.android.art.debug',
185 'com.android.art.release'}),
186 ],
187 'perfetto_trace_protos': [
188 ('apex_available', {
189 '//apex_available:platform',
190 'com.android.art.debug',
191 'com.android.art.release'}),
192 ],
Florian Mayerb6a921f2018-10-18 18:55:23 +0100193}
194
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100195
Primiano Tuccifbf4a732019-12-11 00:32:15 +0000196def enable_gtest_and_gmock(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100197 module.static_libs.add('libgmock')
Primiano Tuccifbf4a732019-12-11 00:32:15 +0000198 module.static_libs.add('libgtest')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000199 if module.name != 'perfetto_gtest_logcat_printer':
200 module.whole_static_libs.add('perfetto_gtest_logcat_printer')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100201
Sami Kyostila865d1d32017-12-12 18:37:04 +0000202
Sami Kyostila865d1d32017-12-12 18:37:04 +0000203def enable_protobuf_full(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100204 module.shared_libs.add('libprotobuf-cpp-full')
205
Sami Kyostila865d1d32017-12-12 18:37:04 +0000206
Sami Kyostila865d1d32017-12-12 18:37:04 +0000207def enable_protobuf_lite(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100208 module.shared_libs.add('libprotobuf-cpp-lite')
209
Sami Kyostila865d1d32017-12-12 18:37:04 +0000210
Sami Kyostila865d1d32017-12-12 18:37:04 +0000211def enable_protoc_lib(module):
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100212 if module.type == 'cc_binary_host':
213 module.static_libs.add('libprotoc')
214 else:
215 module.shared_libs.add('libprotoc')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100216
Sami Kyostila865d1d32017-12-12 18:37:04 +0000217
Florian Mayera2fae262018-08-31 12:10:01 -0700218def enable_libunwindstack(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100219 module.shared_libs.add('libunwindstack')
220 module.shared_libs.add('libprocinfo')
221 module.shared_libs.add('libbase')
222
Sami Kyostila865d1d32017-12-12 18:37:04 +0000223
224def enable_libunwind(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100225 # libunwind is disabled on Darwin so we cannot depend on it.
226 pass
227
Sami Kyostila865d1d32017-12-12 18:37:04 +0000228
Lalit Maganti17aa2732019-02-08 15:47:26 +0000229def enable_sqlite(module):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100230 if module.type == 'cc_binary_host':
231 module.static_libs.add('libsqlite')
232 else:
233 # Copy what the sqlite3 command line tool does.
234 module.android.shared_libs.add('libsqlite')
235 module.android.shared_libs.add('libandroidicu')
236 module.android.shared_libs.add('liblog')
237 module.android.shared_libs.add('libutils')
238 module.host.static_libs.add('libsqlite')
239
Lalit Maganti17aa2732019-02-08 15:47:26 +0000240
Hector Dearmane0b993f2019-05-24 18:48:16 +0100241def enable_zlib(module):
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100242 if module.type == 'cc_binary_host':
243 module.static_libs.add('libz')
244 else:
245 module.shared_libs.add('libz')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100246
Hector Dearmane0b993f2019-05-24 18:48:16 +0100247
Ryan Savitski56bc0c62020-01-27 13:50:02 +0000248def enable_uapi_headers(module):
249 module.include_dirs.add('bionic/libc/kernel')
250
251
Sami Kyostila865d1d32017-12-12 18:37:04 +0000252# Android equivalents for third-party libraries that the upstream project
253# depends on.
254builtin_deps = {
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100255 '//gn:default_deps': lambda x: None,
256 '//gn:gtest_main': lambda x: None,
257 '//gn:protoc': lambda x: None,
Primiano Tuccifbf4a732019-12-11 00:32:15 +0000258 '//gn:gtest_and_gmock': enable_gtest_and_gmock,
Primiano Tuccib7ebffd2019-09-09 07:42:35 -0700259 '//gn:libunwind': enable_libunwind,
260 '//gn:protobuf_full': enable_protobuf_full,
261 '//gn:protobuf_lite': enable_protobuf_lite,
262 '//gn:protoc_lib': enable_protoc_lib,
263 '//gn:libunwindstack': enable_libunwindstack,
264 '//gn:sqlite': enable_sqlite,
265 '//gn:zlib': enable_zlib,
Ryan Savitski56bc0c62020-01-27 13:50:02 +0000266 '//gn:bionic_kernel_uapi_headers' : enable_uapi_headers,
Sami Kyostila865d1d32017-12-12 18:37:04 +0000267}
268
269# ----------------------------------------------------------------------------
270# End of configuration.
271# ----------------------------------------------------------------------------
272
273
274class Error(Exception):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100275 pass
Sami Kyostila865d1d32017-12-12 18:37:04 +0000276
277
278class ThrowingArgumentParser(argparse.ArgumentParser):
Sami Kyostila865d1d32017-12-12 18:37:04 +0000279
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100280 def __init__(self, context):
281 super(ThrowingArgumentParser, self).__init__()
282 self.context = context
283
284 def error(self, message):
285 raise Error('%s: %s' % (self.context, message))
Sami Kyostila865d1d32017-12-12 18:37:04 +0000286
287
Lalit Magantiedace412019-06-18 13:28:28 +0100288def write_blueprint_key_value(output, name, value, sort=True):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100289 """Writes a Blueprint key-value pair to the output"""
Lalit Magantiedace412019-06-18 13:28:28 +0100290
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100291 if not value:
292 return
293 if isinstance(value, set):
294 value = sorted(value)
295 if isinstance(value, list):
296 output.append(' %s: [' % name)
297 for item in sorted(value) if sort else value:
298 output.append(' "%s",' % item)
299 output.append(' ],')
300 return
301 if isinstance(value, bool):
302 output.append(' %s: true,' % name)
303 return
304 if isinstance(value, Target):
305 value.to_string(output)
306 return
Lalit Maganticdda9112019-11-27 14:19:49 +0000307 if isinstance(value, dict):
308 kv_output = []
309 for k, v in value.items():
310 write_blueprint_key_value(kv_output, k, v)
311
312 output.append(' %s: {' % name)
313 for line in kv_output:
314 output.append(' %s' % line)
315 output.append(' },')
316 return
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100317 output.append(' %s: "%s",' % (name, value))
318
Lalit Magantiedace412019-06-18 13:28:28 +0100319
320class Target(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100321 """A target-scoped part of a module"""
Lalit Magantiedace412019-06-18 13:28:28 +0100322
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100323 def __init__(self, name):
324 self.name = name
325 self.shared_libs = set()
326 self.static_libs = set()
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000327 self.whole_static_libs = set()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100328 self.cflags = set()
Lalit Magantiedace412019-06-18 13:28:28 +0100329
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100330 def to_string(self, output):
331 nested_out = []
332 self._output_field(nested_out, 'shared_libs')
333 self._output_field(nested_out, 'static_libs')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000334 self._output_field(nested_out, 'whole_static_libs')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100335 self._output_field(nested_out, 'cflags')
Lalit Magantiedace412019-06-18 13:28:28 +0100336
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100337 if nested_out:
338 output.append(' %s: {' % self.name)
339 for line in nested_out:
340 output.append(' %s' % line)
341 output.append(' },')
Lalit Magantiedace412019-06-18 13:28:28 +0100342
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100343 def _output_field(self, output, name, sort=True):
344 value = getattr(self, name)
345 return write_blueprint_key_value(output, name, value, sort)
346
Lalit Magantiedace412019-06-18 13:28:28 +0100347
Sami Kyostila865d1d32017-12-12 18:37:04 +0000348class Module(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100349 """A single module (e.g., cc_binary, cc_test) in a blueprint."""
Sami Kyostila865d1d32017-12-12 18:37:04 +0000350
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100351 def __init__(self, mod_type, name, gn_target):
352 self.type = mod_type
353 self.gn_target = gn_target
354 self.name = name
355 self.srcs = set()
356 self.comment = 'GN: ' + gn_utils.label_without_toolchain(gn_target)
357 self.shared_libs = set()
358 self.static_libs = set()
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000359 self.whole_static_libs = set()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100360 self.tools = set()
361 self.cmd = None
362 self.host_supported = False
363 self.init_rc = set()
364 self.out = set()
365 self.export_include_dirs = set()
366 self.generated_headers = set()
367 self.export_generated_headers = set()
368 self.defaults = set()
369 self.cflags = set()
370 self.include_dirs = set()
371 self.header_libs = set()
372 self.required = set()
373 self.user_debug_flag = False
374 self.tool_files = None
375 self.android = Target('android')
376 self.host = Target('host')
377 self.lto = None
Lalit Maganticdda9112019-11-27 14:19:49 +0000378 self.stl = None
379 self.dist = dict()
Lalit Magantiaccd64b2020-03-16 19:54:10 +0000380 self.strip = dict()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100381 self.data = set()
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900382 self.apex_available = set()
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100383 # The genrule_XXX below are properties that must to be propagated back
384 # on the module(s) that depend on the genrule.
385 self.genrule_headers = set()
386 self.genrule_srcs = set()
387 self.genrule_shared_libs = set()
Sami Kyostila865d1d32017-12-12 18:37:04 +0000388
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100389 def to_string(self, output):
390 if self.comment:
391 output.append('// %s' % self.comment)
392 output.append('%s {' % self.type)
393 self._output_field(output, 'name')
394 self._output_field(output, 'srcs')
395 self._output_field(output, 'shared_libs')
396 self._output_field(output, 'static_libs')
Primiano Tuccicbbe4802020-02-20 13:19:11 +0000397 self._output_field(output, 'whole_static_libs')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100398 self._output_field(output, 'tools')
399 self._output_field(output, 'cmd', sort=False)
400 self._output_field(output, 'host_supported')
401 self._output_field(output, 'init_rc')
402 self._output_field(output, 'out')
403 self._output_field(output, 'export_include_dirs')
404 self._output_field(output, 'generated_headers')
405 self._output_field(output, 'export_generated_headers')
406 self._output_field(output, 'defaults')
407 self._output_field(output, 'cflags')
408 self._output_field(output, 'include_dirs')
409 self._output_field(output, 'header_libs')
410 self._output_field(output, 'required')
Lalit Maganticdda9112019-11-27 14:19:49 +0000411 self._output_field(output, 'dist')
Lalit Magantiaccd64b2020-03-16 19:54:10 +0000412 self._output_field(output, 'strip')
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100413 self._output_field(output, 'tool_files')
414 self._output_field(output, 'data')
Lalit Maganticdda9112019-11-27 14:19:49 +0000415 self._output_field(output, 'stl')
Jiyong Parkd5ea0112020-04-28 18:22:00 +0900416 self._output_field(output, 'apex_available')
Lalit Magantid8b1a1d2018-05-23 14:41:43 +0100417
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100418 target_out = []
419 self._output_field(target_out, 'android')
420 self._output_field(target_out, 'host')
421 if target_out:
422 output.append(' target: {')
423 for line in target_out:
424 output.append(' %s' % line)
425 output.append(' },')
Lalit Magantiedace412019-06-18 13:28:28 +0100426
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100427 disable_pdk = any(name in library_not_in_pdk for name in self.shared_libs)
428 if self.user_debug_flag or disable_pdk:
429 output.append(' product_variables: {')
430 if disable_pdk:
431 output.append(' pdk: {')
432 output.append(' enabled: false,')
433 output.append(' },')
434 if self.user_debug_flag:
435 output.append(' debuggable: {')
436 output.append(
437 ' cflags: ["-DPERFETTO_BUILD_WITH_ANDROID_USERDEBUG"],')
438 output.append(' },')
439 output.append(' },')
440 if self.lto is not None:
441 output.append(' target: {')
442 output.append(' android: {')
443 output.append(' lto: {')
444 output.append(' thin: %s,' % 'true' if self.lto else 'false')
445 output.append(' },')
446 output.append(' },')
447 output.append(' },')
448 output.append('}')
449 output.append('')
Sami Kyostila865d1d32017-12-12 18:37:04 +0000450
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100451 def _output_field(self, output, name, sort=True):
452 value = getattr(self, name)
453 return write_blueprint_key_value(output, name, value, sort)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000454
455
456class Blueprint(object):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100457 """In-memory representation of an Android.bp file."""
Sami Kyostila865d1d32017-12-12 18:37:04 +0000458
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100459 def __init__(self):
460 self.modules = {}
Sami Kyostila865d1d32017-12-12 18:37:04 +0000461
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100462 def add_module(self, module):
463 """Adds a new module to the blueprint, replacing any existing module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000464 with the same name.
465
466 Args:
467 module: Module instance.
468 """
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100469 self.modules[module.name] = module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000470
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100471 def to_string(self, output):
472 for m in sorted(itervalues(self.modules), key=lambda m: m.name):
473 m.to_string(output)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000474
475
Sami Kyostila865d1d32017-12-12 18:37:04 +0000476def label_to_module_name(label):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100477 """Turn a GN label (e.g., //:perfetto_tests) into a module name."""
478 # If the label is explicibly listed in the default target list, don't prefix
479 # its name and return just the target name. This is so tools like
480 # "trace_to_text" stay as such in the Android tree.
481 label_without_toolchain = gn_utils.label_without_toolchain(label)
482 if label in default_targets or label_without_toolchain in default_targets:
483 return label_without_toolchain.split(':')[-1]
Primiano Tucci02c11762019-08-30 00:57:59 +0200484
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100485 module = re.sub(r'^//:?', '', label_without_toolchain)
486 module = re.sub(r'[^a-zA-Z0-9_]', '_', module)
487 if not module.startswith(module_prefix):
488 return module_prefix + module
489 return module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000490
491
Sami Kyostila865d1d32017-12-12 18:37:04 +0000492def is_supported_source_file(name):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100493 """Returns True if |name| can appear in a 'srcs' list."""
494 return os.path.splitext(name)[1] in ['.c', '.cc', '.proto']
Sami Kyostila865d1d32017-12-12 18:37:04 +0000495
496
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100497def create_proto_modules(blueprint, gn, target):
498 """Generate genrules for a proto GN target.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000499
500 GN actions are used to dynamically generate files during the build. The
501 Soong equivalent is a genrule. This function turns a specific kind of
502 genrule which turns .proto files into source and header files into a pair
Sami Kyostila71625d72017-12-18 10:29:49 +0000503 equivalent genrules.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000504
505 Args:
506 blueprint: Blueprint instance which is being generated.
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100507 target: gn_utils.Target object.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000508
509 Returns:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100510 The source_genrule module.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000511 """
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100512 assert (target.type == 'proto_library')
513 cpp_out_dir = '$(genDir)/%s/' % tree_path
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000514 cmd = ['mkdir -p %s &&' % cpp_out_dir, '$(location aprotoc)']
Sami Kyostila865d1d32017-12-12 18:37:04 +0000515
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100516 # We create two genrules for each proto target: one for the headers and
517 # another for the sources. This is because the module that depends on the
518 # generated files needs to declare two different types of dependencies --
519 # source files in 'srcs' and headers in 'generated_headers' -- and it's not
520 # valid to generate .h files from a source dependency and vice versa.
521 source_module_name = label_to_module_name(target.name) + '_gen'
522 source_module = Module('genrule', source_module_name, target.name)
523 blueprint.add_module(source_module)
524 source_module.srcs.update(
525 gn_utils.label_to_path(src) for src in target.sources)
526 tools = {'aprotoc'}
Primiano Tucci20b760c2018-01-19 12:36:12 +0000527
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100528 header_module = Module('genrule', source_module_name + '_headers',
529 target.name)
530 blueprint.add_module(header_module)
531 header_module.srcs = set(source_module.srcs)
Primiano Tucci20b760c2018-01-19 12:36:12 +0000532
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100533 # TODO(primiano): at some point we should remove this. This was introduced
534 # by aosp/1108421 when adding "protos/" to .proto include paths, in order to
535 # avoid doing multi-repo changes and allow old clients in the android tree
536 # to still do the old #include "perfetto/..." rather than
537 # #include "protos/perfetto/...".
538 header_module.export_include_dirs = {'.', 'protos'}
Sami Kyostila865d1d32017-12-12 18:37:04 +0000539
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100540 source_module.genrule_srcs.add(':' + source_module.name)
541 source_module.genrule_headers.add(header_module.name)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000542
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100543 # In GN builds the proto path is always relative to the output directory
544 # (out/tmp.xxx).
545 cmd += ['--proto_path=%s' % tree_path]
Primiano Tucci355b8c82019-08-29 08:37:51 +0200546
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100547 if target.proto_plugin == 'proto':
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000548 suffixes = ['pb']
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100549 source_module.genrule_shared_libs.add('libprotobuf-cpp-lite')
Primiano Tucci7b6a7882020-01-20 22:34:31 +0000550 cmd += ['--cpp_out=lite=true:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100551 elif target.proto_plugin == 'protozero':
552 suffixes = ['pbzero']
553 plugin = create_modules_from_target(blueprint, gn, protozero_plugin)
554 tools.add(plugin.name)
555 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
556 cmd += ['--plugin_out=wrapper_namespace=pbzero:' + cpp_out_dir]
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100557 elif target.proto_plugin == 'cppgen':
558 suffixes = ['gen']
559 plugin = create_modules_from_target(blueprint, gn, cppgen_plugin)
560 tools.add(plugin.name)
561 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
Primiano Tuccie8020f92019-11-26 13:24:01 +0000562 cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100563 elif target.proto_plugin == 'ipc':
Primiano Tucci3aa027d2019-11-22 21:43:43 +0000564 suffixes = ['ipc']
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100565 plugin = create_modules_from_target(blueprint, gn, ipc_plugin)
566 tools.add(plugin.name)
567 cmd += ['--plugin=protoc-gen-plugin=$(location %s)' % plugin.name]
Primiano Tuccie8020f92019-11-26 13:24:01 +0000568 cmd += ['--plugin_out=wrapper_namespace=gen:' + cpp_out_dir]
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100569 else:
570 raise Error('Unsupported proto plugin: %s' % target.proto_plugin)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000571
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100572 cmd += ['$(in)']
573 source_module.cmd = ' '.join(cmd)
574 header_module.cmd = source_module.cmd
575 source_module.tools = tools
576 header_module.tools = tools
Primiano Tucci20b760c2018-01-19 12:36:12 +0000577
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100578 for sfx in suffixes:
Matthew Clarkson63028d62019-10-10 15:48:23 +0100579 source_module.out.update('%s/%s' %
580 (tree_path, src.replace('.proto', '.%s.cc' % sfx))
581 for src in source_module.srcs)
582 header_module.out.update('%s/%s' %
583 (tree_path, src.replace('.proto', '.%s.h' % sfx))
584 for src in header_module.srcs)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100585 return source_module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000586
Sami Kyostila3c88a1d2019-05-22 18:29:42 +0100587
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100588def create_merged_sql_metrics_module(blueprint, target):
589 module = Module('genrule', 'gen_merged_sql_metrics',
590 '//src/trace_processor/metrics:gen_merged_sql_metrics')
591 module.genrule_headers.add('gen_merged_sql_metrics')
592 module.tool_files = [
593 'tools/gen_merged_sql_metrics.py',
594 ]
595 module.cmd = ' '.join([
596 '$(location tools/gen_merged_sql_metrics.py)',
597 '--cpp_out=$(out)',
598 '$(in)',
599 ])
600 module.out.update(target.outputs)
601 module.srcs.update(gn_utils.label_to_path(src) for src in target.inputs)
602 blueprint.add_module(module)
603 return module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000604
Sami Kyostila3c88a1d2019-05-22 18:29:42 +0100605
Florian Mayer3d5e7e62018-01-19 15:22:46 +0000606def _get_cflags(target):
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100607 cflags = {flag for flag in target.cflags if re.match(cflag_whitelist, flag)}
608 cflags |= set("-D%s" % define
609 for define in target.defines
610 if re.match(define_whitelist, define))
611 return cflags
Florian Mayer3d5e7e62018-01-19 15:22:46 +0000612
613
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100614def create_modules_from_target(blueprint, gn, gn_target_name):
615 """Generate module(s) for a given GN target.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000616
617 Given a GN target name, generate one or more corresponding modules into a
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100618 blueprint. The only case when this generates >1 module is proto libraries.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000619
620 Args:
621 blueprint: Blueprint instance which is being generated.
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100622 gn: gn_utils.GnParser object.
623 gn_target_name: GN target for module generation.
Sami Kyostila865d1d32017-12-12 18:37:04 +0000624 """
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100625 bp_module_name = label_to_module_name(gn_target_name)
626 if bp_module_name in blueprint.modules:
627 return blueprint.modules[bp_module_name]
628 target = gn.get_target(gn_target_name)
629 export_include_dirs = {'include', buildflags_dir}
630
631 if target.type == 'executable':
632 if target.toolchain == gn_utils.HOST_TOOLCHAIN:
633 module_type = 'cc_binary_host'
634 elif target.testonly:
635 module_type = 'cc_test'
Sami Kyostila865d1d32017-12-12 18:37:04 +0000636 else:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100637 module_type = 'cc_binary'
638 module = Module(module_type, bp_module_name, gn_target_name)
639 elif target.type == 'static_library':
640 module = Module('cc_library_static', bp_module_name, gn_target_name)
641 module.export_include_dirs = export_include_dirs
642 elif target.type == 'shared_library':
643 module = Module('cc_library_shared', bp_module_name, gn_target_name)
644 module.export_include_dirs = export_include_dirs
645 elif target.type == 'source_set':
646 module = Module('filegroup', bp_module_name, gn_target_name)
647 elif target.type == 'group':
648 # "group" targets are resolved recursively by gn_utils.get_target().
649 # There's nothing we need to do at this level for them.
650 return None
651 elif target.type == 'proto_library':
652 module = create_proto_modules(blueprint, gn, target)
653 elif target.type == 'action' and 'gen_merged_sql_metrics' in target.name:
654 module = create_merged_sql_metrics_module(blueprint, target)
655 else:
656 raise Error('Unknown target %s (%s)' % (target.name, target.type))
Sami Kyostila865d1d32017-12-12 18:37:04 +0000657
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100658 blueprint.add_module(module)
659 module.host_supported = target.name in target_host_supported
660 module.init_rc = target_initrc.get(target.name, [])
661 module.srcs.update(
662 gn_utils.label_to_path(src)
663 for src in target.sources
664 if is_supported_source_file(src))
Primiano Tucci6067e732018-01-08 16:19:40 +0000665
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100666 if target.type in gn_utils.LINKER_UNIT_TYPES:
667 module.cflags.update(_get_cflags(target))
Sami Kyostila865d1d32017-12-12 18:37:04 +0000668
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100669 module_is_compiled = module.type not in ('genrule', 'filegroup')
670 if module_is_compiled:
671 # Don't try to inject library/source dependencies into genrules or
672 # filegroups because they are not compiled in the traditional sense.
673 module.defaults = [defaults_module]
674 for lib in target.libs:
675 # Generally library names should be mangled as 'libXXX', unless they
676 # are HAL libraries (e.g., android.hardware.health@2.0).
677 android_lib = lib if '@' in lib else 'lib' + lib
Hector Dearman92d7d112019-12-05 15:19:57 +0000678 if lib in shared_library_whitelist:
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100679 module.shared_libs.add(android_lib)
Hector Dearman92d7d112019-12-05 15:19:57 +0000680 if lib in static_library_whitelist:
681 module.static_libs.add(android_lib)
Lalit Magantic5bcd792018-01-12 18:38:11 +0000682
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100683 # If the module is a static library, export all the generated headers.
684 if module.type == 'cc_library_static':
685 module.export_generated_headers = module.generated_headers
Ryan Savitskie65beca2019-01-29 18:29:13 +0000686
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100687 # Merge in additional hardcoded arguments.
688 for key, add_val in additional_args.get(module.name, []):
689 curr = getattr(module, key)
690 if add_val and isinstance(add_val, set) and isinstance(curr, set):
691 curr.update(add_val)
Lalit Maganticdda9112019-11-27 14:19:49 +0000692 elif isinstance(add_val, str) and (not curr or isinstance(curr, str)):
Lalit Maganti3d415ec2019-10-23 17:53:17 +0100693 setattr(module, key, add_val)
Lalit Maganticdda9112019-11-27 14:19:49 +0000694 elif isinstance(add_val, dict) and isinstance(curr, dict):
695 curr.update(add_val)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100696 else:
697 raise Error('Unimplemented type of additional_args: %r' % key)
698
699 # dep_name is an unmangled GN target name (e.g. //foo:bar(toolchain)).
700 for dep_name in target.deps | target.source_set_deps | target.proto_deps:
701 # If the dependency refers to a library which we can replace with an
702 # Android equivalent, stop recursing and patch the dependency in.
703 # Don't recurse into //buildtools, builtin_deps are intercepted at
704 # the //gn:xxx level.
705 if dep_name.startswith('//buildtools'):
706 continue
707
708 # Ignore the dependency on the gen_buildflags genrule. That is run
709 # separately in this generator and the generated file is copied over
710 # into the repo (see usage of |buildflags_dir| in this script).
711 if dep_name.startswith(gn_utils.BUILDFLAGS_TARGET):
712 continue
713
714 dep_module = create_modules_from_target(blueprint, gn, dep_name)
715
716 # For filegroups and genrule, recurse but don't apply the deps.
717 if not module_is_compiled:
718 continue
719
720 # |builtin_deps| override GN deps with Android-specific ones. See the
721 # config in the top of this file.
722 if gn_utils.label_without_toolchain(dep_name) in builtin_deps:
723 builtin_deps[gn_utils.label_without_toolchain(dep_name)](module)
724 continue
725
726 # Don't recurse in any other //gn dep if not handled by builtin_deps.
727 if dep_name.startswith('//gn:'):
728 continue
729
730 if dep_module is None:
731 continue
732 if dep_module.type == 'cc_library_shared':
733 module.shared_libs.add(dep_module.name)
734 elif dep_module.type == 'cc_library_static':
735 module.static_libs.add(dep_module.name)
736 elif dep_module.type == 'filegroup':
737 module.srcs.add(':' + dep_module.name)
738 elif dep_module.type == 'genrule':
739 module.generated_headers.update(dep_module.genrule_headers)
740 module.srcs.update(dep_module.genrule_srcs)
741 module.shared_libs.update(dep_module.genrule_shared_libs)
Primiano Tuccie094eec2020-03-18 16:58:21 +0000742 elif dep_module.type == 'cc_binary':
743 continue # Ignore executables deps (used by cmdline integration tests).
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100744 else:
745 raise Error('Unknown dep %s (%s) for target %s' %
746 (dep_module.name, dep_module.type, module.name))
747
748 return module
Sami Kyostila865d1d32017-12-12 18:37:04 +0000749
750
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100751def create_blueprint_for_targets(gn, desc, targets):
752 """Generate a blueprint for a list of GN targets."""
753 blueprint = Blueprint()
Sami Kyostila865d1d32017-12-12 18:37:04 +0000754
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100755 # Default settings used by all modules.
756 defaults = Module('cc_defaults', defaults_module, '//gn:default_deps')
Sami Kyostila865d1d32017-12-12 18:37:04 +0000757
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100758 # We have to use include_dirs passing the path relative to the android tree.
759 # This is because: (i) perfetto_cc_defaults is used also by
760 # test/**/Android.bp; (ii) if we use local_include_dirs instead, paths
761 # become relative to the Android.bp that *uses* cc_defaults (not the one
762 # that defines it).s
763 defaults.include_dirs = {
764 tree_path, tree_path + '/include', tree_path + '/' + buildflags_dir
765 }
766 defaults.cflags = [
767 '-Wno-error=return-type',
768 '-Wno-sign-compare',
769 '-Wno-sign-promo',
770 '-Wno-unused-parameter',
771 '-fvisibility=hidden',
772 '-O2',
773 ]
774 defaults.user_debug_flag = True
775 defaults.lto = True
Sami Kyostila865d1d32017-12-12 18:37:04 +0000776
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100777 blueprint.add_module(defaults)
778 gn = gn_utils.GnParser(desc)
779 for target in targets:
780 create_modules_from_target(blueprint, gn, target)
781 return blueprint
Sami Kyostila865d1d32017-12-12 18:37:04 +0000782
783
784def main():
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100785 parser = argparse.ArgumentParser(
786 description='Generate Android.bp from a GN description.')
787 parser.add_argument(
788 '--check-only',
789 help='Don\'t keep the generated files',
790 action='store_true')
791 parser.add_argument(
792 '--desc',
Matthew Clarkson63028d62019-10-10 15:48:23 +0100793 help='GN description (e.g., gn desc out --format=json --all-toolchains "//*"'
794 )
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100795 parser.add_argument(
796 '--extras',
797 help='Extra targets to include at the end of the Blueprint file',
798 default=os.path.join(gn_utils.repo_root(), 'Android.bp.extras'),
799 )
800 parser.add_argument(
801 '--output',
802 help='Blueprint file to create',
803 default=os.path.join(gn_utils.repo_root(), 'Android.bp'),
804 )
805 parser.add_argument(
806 'targets',
807 nargs=argparse.REMAINDER,
808 help='Targets to include in the blueprint (e.g., "//:perfetto_tests")')
809 args = parser.parse_args()
Sami Kyostila865d1d32017-12-12 18:37:04 +0000810
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100811 if args.desc:
812 with open(args.desc) as f:
813 desc = json.load(f)
814 else:
815 desc = gn_utils.create_build_description(gn_args)
Sami Kyostila865d1d32017-12-12 18:37:04 +0000816
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100817 gn = gn_utils.GnParser(desc)
818 blueprint = create_blueprint_for_targets(gn, desc, args.targets or
819 default_targets)
820 output = [
821 """// Copyright (C) 2017 The Android Open Source Project
Sami Kyostila865d1d32017-12-12 18:37:04 +0000822//
823// Licensed under the Apache License, Version 2.0 (the "License");
824// you may not use this file except in compliance with the License.
825// You may obtain a copy of the License at
826//
827// http://www.apache.org/licenses/LICENSE-2.0
828//
829// Unless required by applicable law or agreed to in writing, software
830// distributed under the License is distributed on an "AS IS" BASIS,
831// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
832// See the License for the specific language governing permissions and
833// limitations under the License.
834//
835// This file is automatically generated by %s. Do not edit.
836""" % (__file__)
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100837 ]
838 blueprint.to_string(output)
839 with open(args.extras, 'r') as r:
840 for line in r:
841 output.append(line.rstrip("\n\r"))
Primiano Tucci9c411652019-08-27 07:13:59 +0200842
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100843 out_files = []
Primiano Tucci9c411652019-08-27 07:13:59 +0200844
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100845 # Generate the Android.bp file.
846 out_files.append(args.output + '.swp')
847 with open(out_files[-1], 'w') as f:
848 f.write('\n'.join(output))
Sami Kyostila865d1d32017-12-12 18:37:04 +0000849
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100850 # Generate the perfetto_build_flags.h file.
851 out_files.append(os.path.join(buildflags_dir, 'perfetto_build_flags.h.swp'))
852 gn_utils.gen_buildflags(gn_args, out_files[-1])
Sami Kyostila865d1d32017-12-12 18:37:04 +0000853
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100854 # Either check the contents or move the files to their final destination.
855 return gn_utils.check_or_commit_generated_files(out_files, args.check_only)
Primiano Tucci9c411652019-08-27 07:13:59 +0200856
857
Sami Kyostila865d1d32017-12-12 18:37:04 +0000858if __name__ == '__main__':
Primiano Tuccif0d7ef82019-10-04 15:35:24 +0100859 sys.exit(main())