Index: tools/patch_sdk.dart |
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart |
index 1f64d6366c39473b448b33820cc244678c46b033..005b36a06c8e910b10c70d327713d2ea74e64d10 100644 |
--- a/tools/patch_sdk.dart |
+++ b/tools/patch_sdk.dart |
@@ -52,28 +52,39 @@ Future main(List<String> argv) async { |
} |
} |
-Future _main(List<String> argv) async { |
+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.
|
var base = path.fromUri(Platform.script); |
- var dartDir = path.dirname(path.dirname(path.absolute(base))); |
+ final self = path.relative(base); |
+ print('Usage: $self [vm|dart2js] SDK_DIR PATCH_DIR OUTPUT_DIR PACKAGES'); |
+ |
+ final repositoryDir = path.relative(path.dirname(path.dirname(base))); |
+ final sdkExample = path.relative(path.join(repositoryDir, 'sdk')); |
+ final patchExample = path.relative( |
+ path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patch')); |
+ final outExample = path.relative( |
+ path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patched_sdk')); |
+ final packagesExample = path.relative(path.join(repositoryDir, '.packages')); |
+ print('For example:'); |
+ print('\$ $self vm $sdkExample $patchExample $outExample $packagesExample'); |
+ |
+ exit(1); |
+} |
+Future _main(List<String> argv) { |
+ var mode = argv.first; |
+ if (mode == 'vm') return _vmMain(argv); |
+ if (mode == 'dart2js') return _dart2jsMain(argv); |
+ usage('[vm|dart2js]'); |
+ return null; |
+} |
+ |
+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.
|
+ var base = path.fromUri(Platform.script); |
+ var dartDir = path.dirname(path.dirname(path.absolute(base))); |
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.
|
- final self = path.relative(base); |
- print('Usage: $self vm SDK_DIR PATCH_DIR OUTPUT_DIR PACKAGES'); |
- |
- final repositoryDir = path.relative(path.dirname(path.dirname(base))); |
- final sdkExample = path.relative(path.join(repositoryDir, 'sdk')); |
- final patchExample = path.relative( |
- path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patch')); |
- final outExample = path.relative(path.join( |
- repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patched_sdk')); |
- print('For example:'); |
- print('\$ $self vm $sdkExample $patchExample $outExample'); |
- |
- exit(1); |
+ usage('vm'); |
} |
- var mode = argv[0]; |
- assert(mode == "vm"); |
var input = argv[1]; |
var sdkLibIn = path.join(input, 'lib'); |
var patchIn = argv[2]; |
@@ -126,71 +137,7 @@ Future _main(List<String> argv) async { |
if (library.isDart2JsLibrary) { |
continue; |
} |
- |
- var libraryOut = path.join(sdkLibIn, library.path); |
- var libraryIn = libraryOut; |
- |
- var libraryFile = getInputFile(libraryIn, canBeMissing: true); |
- if (libraryFile != null) { |
- var outPaths = <String>[libraryOut]; |
- var libraryContents = libraryFile.readAsStringSync(); |
- |
- int inputModifyTime = |
- libraryFile.lastModifiedSync().millisecondsSinceEpoch; |
- var partFiles = <File>[]; |
- for (var part in parseDirectives(libraryContents).directives) { |
- if (part is PartDirective) { |
- var partPath = part.uri.stringValue; |
- outPaths.add(path.join(path.dirname(libraryOut), partPath)); |
- |
- var partFile = |
- getInputFile(path.join(path.dirname(libraryIn), partPath)); |
- partFiles.add(partFile); |
- inputModifyTime = math.max(inputModifyTime, |
- partFile.lastModifiedSync().millisecondsSinceEpoch); |
- } |
- } |
- |
- // See if we can find a patch file. |
- var patchPath = path.join( |
- patchIn, path.basenameWithoutExtension(libraryIn) + '_patch.dart'); |
- |
- var patchFile = getInputFile(patchPath, canBeMissing: true); |
- if (patchFile != null) { |
- inputModifyTime = math.max(inputModifyTime, |
- patchFile.lastModifiedSync().millisecondsSinceEpoch); |
- } |
- |
- // Compute output paths |
- outPaths = outPaths |
- .map((p) => path.join(sdkOut, path.relative(p, from: sdkLibIn))) |
- .toList(); |
- |
- // Compare output modify time with input modify time. |
- bool needsUpdate = false; |
- for (var outPath in outPaths) { |
- var outFile = new File(outPath); |
- if (!outFile.existsSync() || |
- outFile.lastModifiedSync().millisecondsSinceEpoch < |
- inputModifyTime) { |
- needsUpdate = true; |
- break; |
- } |
- } |
- |
- if (needsUpdate) { |
- var contents = <String>[libraryContents]; |
- contents.addAll(partFiles.map((f) => f.readAsStringSync())); |
- if (patchFile != null) { |
- var patchContents = patchFile.readAsStringSync(); |
- contents = _patchLibrary(patchFile.path, contents, patchContents); |
- } |
- |
- for (var i = 0; i < outPaths.length; i++) { |
- _writeSync(outPaths[i], contents[i]); |
- } |
- } |
- } |
+ _applyPatch(library, sdkLibIn, patchIn, sdkOut); |
} |
for (var tuple in [ |
@@ -231,6 +178,128 @@ Future _main(List<String> argv) async { |
await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); |
} |
+Future _dart2jsMain(List<String> argv) async { |
+ if (argv.length != 5 || argv.first != 'dart2js') { |
+ usage('dart2js'); |
+ } |
+ |
+ var input = argv[1]; |
+ var sdkLibIn = path.join(input, 'lib'); |
+ var patchIn = argv[2]; |
+ var outDir = argv[3]; |
+ var sdkOut = path.join(outDir, 'lib'); |
+ var packagesFile = argv[4]; |
+ |
+ // Parse libraries.dart |
+ var libContents = readInputFile(path.join( |
+ sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart')); |
+ var sdkLibraries = _getSdkLibraries(libContents); |
+ |
+ // Enumerate core libraries and apply patches |
+ for (SdkLibrary library in sdkLibraries) { |
+ if (library.isVmLibrary) continue; |
+ _applyPatch(library, sdkLibIn, patchIn, sdkOut); |
+ } |
+ |
+ Uri platform = Uri.base |
+ .resolveUri(new Uri.directory(outDir).resolve('platform.dill.tmp')); |
+ Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile)); |
+ await compilePlatform( |
+ Uri.base.resolveUri(new Uri.directory(outDir)), platform, |
+ packages: packages, verbose: false, targetDart2js: true); |
+ |
+ Uri platformFinalLocation = |
+ Uri.base.resolveUri(new Uri.directory(outDir).resolve('platform.dill')); |
+ |
+ // To properly regenerate the patched_dart2js_sdk and platform.dill only when |
+ // necessary, we track dependencies as follows: |
+ // - inputs like the sdk libraries and dart2js patch files are covered by the |
+ // extraDependencies argument. |
+ // - this script and its script dependencies are handled by writeDepsFile. |
+ // - the internal platform libraries that may affect how this script |
+ // runs are tracked at the BUILD.gn level (patched_dart2js_sdk depends on |
+ // patched_sdk). |
+ await writeDepsFile(Platform.script, |
+ Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation, |
+ packages: packages, |
+ // To track dependencies of this script, we need to use a platform.dill |
+ // file generated for the VM. The dependency on the patched_sdk at the |
+ // BUILD level guarantees that this file already exists. |
+ platform: Uri.base.resolveUri( |
+ new Uri.directory(outDir).resolve('../patched_sdk/platform.dill')), |
+ extraDependencies: deps, |
+ verbose: false, |
+ targetDart2js: false); |
+ |
+ await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); |
+} |
+ |
+_applyPatch( |
+ SdkLibrary library, String sdkLibIn, String patchIn, String sdkOut) { |
+ var libraryOut = path.join(sdkLibIn, library.path); |
+ var libraryIn = libraryOut; |
+ |
+ var libraryFile = getInputFile(libraryIn, canBeMissing: true); |
+ if (libraryFile != null) { |
+ var outPaths = <String>[libraryOut]; |
+ var libraryContents = libraryFile.readAsStringSync(); |
+ |
+ int inputModifyTime = libraryFile.lastModifiedSync().millisecondsSinceEpoch; |
+ var partFiles = <File>[]; |
+ for (var part in parseDirectives(libraryContents).directives) { |
+ if (part is PartDirective) { |
+ var partPath = part.uri.stringValue; |
+ outPaths.add(path.join(path.dirname(libraryOut), partPath)); |
+ |
+ var partFile = |
+ getInputFile(path.join(path.dirname(libraryIn), partPath)); |
+ partFiles.add(partFile); |
+ inputModifyTime = math.max(inputModifyTime, |
+ partFile.lastModifiedSync().millisecondsSinceEpoch); |
+ } |
+ } |
+ |
+ // See if we can find a patch file. |
+ var patchPath = path.join( |
+ patchIn, path.basenameWithoutExtension(libraryIn) + '_patch.dart'); |
+ |
+ var patchFile = getInputFile(patchPath, canBeMissing: true); |
+ if (patchFile != null) { |
+ inputModifyTime = math.max( |
+ inputModifyTime, patchFile.lastModifiedSync().millisecondsSinceEpoch); |
+ } |
+ |
+ // Compute output paths |
+ outPaths = outPaths |
+ .map((p) => path.join(sdkOut, path.relative(p, from: sdkLibIn))) |
+ .toList(); |
+ |
+ // Compare output modify time with input modify time. |
+ bool needsUpdate = false; |
+ for (var outPath in outPaths) { |
+ var outFile = new File(outPath); |
+ if (!outFile.existsSync() || |
+ outFile.lastModifiedSync().millisecondsSinceEpoch < inputModifyTime) { |
+ needsUpdate = true; |
+ break; |
+ } |
+ } |
+ |
+ if (needsUpdate) { |
+ var contents = <String>[libraryContents]; |
+ contents.addAll(partFiles.map((f) => f.readAsStringSync())); |
+ if (patchFile != null) { |
+ var patchContents = patchFile.readAsStringSync(); |
+ contents = _patchLibrary(patchFile.path, contents, patchContents); |
+ } |
+ |
+ for (var i = 0; i < outPaths.length; i++) { |
+ _writeSync(outPaths[i], contents[i]); |
+ } |
+ } |
+ } |
+} |
+ |
/// Writes a file, creating the directory if needed. |
void _writeSync(String filePath, String contents) { |
var outDir = new Directory(path.dirname(filePath)); |