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:isolate' show RawReceivePort; |
11 import 'dart:async'; | 11 import 'dart:async'; |
12 import 'dart:math' as math; | 12 import 'dart:math' as math; |
13 import 'dart:convert' show JSON; | 13 import 'dart:convert' show JSON; |
14 | 14 |
15 import 'package:analyzer/analyzer.dart'; | 15 import 'package:analyzer/analyzer.dart'; |
16 import 'package:analyzer/src/generated/sdk.dart'; | 16 import 'package:analyzer/src/generated/sdk.dart'; |
17 import 'package:path/path.dart' as path; | 17 import 'package:path/path.dart' as path; |
18 | 18 |
19 import 'package:front_end/src/fasta/fasta.dart' as fasta | 19 import 'package:front_end/front_end.dart'; |
20 show compile, compilePlatform, writeDepsFile; | 20 import 'package:front_end/src/base/processed_options.dart'; |
| 21 import 'package:front_end/src/kernel_generator_impl.dart'; |
| 22 import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri; |
21 | 23 |
22 import 'package:compiler/src/kernel/fasta_support.dart' as dart2js | 24 import 'package:front_end/src/fasta/fasta.dart' as fasta show getDependencies; |
23 show compilePlatform; | 25 import 'package:front_end/src/fasta/kernel/utils.dart' show writeProgramToFile; |
| 26 |
| 27 import 'package:kernel/target/targets.dart'; |
| 28 import 'package:kernel/target/vm_fasta.dart'; |
| 29 import 'package:kernel/target/flutter_fasta.dart'; |
| 30 import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget; |
24 | 31 |
25 /// Set of input files that were read by this script to generate patched SDK. | 32 /// Set of input files that were read by this script to generate patched SDK. |
26 /// We will dump it out into the depfile for ninja to use. | 33 /// We will dump it out into the depfile for ninja to use. |
27 /// | 34 /// |
28 /// For more information see GN and Ninja references: | 35 /// For more information see GN and Ninja references: |
29 /// https://chromium.googlesource.com/chromium/src/+/56807c6cb383140af0c03da8
f6731d77785d7160/tools/gn/docs/reference.md#depfile_string_File-name-for-input-d
ependencies-for-actions | 36 /// https://chromium.googlesource.com/chromium/src/+/56807c6cb383140af0c03da8
f6731d77785d7160/tools/gn/docs/reference.md#depfile_string_File-name-for-input-d
ependencies-for-actions |
30 /// https://ninja-build.org/manual.html#_depfile | 37 /// https://ninja-build.org/manual.html#_depfile |
31 /// | 38 /// |
32 final deps = new Set<Uri>(); | 39 final deps = new Set<Uri>(); |
33 | 40 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 _copyExtraLibraries(sdkOut, locations); | 119 _copyExtraLibraries(sdkOut, locations); |
113 | 120 |
114 Uri platform = outDirUri.resolve('platform.dill.tmp'); | 121 Uri platform = outDirUri.resolve('platform.dill.tmp'); |
115 Uri outline = outDirUri.resolve('outline.dill'); | 122 Uri outline = outDirUri.resolve('outline.dill'); |
116 Uri librariesJson = outDirUri.resolve("lib/libraries.json"); | 123 Uri librariesJson = outDirUri.resolve("lib/libraries.json"); |
117 Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile)); | 124 Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile)); |
118 | 125 |
119 await _writeSync( | 126 await _writeSync( |
120 librariesJson.toFilePath(), JSON.encode({"libraries": locations})); | 127 librariesJson.toFilePath(), JSON.encode({"libraries": locations})); |
121 | 128 |
122 if (forVm || forFlutter) { | 129 var flags = new TargetFlags(); |
123 await fasta.compilePlatform(outDirUri, platform, | 130 var target = forVm |
124 packages: packages, | 131 ? new VmFastaTarget(flags) |
125 outlineOutput: outline, | 132 : (forFlutter ? new FlutterFastaTarget(flags) : new Dart2jsTarget(flags)); |
126 backendTarget: forVm ? 'vm_fasta' : 'flutter_fasta'); | 133 var platformDeps = |
127 } else { | 134 await compilePlatform(outDirUri, target, packages, platform, outline); |
128 await dart2js.compilePlatform(outDirUri, platform, | 135 deps.addAll(platformDeps); |
129 packages: packages, outlineOutput: outline); | |
130 } | |
131 | 136 |
132 if (forVm) { | 137 if (forVm) { |
| 138 // TODO(sigmund): add support for the flutter vmservice_sky as well. |
| 139 var vmserviceName = 'vmservice_io'; |
133 var base = path.fromUri(Platform.script); | 140 var base = path.fromUri(Platform.script); |
134 Uri repositoryDir = | 141 Uri dartDir = |
135 new Uri.directory(path.dirname(path.dirname(path.absolute(base)))); | 142 new Uri.directory(path.dirname(path.dirname(path.absolute(base)))); |
136 var vmserviceName = 'vmservice_io'; | 143 var program = await kernelForProgram( |
137 Uri vmserviceSdk = repositoryDir.resolve('runtime/bin/vmservice_sdk/'); | 144 Uri.parse('dart:$vmserviceName'), |
| 145 new CompilerOptions() |
| 146 ..sdkSummary = outline |
| 147 ..dartLibraries = <String, Uri>{ |
| 148 '_vmservice': outDirUri.resolve('lib/vmservice/vmservice.dart'), |
| 149 'vmservice_io': |
| 150 dartDir.resolve('runtime/bin/vmservice/vmservice_io.dart'), |
| 151 } |
| 152 ..packagesFileUri = packages); |
138 Uri vmserviceUri = outDirUri.resolve('$vmserviceName.dill'); | 153 Uri vmserviceUri = outDirUri.resolve('$vmserviceName.dill'); |
139 // TODO(sigmundch): Specify libraries.json directly instead of "--sdk" | 154 await writeProgramToFile(program, vmserviceUri); |
140 // after #29882 is fixed. | |
141 await fasta.compile([ | |
142 "--sdk=$vmserviceSdk", | |
143 "--platform=$outline", | |
144 "--target=vm_fasta", | |
145 "--packages=$packages", | |
146 "dart:$vmserviceName", | |
147 "-o", | |
148 "$vmserviceUri", | |
149 ]); | |
150 } | 155 } |
151 | 156 |
152 Uri platformFinalLocation = outDirUri.resolve('platform.dill'); | 157 Uri platformFinalLocation = outDirUri.resolve('platform.dill'); |
153 | 158 |
154 // We generate a dependency file for GN to properly regenerate the patched sdk | 159 // We generate a dependency file for GN to properly regenerate the patched sdk |
155 // folder, outline.dill and platform.dill files when necessary: either when | 160 // folder, outline.dill and platform.dill files when necessary: either when |
156 // the sdk sources change or when this script is updated. In particular: | 161 // the sdk sources change or when this script is updated. In particular: |
157 // | 162 // |
158 // - sdk changes: we track the actual sources we are compiling. If we are | 163 // - sdk changes: we track the actual sources we are compiling. If we are |
159 // building the dart2js sdk, this includes the dart2js-specific patch | 164 // building the dart2js sdk, this includes the dart2js-specific patch |
160 // files. | 165 // files. |
161 // | 166 // |
162 // These files are tracked by [deps] and passed below to [writeDepsFile] in | 167 // These files are tracked by [deps] and passed below to [writeDepsFile] in |
163 // the extraDependencies argument. | 168 // the extraDependencies argument. |
164 // | 169 // |
165 // - script updates: we track this script file and any code it imports (even | 170 // - script updates: we track this script file and any code it imports (even |
166 // sdk libraries). Note that this script runs on the standalone VM, so any | 171 // sdk libraries). Note that this script runs on the standalone VM, so any |
167 // sdk library used by this script indirectly depends on a VM-specific | 172 // sdk library used by this script indirectly depends on a VM-specific |
168 // patch file. | 173 // patch file. |
169 // | 174 // |
170 // These set of files is discovered by `writeDepsFile` below, and the | 175 // These set of files is discovered by `getDependencies` below, and the |
171 // [platformForDeps] is always the VM-specific `platform.dill` file. | 176 // [platformForDeps] is always the VM-specific `platform.dill` file. |
172 // | |
173 // TODO(sigmund): we should change this: | |
174 // - we should rewrite writeDepsFile: fasta could provide an API to crawl | |
175 // the dependencies, but anything that is GN specific, should be on | |
176 // this file instead. | |
177 // | |
178 // - We don't need to include sdk dependencies of the script because | |
179 // those are already included indirectly (either in [deps] when | |
180 // building the sdk for the VM, or via the .GN dependencies in the | |
181 // build files for dart2js and flutter). | |
182 var platformForDeps = platform; | 177 var platformForDeps = platform; |
183 var sdkDir = outDirUri; | 178 var sdkDir = outDirUri; |
184 if (forDart2js || forFlutter) { | 179 if (forDart2js || forFlutter) { |
185 // Note: this would fail if `../patched_sdk/platform.dill` doesn't exist. We | 180 // Note: this would fail if `../patched_sdk/platform.dill` doesn't exist. We |
186 // added an explicit dependency in the .GN rules so patched_dart2js_sdk (and | 181 // added an explicit dependency in the .GN rules so patched_dart2js_sdk (and |
187 // patched_flutter_sdk) depend on patched_sdk to ensure that it exists. | 182 // patched_flutter_sdk) depend on patched_sdk to ensure that it exists. |
188 platformForDeps = outDirUri.resolve('../patched_sdk/platform.dill'); | 183 platformForDeps = outDirUri.resolve('../patched_sdk/platform.dill'); |
189 sdkDir = outDirUri.resolve('../patched_sdk/'); | 184 sdkDir = outDirUri.resolve('../patched_sdk/'); |
190 } | 185 } |
191 await fasta.writeDepsFile(Platform.script, | 186 deps.addAll(await fasta.getDependencies(Platform.script, |
192 Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation, | 187 sdk: sdkDir, packages: packages, platform: platformForDeps)); |
193 sdk: sdkDir, | 188 await writeDepsFile(Uri.base.resolveUri(new Uri.file("$outDir.d")), |
194 packages: packages, | 189 platformFinalLocation, deps); |
195 platform: platformForDeps, | 190 await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); |
196 extraDependencies: deps); | 191 } |
197 | 192 |
198 await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); | 193 /// Generates an outline.dill and platform.dill file containing the result of |
| 194 /// compiling a platform's SDK. |
| 195 /// |
| 196 /// Returns a list of dependencies read by the compiler. This list can be used |
| 197 /// to create GN dependency files. |
| 198 Future<List<Uri>> compilePlatform(Uri patchedSdk, Target target, Uri packages, |
| 199 Uri fullOutput, Uri outlineOutput) async { |
| 200 var options = new CompilerOptions() |
| 201 ..strongMode = false |
| 202 ..compileSdk = true |
| 203 ..sdkRoot = patchedSdk |
| 204 ..packagesFileUri = packages |
| 205 ..chaseDependencies = true |
| 206 ..target = target; |
| 207 |
| 208 var result = await generateKernel( |
| 209 new ProcessedOptions( |
| 210 options, |
| 211 // TODO(sigmund): pass all sdk libraries needed here, and make this |
| 212 // hermetic. |
| 213 false, |
| 214 [Uri.parse('dart:core')]), |
| 215 buildSummary: true, |
| 216 buildProgram: true); |
| 217 new File.fromUri(outlineOutput).writeAsBytesSync(result.summary); |
| 218 await writeProgramToFile(result.program, fullOutput); |
| 219 return result.deps; |
| 220 } |
| 221 |
| 222 Future writeDepsFile( |
| 223 Uri output, Uri depsFile, Iterable<Uri> allDependencies) async { |
| 224 if (allDependencies.isEmpty) return; |
| 225 String toRelativeFilePath(Uri uri) { |
| 226 // Ninja expects to find file names relative to the current working |
| 227 // directory. We've tried making them relative to the deps file, but that |
| 228 // doesn't work for downstream projects. Making them absolute also |
| 229 // doesn't work. |
| 230 // |
| 231 // We can test if it works by running ninja twice, for example: |
| 232 // |
| 233 // ninja -C xcodebuild/ReleaseX64 runtime_kernel -d explain |
| 234 // ninja -C xcodebuild/ReleaseX64 runtime_kernel -d explain |
| 235 // |
| 236 // The second time, ninja should say: |
| 237 // |
| 238 // ninja: Entering directory `xcodebuild/ReleaseX64' |
| 239 // ninja: no work to do. |
| 240 // |
| 241 // It's broken if it says something like this: |
| 242 // |
| 243 // ninja explain: expected depfile 'patched_sdk.d' to mention |
| 244 // 'patched_sdk/platform.dill', got |
| 245 // '/.../xcodebuild/ReleaseX64/patched_sdk/platform.dill' |
| 246 return Uri.parse(relativizeUri(uri, base: Uri.base)).toFilePath(); |
| 247 } |
| 248 |
| 249 StringBuffer sb = new StringBuffer(); |
| 250 sb.write(toRelativeFilePath(output)); |
| 251 sb.write(":"); |
| 252 for (Uri uri in allDependencies) { |
| 253 sb.write(" "); |
| 254 sb.write(toRelativeFilePath(uri)); |
| 255 } |
| 256 sb.writeln(); |
| 257 await new File.fromUri(depsFile).writeAsString("$sb"); |
199 } | 258 } |
200 | 259 |
201 /// Updates the contents of | 260 /// Updates the contents of |
202 /// sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart to include | 261 /// sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart to include |
203 /// declarations for vm internal libraries. | 262 /// declarations for vm internal libraries. |
204 String _updateLibraryMetadata(String sdkOut, String libContents) { | 263 String _updateLibraryMetadata(String sdkOut, String libContents) { |
205 if (!forVm && !forFlutter) return libContents; | 264 if (!forVm && !forFlutter) return libContents; |
206 var extraLibraries = new StringBuffer(); | 265 var extraLibraries = new StringBuffer(); |
207 extraLibraries.write(''' | 266 extraLibraries.write(''' |
208 "_builtin": const LibraryInfo( | 267 "_builtin": const LibraryInfo( |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 if (diff != 0) return diff; | 733 if (diff != 0) return diff; |
675 return end - other.end; | 734 return end - other.end; |
676 } | 735 } |
677 } | 736 } |
678 | 737 |
679 List<SdkLibrary> _getSdkLibraries(String contents) { | 738 List<SdkLibrary> _getSdkLibraries(String contents) { |
680 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(forDart2js); | 739 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(forDart2js); |
681 parseCompilationUnit(contents).accept(libraryBuilder); | 740 parseCompilationUnit(contents).accept(libraryBuilder); |
682 return libraryBuilder.librariesMap.sdkLibraries; | 741 return libraryBuilder.librariesMap.sdkLibraries; |
683 } | 742 } |
OLD | NEW |