blob: 85f8cfeb52ab1db4d7f6a6b9ecbb3788fafb3141 [file] [log] [blame]
Ben Murdochc8c1d9e2017-03-08 14:04:23 +00001#!/usr/bin/env python
2
3import os
Dan Willemsen1f906bf2018-10-24 23:07:53 -07004import subprocess
Rubin Xu2894c6a2019-02-07 16:01:35 +00005import sys
6from antlr4 import *
7from gnparser.gnLexer import gnLexer
8from gnparser.gnParser import gnParser
9from gnparser.gnListener import gnListener
10from string import Template
11
12DBG = False
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000013
Dan Willemsen1f906bf2018-10-24 23:07:53 -070014# Reformat the specified Android.bp file
15def _bpFmt(filename):
Rubin Xu2894c6a2019-02-07 16:01:35 +000016 ## NOTE: bpfmt does not set error code even when the bp file is illegal.
17 print subprocess.check_output(["bpfmt", "-w", filename])
Dan Willemsen1f906bf2018-10-24 23:07:53 -070018
Rubin Xu2894c6a2019-02-07 16:01:35 +000019def _bpList(entries):
20 return '[' + ",".join(['"' + x + '"' for x in entries]) + ']'
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000021
Dan Willemsen1f906bf2018-10-24 23:07:53 -070022# Write an Android.bp in the simpler format used by v8_libplatform and
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000023# v8_libsampler
Dan Willemsen1f906bf2018-10-24 23:07:53 -070024def _writeBP(filename, module_name, sources):
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000025 if not sources:
26 raise ValueError('No sources for ' + filename)
27
28 with open(filename, 'w') as out:
Rubin Xu2894c6a2019-02-07 16:01:35 +000029 out.write(Template('''
30 // GENERATED, do not edit
31 // for changes, see genmakefiles.py
32 cc_library_static {
33 name: "$module_name",
34 defaults: ["v8_defaults"],
35 srcs: $srcs,
36 local_include_dirs: ["src", "include"],
Rubin Xu7314a9f2021-02-10 00:04:48 +000037 apex_available: [
38 "com.android.art.debug",
39 "com.android.art.release",
40 ],
41 }
42 ''').substitute({'module_name': module_name, 'srcs' : _bpList(sorted(sources))}))
43
44 _bpFmt(filename)
45
46def _writeFileGroupBP(filename, module_name, sources):
47 if not sources:
48 raise ValueError('No sources for ' + filename)
49
50 with open(filename, 'w') as out:
51 out.write(Template('''
52 // GENERATED, do not edit
53 // for changes, see genmakefiles.py
54 filegroup {
55 name: "$module_name",
56 srcs: $srcs,
Rubin Xu2894c6a2019-02-07 16:01:35 +000057 }
58 ''').substitute({'module_name': module_name, 'srcs' : _bpList(sorted(sources))}))
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000059
Dan Willemsen1f906bf2018-10-24 23:07:53 -070060 _bpFmt(filename)
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000061
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000062
Rubin Xu7314a9f2021-02-10 00:04:48 +000063def _writeV8BaseBP(getSourcesFunc):
Rubin Xu2894c6a2019-02-07 16:01:35 +000064 sources = getSourcesFunc(None)
65 if not sources:
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000066 raise ValueError('Must specify v8_base target properties')
Rubin Xu7314a9f2021-02-10 00:04:48 +000067 sources.add('src/heap/base/stack.cc')
68 sources.add('src/heap/base/worklist.cc')
69 sources.add('third_party/zlib/google/compression_utils_portable.cc')
70
Rubin Xu2894c6a2019-02-07 16:01:35 +000071 arm_src = list(getSourcesFunc('arm') - sources)
72 arm64_src = list(getSourcesFunc('arm64') - sources)
73 x86_src = list(getSourcesFunc('x86') - sources)
74 x86_64_src = list(getSourcesFunc('x64') - sources)
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000075
Dan Willemsen1f906bf2018-10-24 23:07:53 -070076 filename = 'Android.base.bp'
77 with open(filename, 'w') as out:
Rubin Xu2894c6a2019-02-07 16:01:35 +000078 out.write(Template('''
79 // GENERATED, do not edit
80 // for changes, see genmakefiles.py
81 cc_library_static {
Rubin Xu7314a9f2021-02-10 00:04:48 +000082 name: "v8_base",
83 defaults: ["v8_defaults", "v8_torque_headers"],
84 srcs: $srcs,
85 arch: {
86 arm: {
87 srcs: $arm_src,
88 generated_sources: [
89 "v8_torque_file_cc_32",
90 ],
91 },
92 arm64: {
93 srcs: $arm64_src,
94 generated_sources: [
95 "v8_torque_file_cc",
96 ],
97 },
98 x86: {
99 srcs: $x86_src,
100 generated_sources: [
101 "v8_torque_file_cc_32",
102 ],
103
104 },
105 x86_64: {
106 srcs: $x86_64_src,
107 generated_sources: [
108 "v8_torque_file_cc",
109 ],
110 },
111 },
112 local_include_dirs: ["src", "include", "third_party/zlib",],
113 generated_headers: ["v8_generate_bytecode_builtins_list"],
114 sanitize: {
115 cfi: true,
116 blacklist: "./tools/cfi/blacklist.txt",
117 },
118 apex_available: [
119 "com.android.art.debug",
120 "com.android.art.release",
121 ],
122 }
123 ''').substitute({'srcs': _bpList(sorted(sources)),
124 'arm_src': _bpList(sorted(arm_src)),
125 'arm64_src': _bpList(sorted(arm64_src)),
126 'x86_src': _bpList(sorted(x86_src)),
127 'x86_64_src': _bpList(sorted(x86_64_src)),
128 }))
129
130 _bpFmt(filename)
131
132
133def _writeLibBaseBP(sources):
134 if not sources:
135 raise ValueError('Must specify v8_libbase target properties')
136
137 filename = 'Android.libbase.bp'
138 with open(filename, 'w') as out:
139 out.write(Template('''
140 // GENERATED, do not edit
141 // for changes, see genmakefiles.py
142 cc_library_static {
143 name: "v8_libbase",
Rubin Xu2894c6a2019-02-07 16:01:35 +0000144 defaults: ["v8_defaults"],
145 host_supported: true,
146 srcs: $srcs,
147 local_include_dirs: ["src"],
148 target: {
149 android: {
Rubin Xu7314a9f2021-02-10 00:04:48 +0000150 srcs: [
151 "src/base/debug/stack_trace_android.cc",
152 "src/base/platform/platform-linux.cc",
153 ],
Rubin Xu2894c6a2019-02-07 16:01:35 +0000154 },
155 host: {
Rubin Xu7314a9f2021-02-10 00:04:48 +0000156 srcs: [
157 "src/base/debug/stack_trace_posix.cc",
158 "src/base/platform/platform-linux.cc",
159 ],
Rubin Xu2894c6a2019-02-07 16:01:35 +0000160 cflags: ["-UANDROID"],
161 },
Rubin Xu2894c6a2019-02-07 16:01:35 +0000162 },
Rubin Xu7314a9f2021-02-10 00:04:48 +0000163 apex_available: [
164 "com.android.art.debug",
165 "com.android.art.release",
166 ],
Rubin Xu2894c6a2019-02-07 16:01:35 +0000167 }
168 ''').substitute({'srcs' : _bpList(sorted(sources))}))
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000169
Dan Willemsen1f906bf2018-10-24 23:07:53 -0700170 _bpFmt(filename)
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000171
Rubin Xu2894c6a2019-02-07 16:01:35 +0000172
Rubin Xu7314a9f2021-02-10 00:04:48 +0000173def _writeTorqueBP(sources):
174 if not sources:
175 raise ValueError('Must specify torque_files target properties')
176 genfiles = [
177 "torque-generated/bit-fields.h",
178 "torque-generated/builtin-definitions.h",
179 "torque-generated/interface-descriptors.inc",
180 "torque-generated/factory.cc",
181 "torque-generated/factory.inc",
182 "torque-generated/field-offsets.h",
183 "torque-generated/class-verifiers.cc",
184 "torque-generated/class-verifiers.h",
185 "torque-generated/enum-verifiers.cc",
186 "torque-generated/objects-printer.cc",
187 "torque-generated/objects-body-descriptors-inl.inc",
188# "torque-generated/class-debug-readers.cc",
189# "torque-generated/class-debug-readers.h",
190 "torque-generated/exported-macros-assembler.cc",
191 "torque-generated/exported-macros-assembler.h",
192 "torque-generated/csa-types.h",
193 "torque-generated/instance-types.h",
194 "torque-generated/runtime-macros.cc",
195 "torque-generated/runtime-macros.h",
196 "torque-generated/class-forward-declarations.h",
197 ]
198
199 intl_files = set([
200 "src/objects/intl-objects.tq",
201 "src/objects/js-break-iterator.tq",
202 "src/objects/js-collator.tq",
203 "src/objects/js-date-time-format.tq",
204 "src/objects/js-display-names.tq",
205 "src/objects/js-list-format.tq",
206 "src/objects/js-locale.tq",
207 "src/objects/js-number-format.tq",
208 "src/objects/js-plural-rules.tq",
209 "src/objects/js-relative-time-format.tq",
210 "src/objects/js-segment-iterator.tq",
211 "src/objects/js-segmenter.tq",
212 "src/objects/js-segments.tq"
213 ])
214 sources = [s for s in sources if not s in intl_files]
215
216 #sources = sources[:1]
217 #sources = filter(lambda s:not s.startswith("test/"), sources)
218 for tq in sources:
219 filetq = tq.replace('.tq', '-tq')
220 genfiles.append("torque-generated/" + filetq + "-csa.cc")
221 genfiles.append("torque-generated/" + filetq + "-csa.h")
222 genfiles.append("torque-generated/" + filetq + "-inl.inc")
223 genfiles.append("torque-generated/" + filetq + ".cc")
224 genfiles.append("torque-generated/" + filetq + ".inc")
225
226 dirs = set(map(os.path.dirname, sources))
227 cc_files = filter(lambda s:s.endswith(".cc"), genfiles)
228 include_files = filter(lambda s:not s.endswith(".cc"), genfiles)
229
230 filename = 'Android.torque.bp'
231 with open(filename, 'w') as out:
232 out.write(Template('''
233 // GENERATED, do not edit
234 // for changes, see genmakefiles.py
235 filegroup {
236 name: "v8_torque_src_files",
237 srcs: $srcs,
238 }
239
240 genrule {
241 name: "v8_torque_file",
242 tools: ["v8_torque"],
243 srcs: [":v8_torque_src_files"],
244 cmd: $cmd,
245 out: $include_files,
246 }
247
248 genrule {
249 name: "v8_torque_file_cc",
250 tools: ["v8_torque"],
251 srcs: [":v8_torque_src_files"],
252 cmd: $cmd,
253 out: $cc_files,
254 }
255
256 genrule {
257 name: "v8_torque_file_32",
258 tools: ["v8_torque"],
259 srcs: [":v8_torque_src_files"],
260 cmd: $cmd32,
261 out: $include_files,
262 }
263
264 genrule {
265 name: "v8_torque_file_cc_32",
266 tools: ["v8_torque"],
267 srcs: [":v8_torque_src_files"],
268 cmd: $cmd32,
269 out: $cc_files,
270 }
271 ''').substitute({
272 'srcs' : _bpList(sources),
273 'cmd' : '''"mkdir -p $(genDir)/torque-generated/ && pushd . && cd $(genDir)/torque-generated/ && mkdir -p ''' + ' '.join(dirs) + ''' && popd && $(location v8_torque) -o $(genDir)/torque-generated/ -v8-root $$(pwd)/external/v8 $$(echo $(in) | sed 's/external.v8.//g'); true"''',
274 'cmd32' : '''"mkdir -p $(genDir)/torque-generated/ && pushd . && cd $(genDir)/torque-generated/ && mkdir -p ''' + ' '.join(dirs) + ''' && popd && $(location v8_torque) -o $(genDir)/torque-generated/ -v8-root $$(pwd)/external/v8 -m32 $$(echo $(in) | sed 's/external.v8.//g'); true"''',
275 'cc_files' : _bpList(cc_files),
276 'include_files' : _bpList(include_files)}))
277
278 _bpFmt(filename)
279
Rubin Xu2894c6a2019-02-07 16:01:35 +0000280def _expr_to_str(expr):
281 val = expr.unaryexpr().primaryexpr()
282 if val.String():
283 return val.String().getText()[1:-1] ## Strip quotation marks around string
284 elif val.Identifier():
285 return val.Identifier().getText()
286 else:
287 if DBG: print 'WARN: unhandled primary expression'
288 return None
289
290class V8GnListener(gnListener):
291 def __init__(self, target, arch, only_cc_files):
292 super(gnListener, self).__init__()
293 self._match = False
294 self._depth = 0
295 self._target = target
296 self._arch = arch
297 self._sources = []
298 self._fixed_conditions = {
299 'use_jumbo_build' : True,
300 'use_jumbo_build==true' : True,
301 'is_win' : False,
302 'is_linux' : False,
303 'v8_postmortem_support' : False,
Rubin Xu7314a9f2021-02-10 00:04:48 +0000304 'v8_enable_i18n_support': False,
305 '!v8_enable_i18n_support': True,
Rubin Xu2894c6a2019-02-07 16:01:35 +0000306 'current_os!="aix"' : True,
307 'is_posix||is_fuchsia' : True,
308 'v8_current_cpu=="arm"' : arch == 'arm',
309 'v8_current_cpu=="arm64"' : arch == 'arm64',
310 'v8_current_cpu=="x86"' : arch == 'x86',
311 'v8_current_cpu=="x64"' : arch == 'x64',
312 'v8_current_cpu=="mips"||v8_current_cpu=="mipsel"' : arch == 'mips',
313 'v8_current_cpu=="mips64"||v8_current_cpu=="mips64el"' : arch == 'mips64',
314 'v8_current_cpu=="ppc"||v8_current_cpu=="ppc64"' : False,
315 'v8_current_cpu=="s390"||v8_current_cpu=="s390x"' : False,
Rubin Xu7314a9f2021-02-10 00:04:48 +0000316 'is_linux||is_chromeos||is_mac||is_ios||target_os=="freebsd"' : True,
Rubin Xu2894c6a2019-02-07 16:01:35 +0000317
318 }
319 self._only_cc_files = only_cc_files
320
321 def _match_call_target(self, ctx):
322 call_type = ctx.Identifier().getText()
323 if not call_type in ['v8_source_set', 'v8_component', 'action']: return False
324 call_name = _expr_to_str(ctx.exprlist().expr(0))
325 return call_name == self._target
326
327 def enterCall(self, ctx):
328 if self._depth == 1 and self._match_call_target(ctx):
329 self._match = True
330 self._conditions = [] ## [(value, condition), ...]
331 if DBG: print 'Found call', str(ctx.Identifier()), ctx.exprlist().getText()
332
333 def exitCall(self, ctx):
334 if self._match and self._match_call_target(ctx):
335 self._match = False
336 self._conditions = []
337 if DBG: print 'Left call'
338
339 def _extract_sources(self, ctx):
340 op = ctx.AssignOp().getText()
341 if not ctx.expr().unaryexpr().primaryexpr().exprlist():
342 ## sources += check_header_includes_sources
343 return
344 srcs = map(_expr_to_str, ctx.expr().unaryexpr().primaryexpr().exprlist().expr())
345 if self._only_cc_files:
346 srcs = [x for x in srcs if x.endswith('.cc')]
347 if DBG: print '_extract_sources: ', len(srcs), "condition:", self._conditions
348 if op == '=':
349 if self._sources:
350 print "WARN: override sources"
351 self._sources = srcs
352 elif op == '+=':
353 self._sources.extend(srcs)
354
355 def _compute_condition(self, ctx):
356 condition = ctx.expr().getText()
357 if DBG: print '_extract_condition', condition
358 if condition in self._fixed_conditions:
359 result = self._fixed_conditions[condition]
360 else:
361 print 'WARN: unknown condition, assume False', condition
362 self._fixed_conditions[condition] = False
363 result = False
364 if DBG: print 'Add condition:', condition
365 self._conditions.append((result, condition))
366
367
368 def enterCondition(self, ctx):
369 if not self._match: return
370 self._compute_condition(ctx)
371
372 def enterElsec(self, ctx):
373 if not self._match: return
374 c = self._conditions[-1]
375 self._conditions[-1] = (not c[0], c[1])
376 if DBG: print 'Negate condition:', self._conditions[-1]
377
378 def exitCondition(self, ctx):
379 if not self._match: return
380 if DBG: print 'Remove conditions: ', self._conditions[-1]
381 del self._conditions[-1]
382
383 def _flatten_conditions(self):
384 if DBG: print '_flatten_conditions: ', self._conditions
385 for condition, _ in self._conditions:
386 if not condition:
387 return False
388 return True
389
390 def enterAssignment(self, ctx):
391 if not self._match: return
392 if ctx.lvalue().Identifier().getText() == "sources":
393 if self._flatten_conditions():
394 self._extract_sources(ctx)
395
396 def enterStatement(self, ctx):
397 self._depth += 1
398
399 def exitStatement(self, ctx):
400 self._depth -= 1
401
402 def get_sources(self):
403 seen = set()
404 result = []
405 ## Deduplicate list while maintaining ordering. needed for js2c files
406 for s in self._sources:
407 if not s in seen:
408 result.append(s)
409 seen.add(s)
410 return result
411
412def parseSources(tree, target, arch = None, only_cc_files = True):
413 listener = V8GnListener(target, arch, only_cc_files)
414 ParseTreeWalker().walk(listener, tree)
415 return listener.get_sources()
416
Rubin Xu7314a9f2021-02-10 00:04:48 +0000417class V8VariableListener(gnListener):
418 def __init__(self, variableName):
419 super(gnListener, self).__init__()
420 self._sources = []
421 self._variable = variableName
422
423 def enterAssignment(self, ctx):
424 if ctx.lvalue().Identifier().getText() == self._variable:
425 op = ctx.AssignOp().getText()
426 srcs = map(_expr_to_str, ctx.expr().unaryexpr().primaryexpr().exprlist().expr())
427 if DBG: print self._variable, ':', len(srcs)
428 if op == '=':
429 if self._sources:
430 print "WARN: override", self._variable
431 self._sources = srcs
432 elif op == '+=':
433 self._sources.extend(srcs)
434
435 def get_sources(self):
436 return self._sources
437
438def parseTorqueSources(tree):
439 listener = V8VariableListener("torque_files")
440 ParseTreeWalker().walk(listener, tree)
441 return listener.get_sources()
442
443def getV8BaseSourceFunc(tree):
444 intl_files = set([
445 "src/builtins/builtins-intl.cc",
446 "src/objects/intl-objects.cc",
447 "src/objects/intl-objects.h",
448 "src/objects/js-break-iterator-inl.h",
449 "src/objects/js-break-iterator.cc",
450 "src/objects/js-break-iterator.h",
451 "src/objects/js-collator-inl.h",
452 "src/objects/js-collator.cc",
453 "src/objects/js-collator.h",
454 "src/objects/js-date-time-format-inl.h",
455 "src/objects/js-date-time-format.cc",
456 "src/objects/js-date-time-format.h",
457 "src/objects/js-display-names-inl.h",
458 "src/objects/js-display-names.cc",
459 "src/objects/js-display-names.h",
460 "src/objects/js-list-format-inl.h",
461 "src/objects/js-list-format.cc",
462 "src/objects/js-list-format.h",
463 "src/objects/js-locale-inl.h",
464 "src/objects/js-locale.cc",
465 "src/objects/js-locale.h",
466 "src/objects/js-number-format-inl.h",
467 "src/objects/js-number-format.cc",
468 "src/objects/js-number-format.h",
469 "src/objects/js-plural-rules-inl.h",
470 "src/objects/js-plural-rules.cc",
471 "src/objects/js-plural-rules.h",
472 "src/objects/js-relative-time-format-inl.h",
473 "src/objects/js-relative-time-format.cc",
474 "src/objects/js-relative-time-format.h",
475 "src/objects/js-segment-iterator-inl.h",
476 "src/objects/js-segment-iterator.cc",
477 "src/objects/js-segment-iterator.h",
478 "src/objects/js-segmenter-inl.h",
479 "src/objects/js-segmenter.cc",
480 "src/objects/js-segmenter.h",
481 "src/objects/js-segments-inl.h",
482 "src/objects/js-segments.cc",
483 "src/objects/js-segments.h",
484 "src/runtime/runtime-intl.cc",
485 "src/strings/char-predicates.cc",
486 "src/builtins/builtins-intl-gen.cc",
487 ])
488
489 listener = V8VariableListener("v8_compiler_sources")
490 ParseTreeWalker().walk(listener, tree)
491 v8_compiler_sources = listener.get_sources()
492 v8_compiler_sources = [x for x in v8_compiler_sources if x.endswith('.cc')]
493 def getSourceFunc(arch):
494 return set(parseSources(tree, "v8_base_without_compiler", arch) + v8_compiler_sources) \
495 - intl_files
496 return getSourceFunc
497
Ben Murdoch62ed6312017-06-06 11:06:27 +0100498def GenerateMakefiles():
Rubin Xu2894c6a2019-02-07 16:01:35 +0000499 f = FileStream(os.path.join(os.getcwd(), './BUILD.gn'))
500 lexer = gnLexer(f)
501 stream = CommonTokenStream(lexer)
502 parser = gnParser(stream)
503 tree = parser.r()
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000504
Rubin Xu2894c6a2019-02-07 16:01:35 +0000505 _writeLibBaseBP(parseSources(tree, "v8_libbase"))
Rubin Xu7314a9f2021-02-10 00:04:48 +0000506 _writeBP('Android.libplatform.bp', 'v8_libplatform', parseSources(tree, "v8_libplatform"))
507 _writeBP('Android.libsampler.bp', 'v8_libsampler', parseSources(tree, "v8_libsampler"))
508 _writeV8BaseBP(getV8BaseSourceFunc(tree))
509 v8_init_sources = parseSources(tree, "v8_initializers")
510 v8_init_sources.remove("src/builtins/builtins-intl-gen.cc")
511 _writeFileGroupBP('Android.initializers.bp', 'v8_initializers', v8_init_sources)
512 _writeTorqueBP(parseTorqueSources(tree))
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000513
Dan Willemsen1f906bf2018-10-24 23:07:53 -0700514if __name__ == '__main__':
515 GenerateMakefiles()