Chromium Code Reviews| 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; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 | 45 |
| 46 Future main(List<String> argv) async { | 46 Future main(List<String> argv) async { |
| 47 var port = new RawReceivePort(); | 47 var port = new RawReceivePort(); |
| 48 try { | 48 try { |
| 49 await _main(argv); | 49 await _main(argv); |
| 50 } finally { | 50 } finally { |
| 51 port.close(); | 51 port.close(); |
| 52 } | 52 } |
| 53 } | 53 } |
| 54 | 54 |
| 55 Future _main(List<String> argv) async { | 55 void usage(String mode) { |
|
Vyacheslav Egorov (Google)
2017/04/27 14:07:23
mode is not used in the body of this function
Siggi Cherem (dart-lang)
2017/04/28 21:37:21
oops. Done.
| |
| 56 var base = path.fromUri(Platform.script); | |
| 57 final self = path.relative(base); | |
| 58 print('Usage: $self [vm|dart2js] SDK_DIR PATCH_DIR OUTPUT_DIR PACKAGES'); | |
| 59 | |
| 60 final repositoryDir = path.relative(path.dirname(path.dirname(base))); | |
| 61 final sdkExample = path.relative(path.join(repositoryDir, 'sdk')); | |
| 62 final patchExample = path.relative( | |
| 63 path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patch')); | |
| 64 final outExample = path.relative( | |
| 65 path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patched_sdk')); | |
| 66 final packagesExample = path.relative(path.join(repositoryDir, '.packages')); | |
| 67 print('For example:'); | |
| 68 print('\$ $self vm $sdkExample $patchExample $outExample $packagesExample'); | |
| 69 | |
| 70 exit(1); | |
| 71 } | |
| 72 | |
| 73 Future _main(List<String> argv) { | |
| 74 var mode = argv.first; | |
| 75 if (mode == 'vm') return _vmMain(argv); | |
| 76 if (mode == 'dart2js') return _dart2jsMain(argv); | |
| 77 usage('[vm|dart2js]'); | |
| 78 return null; | |
| 79 } | |
| 80 | |
| 81 Future _vmMain(List<String> argv) async { | |
|
Vyacheslav Egorov (Google)
2017/04/27 14:07:23
vmMain and dart2jsMain have very similar prefix an
Siggi Cherem (dart-lang)
2017/04/28 21:37:21
Done.
| |
| 56 var base = path.fromUri(Platform.script); | 82 var base = path.fromUri(Platform.script); |
| 57 var dartDir = path.dirname(path.dirname(path.absolute(base))); | 83 var dartDir = path.dirname(path.dirname(path.absolute(base))); |
| 58 | |
| 59 if (argv.length != 5 || argv.first != 'vm') { | 84 if (argv.length != 5 || argv.first != 'vm') { |
|
Vyacheslav Egorov (Google)
2017/04/27 14:07:23
argv.first != 'vm' can't happen anymore.
Siggi Cherem (dart-lang)
2017/04/28 21:37:21
Done.
| |
| 60 final self = path.relative(base); | 85 usage('vm'); |
| 61 print('Usage: $self vm SDK_DIR PATCH_DIR OUTPUT_DIR PACKAGES'); | |
| 62 | |
| 63 final repositoryDir = path.relative(path.dirname(path.dirname(base))); | |
| 64 final sdkExample = path.relative(path.join(repositoryDir, 'sdk')); | |
| 65 final patchExample = path.relative( | |
| 66 path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patch')); | |
| 67 final outExample = path.relative(path.join( | |
| 68 repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patched_sdk')); | |
| 69 print('For example:'); | |
| 70 print('\$ $self vm $sdkExample $patchExample $outExample'); | |
| 71 | |
| 72 exit(1); | |
| 73 } | 86 } |
| 74 | 87 |
| 75 var mode = argv[0]; | |
| 76 assert(mode == "vm"); | |
| 77 var input = argv[1]; | 88 var input = argv[1]; |
| 78 var sdkLibIn = path.join(input, 'lib'); | 89 var sdkLibIn = path.join(input, 'lib'); |
| 79 var patchIn = argv[2]; | 90 var patchIn = argv[2]; |
| 80 var outDir = argv[3]; | 91 var outDir = argv[3]; |
| 81 var sdkOut = path.join(outDir, 'lib'); | 92 var sdkOut = path.join(outDir, 'lib'); |
| 82 var packagesFile = argv[4]; | 93 var packagesFile = argv[4]; |
| 83 | 94 |
| 84 // Copy and patch libraries.dart and version | 95 // Copy and patch libraries.dart and version |
| 85 var libContents = readInputFile(path.join( | 96 var libContents = readInputFile(path.join( |
| 86 sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart')); | 97 sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart')); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 libContents); | 130 libContents); |
| 120 | 131 |
| 121 // Parse libraries.dart | 132 // Parse libraries.dart |
| 122 var sdkLibraries = _getSdkLibraries(libContents); | 133 var sdkLibraries = _getSdkLibraries(libContents); |
| 123 | 134 |
| 124 // Enumerate core libraries and apply patches | 135 // Enumerate core libraries and apply patches |
| 125 for (SdkLibrary library in sdkLibraries) { | 136 for (SdkLibrary library in sdkLibraries) { |
| 126 if (library.isDart2JsLibrary) { | 137 if (library.isDart2JsLibrary) { |
| 127 continue; | 138 continue; |
| 128 } | 139 } |
| 129 | 140 _applyPatch(library, sdkLibIn, patchIn, sdkOut); |
| 130 var libraryOut = path.join(sdkLibIn, library.path); | |
| 131 var libraryIn = libraryOut; | |
| 132 | |
| 133 var libraryFile = getInputFile(libraryIn, canBeMissing: true); | |
| 134 if (libraryFile != null) { | |
| 135 var outPaths = <String>[libraryOut]; | |
| 136 var libraryContents = libraryFile.readAsStringSync(); | |
| 137 | |
| 138 int inputModifyTime = | |
| 139 libraryFile.lastModifiedSync().millisecondsSinceEpoch; | |
| 140 var partFiles = <File>[]; | |
| 141 for (var part in parseDirectives(libraryContents).directives) { | |
| 142 if (part is PartDirective) { | |
| 143 var partPath = part.uri.stringValue; | |
| 144 outPaths.add(path.join(path.dirname(libraryOut), partPath)); | |
| 145 | |
| 146 var partFile = | |
| 147 getInputFile(path.join(path.dirname(libraryIn), partPath)); | |
| 148 partFiles.add(partFile); | |
| 149 inputModifyTime = math.max(inputModifyTime, | |
| 150 partFile.lastModifiedSync().millisecondsSinceEpoch); | |
| 151 } | |
| 152 } | |
| 153 | |
| 154 // See if we can find a patch file. | |
| 155 var patchPath = path.join( | |
| 156 patchIn, path.basenameWithoutExtension(libraryIn) + '_patch.dart'); | |
| 157 | |
| 158 var patchFile = getInputFile(patchPath, canBeMissing: true); | |
| 159 if (patchFile != null) { | |
| 160 inputModifyTime = math.max(inputModifyTime, | |
| 161 patchFile.lastModifiedSync().millisecondsSinceEpoch); | |
| 162 } | |
| 163 | |
| 164 // Compute output paths | |
| 165 outPaths = outPaths | |
| 166 .map((p) => path.join(sdkOut, path.relative(p, from: sdkLibIn))) | |
| 167 .toList(); | |
| 168 | |
| 169 // Compare output modify time with input modify time. | |
| 170 bool needsUpdate = false; | |
| 171 for (var outPath in outPaths) { | |
| 172 var outFile = new File(outPath); | |
| 173 if (!outFile.existsSync() || | |
| 174 outFile.lastModifiedSync().millisecondsSinceEpoch < | |
| 175 inputModifyTime) { | |
| 176 needsUpdate = true; | |
| 177 break; | |
| 178 } | |
| 179 } | |
| 180 | |
| 181 if (needsUpdate) { | |
| 182 var contents = <String>[libraryContents]; | |
| 183 contents.addAll(partFiles.map((f) => f.readAsStringSync())); | |
| 184 if (patchFile != null) { | |
| 185 var patchContents = patchFile.readAsStringSync(); | |
| 186 contents = _patchLibrary(patchFile.path, contents, patchContents); | |
| 187 } | |
| 188 | |
| 189 for (var i = 0; i < outPaths.length; i++) { | |
| 190 _writeSync(outPaths[i], contents[i]); | |
| 191 } | |
| 192 } | |
| 193 } | |
| 194 } | 141 } |
| 195 | 142 |
| 196 for (var tuple in [ | 143 for (var tuple in [ |
| 197 ['_builtin', 'builtin.dart'] | 144 ['_builtin', 'builtin.dart'] |
| 198 ]) { | 145 ]) { |
| 199 var vmLibrary = tuple[0]; | 146 var vmLibrary = tuple[0]; |
| 200 var dartFile = tuple[1]; | 147 var dartFile = tuple[1]; |
| 201 | 148 |
| 202 // The "dart:_builtin" library is only available for the DartVM. | 149 // The "dart:_builtin" library is only available for the DartVM. |
| 203 var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', dartFile); | 150 var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', dartFile); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 224 await writeDepsFile(Platform.script, | 171 await writeDepsFile(Platform.script, |
| 225 Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation, | 172 Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation, |
| 226 packages: packages, | 173 packages: packages, |
| 227 platform: platform, | 174 platform: platform, |
| 228 extraDependencies: deps, | 175 extraDependencies: deps, |
| 229 verbose: false); | 176 verbose: false); |
| 230 | 177 |
| 231 await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); | 178 await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); |
| 232 } | 179 } |
| 233 | 180 |
| 181 Future _dart2jsMain(List<String> argv) async { | |
| 182 if (argv.length != 5 || argv.first != 'dart2js') { | |
| 183 usage('dart2js'); | |
| 184 } | |
| 185 | |
| 186 var input = argv[1]; | |
| 187 var sdkLibIn = path.join(input, 'lib'); | |
| 188 var patchIn = argv[2]; | |
| 189 var outDir = argv[3]; | |
| 190 var sdkOut = path.join(outDir, 'lib'); | |
| 191 var packagesFile = argv[4]; | |
| 192 | |
| 193 // Parse libraries.dart | |
| 194 var libContents = readInputFile(path.join( | |
| 195 sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart')); | |
| 196 var sdkLibraries = _getSdkLibraries(libContents); | |
| 197 | |
| 198 // Enumerate core libraries and apply patches | |
| 199 for (SdkLibrary library in sdkLibraries) { | |
| 200 if (library.isVmLibrary) continue; | |
| 201 _applyPatch(library, sdkLibIn, patchIn, sdkOut); | |
| 202 } | |
| 203 | |
| 204 Uri platform = Uri.base | |
| 205 .resolveUri(new Uri.directory(outDir).resolve('platform.dill.tmp')); | |
| 206 Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile)); | |
| 207 await compilePlatform( | |
| 208 Uri.base.resolveUri(new Uri.directory(outDir)), platform, | |
| 209 packages: packages, verbose: false, targetDart2js: true); | |
| 210 | |
| 211 Uri platformFinalLocation = | |
| 212 Uri.base.resolveUri(new Uri.directory(outDir).resolve('platform.dill')); | |
| 213 | |
| 214 // To properly regenerate the patched_dart2js_sdk and platform.dill only when | |
| 215 // necessary, we track dependencies as follows: | |
| 216 // - inputs like the sdk libraries and dart2js patch files are covered by the | |
| 217 // extraDependencies argument. | |
| 218 // - this script and its script dependencies are handled by writeDepsFile. | |
| 219 // - the internal platform libraries that may affect how this script | |
| 220 // runs are tracked at the BUILD.gn level (patched_dart2js_sdk depends on | |
| 221 // patched_sdk). | |
| 222 await writeDepsFile(Platform.script, | |
| 223 Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation, | |
| 224 packages: packages, | |
| 225 // To track dependencies of this script, we need to use a platform.dill | |
| 226 // file generated for the VM. The dependency on the patched_sdk at the | |
| 227 // BUILD level guarantees that this file already exists. | |
| 228 platform: Uri.base.resolveUri( | |
| 229 new Uri.directory(outDir).resolve('../patched_sdk/platform.dill')), | |
| 230 extraDependencies: deps, | |
| 231 verbose: false, | |
| 232 targetDart2js: false); | |
| 233 | |
| 234 await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); | |
| 235 } | |
| 236 | |
| 237 _applyPatch( | |
| 238 SdkLibrary library, String sdkLibIn, String patchIn, String sdkOut) { | |
| 239 var libraryOut = path.join(sdkLibIn, library.path); | |
| 240 var libraryIn = libraryOut; | |
| 241 | |
| 242 var libraryFile = getInputFile(libraryIn, canBeMissing: true); | |
| 243 if (libraryFile != null) { | |
| 244 var outPaths = <String>[libraryOut]; | |
| 245 var libraryContents = libraryFile.readAsStringSync(); | |
| 246 | |
| 247 int inputModifyTime = libraryFile.lastModifiedSync().millisecondsSinceEpoch; | |
| 248 var partFiles = <File>[]; | |
| 249 for (var part in parseDirectives(libraryContents).directives) { | |
| 250 if (part is PartDirective) { | |
| 251 var partPath = part.uri.stringValue; | |
| 252 outPaths.add(path.join(path.dirname(libraryOut), partPath)); | |
| 253 | |
| 254 var partFile = | |
| 255 getInputFile(path.join(path.dirname(libraryIn), partPath)); | |
| 256 partFiles.add(partFile); | |
| 257 inputModifyTime = math.max(inputModifyTime, | |
| 258 partFile.lastModifiedSync().millisecondsSinceEpoch); | |
| 259 } | |
| 260 } | |
| 261 | |
| 262 // See if we can find a patch file. | |
| 263 var patchPath = path.join( | |
| 264 patchIn, path.basenameWithoutExtension(libraryIn) + '_patch.dart'); | |
| 265 | |
| 266 var patchFile = getInputFile(patchPath, canBeMissing: true); | |
| 267 if (patchFile != null) { | |
| 268 inputModifyTime = math.max( | |
| 269 inputModifyTime, patchFile.lastModifiedSync().millisecondsSinceEpoch); | |
| 270 } | |
| 271 | |
| 272 // Compute output paths | |
| 273 outPaths = outPaths | |
| 274 .map((p) => path.join(sdkOut, path.relative(p, from: sdkLibIn))) | |
| 275 .toList(); | |
| 276 | |
| 277 // Compare output modify time with input modify time. | |
| 278 bool needsUpdate = false; | |
| 279 for (var outPath in outPaths) { | |
| 280 var outFile = new File(outPath); | |
| 281 if (!outFile.existsSync() || | |
| 282 outFile.lastModifiedSync().millisecondsSinceEpoch < inputModifyTime) { | |
| 283 needsUpdate = true; | |
| 284 break; | |
| 285 } | |
| 286 } | |
| 287 | |
| 288 if (needsUpdate) { | |
| 289 var contents = <String>[libraryContents]; | |
| 290 contents.addAll(partFiles.map((f) => f.readAsStringSync())); | |
| 291 if (patchFile != null) { | |
| 292 var patchContents = patchFile.readAsStringSync(); | |
| 293 contents = _patchLibrary(patchFile.path, contents, patchContents); | |
| 294 } | |
| 295 | |
| 296 for (var i = 0; i < outPaths.length; i++) { | |
| 297 _writeSync(outPaths[i], contents[i]); | |
| 298 } | |
| 299 } | |
| 300 } | |
| 301 } | |
| 302 | |
| 234 /// Writes a file, creating the directory if needed. | 303 /// Writes a file, creating the directory if needed. |
| 235 void _writeSync(String filePath, String contents) { | 304 void _writeSync(String filePath, String contents) { |
| 236 var outDir = new Directory(path.dirname(filePath)); | 305 var outDir = new Directory(path.dirname(filePath)); |
| 237 if (!outDir.existsSync()) outDir.createSync(recursive: true); | 306 if (!outDir.existsSync()) outDir.createSync(recursive: true); |
| 238 | 307 |
| 239 new File(filePath).writeAsStringSync(contents); | 308 new File(filePath).writeAsStringSync(contents); |
| 240 } | 309 } |
| 241 | 310 |
| 242 /// Merges dart:* library code with code from *_patch.dart file. | 311 /// Merges dart:* library code with code from *_patch.dart file. |
| 243 /// | 312 /// |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 if (diff != 0) return diff; | 638 if (diff != 0) return diff; |
| 570 return end - other.end; | 639 return end - other.end; |
| 571 } | 640 } |
| 572 } | 641 } |
| 573 | 642 |
| 574 List<SdkLibrary> _getSdkLibraries(String contents) { | 643 List<SdkLibrary> _getSdkLibraries(String contents) { |
| 575 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true); | 644 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true); |
| 576 parseCompilationUnit(contents).accept(libraryBuilder); | 645 parseCompilationUnit(contents).accept(libraryBuilder); |
| 577 return libraryBuilder.librariesMap.sdkLibraries; | 646 return libraryBuilder.librariesMap.sdkLibraries; |
| 578 } | 647 } |
| OLD | NEW |