OLD | NEW |
1 #!/usr/bin/env dart | 1 #!/usr/bin/env dart |
2 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 2 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 /// Command line tool to merge the SDK libraries and our patch files. | 6 /// Command line tool to merge the SDK libraries and our patch files. |
7 /// This is currently designed as an offline tool, but we could automate it. | 7 /// This is currently designed as an offline tool, but we could automate it. |
8 | 8 |
9 import 'dart:io'; | 9 import 'dart:io'; |
| 10 import 'dart:isolate' show RawReceivePort; |
10 import 'dart:async'; | 11 import 'dart:async'; |
11 import 'dart:math' as math; | 12 import 'dart:math' as math; |
12 | 13 |
13 import 'package:analyzer/analyzer.dart'; | 14 import 'package:analyzer/analyzer.dart'; |
14 import 'package:analyzer/src/generated/sdk.dart'; | 15 import 'package:analyzer/src/generated/sdk.dart'; |
15 import 'package:path/path.dart' as path; | 16 import 'package:path/path.dart' as path; |
16 import 'package:front_end/src/fasta/compile_platform.dart' as compile_platform; | |
17 | 17 |
18 import 'package:front_end/src/fasta/fasta.dart' show CompileTask; | 18 import 'package:front_end/src/fasta/fasta.dart' |
19 | 19 show compilePlatform, writeDepsFile; |
20 import 'package:front_end/src/fasta/compiler_command_line.dart' | |
21 show CompilerCommandLine; | |
22 | |
23 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext; | |
24 | |
25 import 'package:front_end/src/fasta/ticker.dart' show Ticker; | |
26 | 20 |
27 /// Set of input files that were read by this script to generate patched SDK. | 21 /// Set of input files that were read by this script to generate patched SDK. |
28 /// We will dump it out into the depfile for ninja to use. | 22 /// We will dump it out into the depfile for ninja to use. |
29 /// | 23 /// |
30 /// For more information see GN and Ninja references: | 24 /// For more information see GN and Ninja references: |
31 /// https://chromium.googlesource.com/chromium/src/+/56807c6cb383140af0c03da8
f6731d77785d7160/tools/gn/docs/reference.md#depfile_string_File-name-for-input-d
ependencies-for-actions | 25 /// https://chromium.googlesource.com/chromium/src/+/56807c6cb383140af0c03da8
f6731d77785d7160/tools/gn/docs/reference.md#depfile_string_File-name-for-input-d
ependencies-for-actions |
32 /// https://ninja-build.org/manual.html#_depfile | 26 /// https://ninja-build.org/manual.html#_depfile |
33 /// | 27 /// |
34 final deps = new Set<String>(); | 28 final deps = new Set<Uri>(); |
35 | 29 |
36 /// Create [File] object from the given path and register it as a dependency. | 30 /// Create [File] object from the given path and register it as a dependency. |
37 File getInputFile(String path, {canBeMissing: false}) { | 31 File getInputFile(String path, {canBeMissing: false}) { |
38 final file = new File(path); | 32 final file = new File(path); |
39 if (!file.existsSync()) { | 33 if (!file.existsSync()) { |
40 if (!canBeMissing) throw "patch_sdk.dart expects all inputs to exist"; | 34 if (!canBeMissing) throw "patch_sdk.dart expects all inputs to exist"; |
41 return null; | 35 return null; |
42 } | 36 } |
43 deps.add(file.absolute.path); | 37 deps.add(Uri.base.resolveUri(file.uri)); |
44 return file; | 38 return file; |
45 } | 39 } |
46 | 40 |
47 /// Read the given file synchronously as a string and register this path as | 41 /// Read the given file synchronously as a string and register this path as |
48 /// a dependency. | 42 /// a dependency. |
49 String readInputFile(String path, {canBeMissing: false}) => | 43 String readInputFile(String path, {canBeMissing: false}) => |
50 getInputFile(path, canBeMissing: canBeMissing)?.readAsStringSync(); | 44 getInputFile(path, canBeMissing: canBeMissing)?.readAsStringSync(); |
51 | 45 |
52 Future main(List<String> argv) async { | 46 Future main(List<String> argv) async { |
| 47 var port = new RawReceivePort(); |
| 48 try { |
| 49 await _main(argv); |
| 50 } finally { |
| 51 port.close(); |
| 52 } |
| 53 } |
| 54 |
| 55 Future _main(List<String> argv) async { |
53 var base = path.fromUri(Platform.script); | 56 var base = path.fromUri(Platform.script); |
54 var dartDir = path.dirname(path.dirname(path.absolute(base))); | 57 var dartDir = path.dirname(path.dirname(path.absolute(base))); |
55 | 58 |
56 if (argv.length != 5 || argv.first != 'vm') { | 59 if (argv.length != 5 || argv.first != 'vm') { |
57 final self = path.relative(base); | 60 final self = path.relative(base); |
58 print('Usage: $self vm SDK_DIR PATCH_DIR OUTPUT_DIR PACKAGES'); | 61 print('Usage: $self vm SDK_DIR PATCH_DIR OUTPUT_DIR PACKAGES'); |
59 | 62 |
60 final repositoryDir = path.relative(path.dirname(path.dirname(base))); | 63 final repositoryDir = path.relative(path.dirname(path.dirname(base))); |
61 final sdkExample = path.relative(path.join(repositoryDir, 'sdk')); | 64 final sdkExample = path.relative(path.join(repositoryDir, 'sdk')); |
62 final patchExample = path.relative( | 65 final patchExample = path.relative( |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 var builtinLibraryOut = path.join(sdkOut, vmLibrary, '${vmLibrary}.dart'); | 204 var builtinLibraryOut = path.join(sdkOut, vmLibrary, '${vmLibrary}.dart'); |
202 _writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn)); | 205 _writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn)); |
203 } | 206 } |
204 | 207 |
205 for (var file in ['loader.dart', 'server.dart', 'vmservice_io.dart']) { | 208 for (var file in ['loader.dart', 'server.dart', 'vmservice_io.dart']) { |
206 var libraryIn = path.join(dartDir, 'runtime', 'bin', 'vmservice', file); | 209 var libraryIn = path.join(dartDir, 'runtime', 'bin', 'vmservice', file); |
207 var libraryOut = path.join(sdkOut, 'vmservice_io', file); | 210 var libraryOut = path.join(sdkOut, 'vmservice_io', file); |
208 _writeSync(libraryOut, readInputFile(libraryIn)); | 211 _writeSync(libraryOut, readInputFile(libraryIn)); |
209 } | 212 } |
210 | 213 |
211 final platform = path.join(outDir, 'platform.dill'); | 214 Uri platform = Uri.base |
| 215 .resolveUri(new Uri.directory(outDir).resolve('platform.dill.tmp')); |
| 216 Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile)); |
| 217 await compilePlatform( |
| 218 Uri.base.resolveUri(new Uri.directory(outDir)), platform, |
| 219 packages: packages, verbose: false); |
212 | 220 |
213 await compile_platform.mainEntryPoint(<String>[ | 221 Uri platformFinalLocation = |
214 '--packages', | 222 Uri.base.resolveUri(new Uri.directory(outDir).resolve('platform.dill')); |
215 new Uri.file(packagesFile).toString(), | |
216 new Uri.directory(outDir).toString(), | |
217 platform, | |
218 ]); | |
219 | 223 |
220 // TODO(kustermann): We suppress compiler hints/warnings/errors temporarily | 224 await writeDepsFile(Platform.script, |
221 // because everyone building the `runtime` target will get these now. | 225 Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation, |
222 // We should remove the suppression again once the underlying issues have | 226 packages: packages, |
223 // been fixed (either in fasta or the dart files in the patched_sdk). | 227 platform: platform, |
224 final capturedLines = <String>[]; | 228 extraDependencies: deps, |
225 try { | 229 verbose: false); |
226 await runZoned(() async { | |
227 // platform.dill was generated, now generate platform.dill.d depfile | |
228 // that captures all dependencies that participated in the generation. | |
229 // There are two types of dependencies: | |
230 // (1) all Dart sources that constitute this tool itself | |
231 // (2) Dart SDK and patch sources. | |
232 // We already collected all inputs from the second category in the deps | |
233 // set. To collect inputs from the first category we actually use Fasta: | |
234 // we ask Fasta to outline patch_sdk.dart and generate a depfile which | |
235 // would list all the sources. | |
236 final depfile = "${outDir}.d"; | |
237 await CompilerCommandLine.withGlobalOptions("outline", [ | |
238 '--packages', | |
239 new Uri.file(packagesFile).toString(), | |
240 '--platform', | |
241 new Uri.file(platform).toString(), // platform.dill | |
242 Platform.script.toString() // patch_sdk.dart | |
243 ], (CompilerContext c) async { | |
244 CompileTask task = | |
245 new CompileTask(c, new Ticker(isVerbose: c.options.verbose)); | |
246 final kernelTarget = await task.buildOutline(null); | |
247 await kernelTarget.writeDepsFile( | |
248 new Uri.file(platform), new Uri.file(depfile)); | |
249 }); | |
250 | 230 |
251 // Read depfile generated by Fasta and append deps that we have collected | 231 await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); |
252 // during generation of patched_sdk to it. | |
253 // Note: we are splitting by ': ' because Windows paths can start with | |
254 // drive letter followed by a colon. | |
255 final list = new File(depfile).readAsStringSync().split(': '); | |
256 assert(list.length == 2); | |
257 deps.addAll(list[1].split(' ').where((str) => str.isNotEmpty)); | |
258 assert(list[0] == path.join('patched_sdk', 'platform.dill')); | |
259 new File(depfile).writeAsStringSync("${list[0]}: ${deps.join(' ')}\n"); | |
260 }, zoneSpecification: new ZoneSpecification(print: (_, _2, _3, line) { | |
261 capturedLines.add(line); | |
262 })); | |
263 } catch (_) { | |
264 for (final line in capturedLines) { | |
265 print(line); | |
266 } | |
267 rethrow; | |
268 } | |
269 } | 232 } |
270 | 233 |
271 /// Writes a file, creating the directory if needed. | 234 /// Writes a file, creating the directory if needed. |
272 void _writeSync(String filePath, String contents) { | 235 void _writeSync(String filePath, String contents) { |
273 var outDir = new Directory(path.dirname(filePath)); | 236 var outDir = new Directory(path.dirname(filePath)); |
274 if (!outDir.existsSync()) outDir.createSync(recursive: true); | 237 if (!outDir.existsSync()) outDir.createSync(recursive: true); |
275 | 238 |
276 new File(filePath).writeAsStringSync(contents); | 239 new File(filePath).writeAsStringSync(contents); |
277 } | 240 } |
278 | 241 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 if (diff != 0) return diff; | 569 if (diff != 0) return diff; |
607 return end - other.end; | 570 return end - other.end; |
608 } | 571 } |
609 } | 572 } |
610 | 573 |
611 List<SdkLibrary> _getSdkLibraries(String contents) { | 574 List<SdkLibrary> _getSdkLibraries(String contents) { |
612 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true); | 575 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true); |
613 parseCompilationUnit(contents).accept(libraryBuilder); | 576 parseCompilationUnit(contents).accept(libraryBuilder); |
614 return libraryBuilder.librariesMap.sdkLibraries; | 577 return libraryBuilder.librariesMap.sdkLibraries; |
615 } | 578 } |
OLD | NEW |