Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: tools/patch_sdk.dart

Issue 2832353002: Add support for building patched_sdk and platform.dill for dart2js: (Closed)
Patch Set: rebase Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698