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

Side by Side Diff: tools/patch_sdk.dart

Issue 2832353002: Add support for building patched_sdk and platform.dill for dart2js: (Closed)
Patch Set: fix .gn circularity by removing use of rebase_path 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
« no previous file with comments | « runtime/vm/BUILD.gn ('k') | utils/compiler/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
11 import 'dart:async'; 11 import 'dart:async';
12 import 'dart:math' as math; 12 import 'dart:math' as math;
13 13
14 import 'package:analyzer/analyzer.dart'; 14 import 'package:analyzer/analyzer.dart';
15 import 'package:analyzer/src/generated/sdk.dart'; 15 import 'package:analyzer/src/generated/sdk.dart';
16 import 'package:path/path.dart' as path; 16 import 'package:path/path.dart' as path;
17 17
18 import 'package:front_end/src/fasta/fasta.dart' 18 import 'package:front_end/src/fasta/fasta.dart' as fasta
19 show compilePlatform, writeDepsFile; 19 show compilePlatform, writeDepsFile;
20 20
21 import 'package:compiler/src/kernel/fasta_support.dart' as dart2js
22 show compilePlatform;
23
21 /// Set of input files that were read by this script to generate patched SDK. 24 /// Set of input files that were read by this script to generate patched SDK.
22 /// We will dump it out into the depfile for ninja to use. 25 /// We will dump it out into the depfile for ninja to use.
23 /// 26 ///
24 /// For more information see GN and Ninja references: 27 /// For more information see GN and Ninja references:
25 /// https://chromium.googlesource.com/chromium/src/+/56807c6cb383140af0c03da8 f6731d77785d7160/tools/gn/docs/reference.md#depfile_string_File-name-for-input-d ependencies-for-actions 28 /// https://chromium.googlesource.com/chromium/src/+/56807c6cb383140af0c03da8 f6731d77785d7160/tools/gn/docs/reference.md#depfile_string_File-name-for-input-d ependencies-for-actions
26 /// https://ninja-build.org/manual.html#_depfile 29 /// https://ninja-build.org/manual.html#_depfile
27 /// 30 ///
28 final deps = new Set<Uri>(); 31 final deps = new Set<Uri>();
29 32
30 /// Create [File] object from the given path and register it as a dependency. 33 /// Create [File] object from the given path and register it as a dependency.
(...skipping 14 matching lines...) Expand all
45 48
46 Future main(List<String> argv) async { 49 Future main(List<String> argv) async {
47 var port = new RawReceivePort(); 50 var port = new RawReceivePort();
48 try { 51 try {
49 await _main(argv); 52 await _main(argv);
50 } finally { 53 } finally {
51 port.close(); 54 port.close();
52 } 55 }
53 } 56 }
54 57
58 void usage(String mode) {
59 var base = path.fromUri(Platform.script);
60 final self = path.relative(base);
61 print('Usage: $self $mode 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(
68 path.join(repositoryDir, 'out', 'DebugX64', 'obj', 'gen', 'patched_sdk'));
69 final packagesExample = path.relative(path.join(repositoryDir, '.packages'));
70 print('For example:');
71 print('\$ $self vm $sdkExample $patchExample $outExample $packagesExample');
72
73 exit(1);
74 }
75
55 Future _main(List<String> argv) async { 76 Future _main(List<String> argv) async {
56 var base = path.fromUri(Platform.script); 77 var mode = argv.first;
57 var dartDir = path.dirname(path.dirname(path.absolute(base))); 78 if (mode != 'vm' && mode != 'dart2js') usage('[vm|dart2js]');
79 if (argv.length != 5) usage(mode);
58 80
59 if (argv.length != 5 || argv.first != 'vm') { 81 bool forVm = mode == 'vm';
60 final self = path.relative(base); 82 bool forDart2js = mode == 'dart2js';
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 }
74
75 var mode = argv[0];
76 assert(mode == "vm");
77 var input = argv[1]; 83 var input = argv[1];
78 var sdkLibIn = path.join(input, 'lib'); 84 var sdkLibIn = path.join(input, 'lib');
79 var patchIn = argv[2]; 85 var patchIn = argv[2];
80 var outDir = argv[3]; 86 var outDir = argv[3];
87 var outDirUri = Uri.base.resolveUri(new Uri.directory(outDir));
81 var sdkOut = path.join(outDir, 'lib'); 88 var sdkOut = path.join(outDir, 'lib');
82 var packagesFile = argv[4]; 89 var packagesFile = argv[4];
83 90
84 // Copy and patch libraries.dart and version 91 // Parse libraries.dart
85 var libContents = readInputFile(path.join( 92 var libContents = readInputFile(path.join(
86 sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart')); 93 sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'));
94 if (forVm) libContents = _updateLibraryMetadata(sdkOut, libContents);
95 var sdkLibraries = _getSdkLibraries(libContents);
96
97 // Enumerate core libraries and apply patches
98 for (SdkLibrary library in sdkLibraries) {
99 if (forDart2js && library.isVmLibrary) continue;
100 if (forVm && library.isDart2JsLibrary) continue;
101 _applyPatch(library, sdkLibIn, patchIn, sdkOut);
102 }
103
104 if (forVm) _copyExtraVmLibraries(sdkOut);
105
106 Uri platform = outDirUri.resolve('platform.dill.tmp');
107 Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile));
108 if (forVm) {
109 await fasta.compilePlatform(outDirUri, platform, packages: packages);
110 } else {
111 await dart2js.compilePlatform(outDirUri, platform, packages: packages);
112 }
113
114 Uri platformFinalLocation = outDirUri.resolve('platform.dill');
115
116 // To properly regenerate the patched_sdk, patched_dart2js_sdk, and
117 // platform.dill only when necessary, we track dependencies as follows:
118 // - inputs like the sdk libraries and patch files are covered by the
119 // extraDependencies argument.
120 // - this script and its script dependencies are handled by writeDepsFile
121 // here.
122 // - the internal platform libraries that may affect how this script
123 // runs in the VM are discovered by providing the `platform` argument
124 // below. Regardless of patched_sdk or patched_dart2js_sdk we provide below
125 // the .dill file of patched_sdk (since the script runs in the VM and not
126 // in dart2js). At the BUILD.gn level we have a dependency from
127 // patched_dart2js_sdk to patched_sdk to ensure that file already exists.
128 await fasta.writeDepsFile(Platform.script,
129 Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation,
130 packages: packages,
131 platform:
132 forVm ? platform : outDirUri.resolve('../patched_sdk/platform.dill'),
133 extraDependencies: deps,
134 verbose: false);
135
136 await new File.fromUri(platform).rename(platformFinalLocation.toFilePath());
137 }
138
139 /// Updates the contents of
140 /// sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart to include
141 /// declarations for vm internal libraries.
142 String _updateLibraryMetadata(String sdkOut, String libContents) {
143 // Copy and patch libraries.dart and version
87 libContents = libContents.replaceAll( 144 libContents = libContents.replaceAll(
88 ' libraries = const {', 145 ' libraries = const {',
89 ''' libraries = const { 146 ''' libraries = const {
90 147
91 "_builtin": const LibraryInfo( 148 "_builtin": const LibraryInfo(
92 "_builtin/_builtin.dart", 149 "_builtin/_builtin.dart",
93 categories: "Client,Server", 150 categories: "Client,Server",
94 implementation: true, 151 implementation: true,
95 documented: false, 152 documented: false,
96 platforms: VM_PLATFORM), 153 platforms: VM_PLATFORM),
(...skipping 13 matching lines...) Expand all
110 "vmservice_io/vmservice_io.dart", 167 "vmservice_io/vmservice_io.dart",
111 implementation: true, 168 implementation: true,
112 documented: false, 169 documented: false,
113 platforms: VM_PLATFORM), 170 platforms: VM_PLATFORM),
114 171
115 '''); 172 ''');
116 _writeSync( 173 _writeSync(
117 path.join( 174 path.join(
118 sdkOut, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'), 175 sdkOut, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'),
119 libContents); 176 libContents);
177 return libContents;
178 }
120 179
121 // Parse libraries.dart 180 /// Copy internal libraries that are developed under 'runtime/bin/' to the
122 var sdkLibraries = _getSdkLibraries(libContents); 181 /// patched_sdk folder.
123 182 _copyExtraVmLibraries(String sdkOut) {
124 // Enumerate core libraries and apply patches 183 var base = path.fromUri(Platform.script);
125 for (SdkLibrary library in sdkLibraries) { 184 var dartDir = path.dirname(path.dirname(path.absolute(base)));
126 if (library.isDart2JsLibrary) {
127 continue;
128 }
129
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 }
195 185
196 for (var tuple in [ 186 for (var tuple in [
197 ['_builtin', 'builtin.dart'] 187 ['_builtin', 'builtin.dart']
198 ]) { 188 ]) {
199 var vmLibrary = tuple[0]; 189 var vmLibrary = tuple[0];
200 var dartFile = tuple[1]; 190 var dartFile = tuple[1];
201 191
202 // The "dart:_builtin" library is only available for the DartVM. 192 // The "dart:_builtin" library is only available for the DartVM.
203 var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', dartFile); 193 var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', dartFile);
204 var builtinLibraryOut = path.join(sdkOut, vmLibrary, '${vmLibrary}.dart'); 194 var builtinLibraryOut = path.join(sdkOut, vmLibrary, '${vmLibrary}.dart');
205 _writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn)); 195 _writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn));
206 } 196 }
207 197
208 for (var file in ['loader.dart', 'server.dart', 'vmservice_io.dart']) { 198 for (var file in ['loader.dart', 'server.dart', 'vmservice_io.dart']) {
209 var libraryIn = path.join(dartDir, 'runtime', 'bin', 'vmservice', file); 199 var libraryIn = path.join(dartDir, 'runtime', 'bin', 'vmservice', file);
210 var libraryOut = path.join(sdkOut, 'vmservice_io', file); 200 var libraryOut = path.join(sdkOut, 'vmservice_io', file);
211 _writeSync(libraryOut, readInputFile(libraryIn)); 201 _writeSync(libraryOut, readInputFile(libraryIn));
212 } 202 }
203 }
213 204
214 Uri platform = Uri.base 205 _applyPatch(
215 .resolveUri(new Uri.directory(outDir).resolve('platform.dill.tmp')); 206 SdkLibrary library, String sdkLibIn, String patchIn, String sdkOut) {
216 Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile)); 207 var libraryOut = path.join(sdkLibIn, library.path);
217 await compilePlatform( 208 var libraryIn = libraryOut;
218 Uri.base.resolveUri(new Uri.directory(outDir)), platform,
219 packages: packages, verbose: false);
220 209
221 Uri platformFinalLocation = 210 var libraryFile = getInputFile(libraryIn, canBeMissing: true);
222 Uri.base.resolveUri(new Uri.directory(outDir).resolve('platform.dill')); 211 if (libraryFile != null) {
212 var outPaths = <String>[libraryOut];
213 var libraryContents = libraryFile.readAsStringSync();
223 214
224 await writeDepsFile(Platform.script, 215 int inputModifyTime = libraryFile.lastModifiedSync().millisecondsSinceEpoch;
225 Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation, 216 var partFiles = <File>[];
226 packages: packages, 217 for (var part in parseDirectives(libraryContents).directives) {
227 platform: platform, 218 if (part is PartDirective) {
228 extraDependencies: deps, 219 var partPath = part.uri.stringValue;
229 verbose: false); 220 outPaths.add(path.join(path.dirname(libraryOut), partPath));
230 221
231 await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); 222 var partFile =
223 getInputFile(path.join(path.dirname(libraryIn), partPath));
224 partFiles.add(partFile);
225 inputModifyTime = math.max(inputModifyTime,
226 partFile.lastModifiedSync().millisecondsSinceEpoch);
227 }
228 }
229
230 // See if we can find a patch file.
231 var patchPath = path.join(
232 patchIn, path.basenameWithoutExtension(libraryIn) + '_patch.dart');
233
234 var patchFile = getInputFile(patchPath, canBeMissing: true);
235 if (patchFile != null) {
236 inputModifyTime = math.max(
237 inputModifyTime, patchFile.lastModifiedSync().millisecondsSinceEpoch);
238 }
239
240 // Compute output paths
241 outPaths = outPaths
242 .map((p) => path.join(sdkOut, path.relative(p, from: sdkLibIn)))
243 .toList();
244
245 // Compare output modify time with input modify time.
246 bool needsUpdate = false;
247 for (var outPath in outPaths) {
248 var outFile = new File(outPath);
249 if (!outFile.existsSync() ||
250 outFile.lastModifiedSync().millisecondsSinceEpoch < inputModifyTime) {
251 needsUpdate = true;
252 break;
253 }
254 }
255
256 if (needsUpdate) {
257 var contents = <String>[libraryContents];
258 contents.addAll(partFiles.map((f) => f.readAsStringSync()));
259 if (patchFile != null) {
260 var patchContents = patchFile.readAsStringSync();
261 contents = _patchLibrary(patchFile.path, contents, patchContents);
262 }
263
264 for (var i = 0; i < outPaths.length; i++) {
265 _writeSync(outPaths[i], contents[i]);
266 }
267 }
268 }
232 } 269 }
233 270
234 /// Writes a file, creating the directory if needed. 271 /// Writes a file, creating the directory if needed.
235 void _writeSync(String filePath, String contents) { 272 void _writeSync(String filePath, String contents) {
236 var outDir = new Directory(path.dirname(filePath)); 273 var outDir = new Directory(path.dirname(filePath));
237 if (!outDir.existsSync()) outDir.createSync(recursive: true); 274 if (!outDir.existsSync()) outDir.createSync(recursive: true);
238 275
239 new File(filePath).writeAsStringSync(contents); 276 new File(filePath).writeAsStringSync(contents);
240 } 277 }
241 278
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 if (diff != 0) return diff; 606 if (diff != 0) return diff;
570 return end - other.end; 607 return end - other.end;
571 } 608 }
572 } 609 }
573 610
574 List<SdkLibrary> _getSdkLibraries(String contents) { 611 List<SdkLibrary> _getSdkLibraries(String contents) {
575 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true); 612 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true);
576 parseCompilationUnit(contents).accept(libraryBuilder); 613 parseCompilationUnit(contents).accept(libraryBuilder);
577 return libraryBuilder.librariesMap.sdkLibraries; 614 return libraryBuilder.librariesMap.sdkLibraries;
578 } 615 }
OLDNEW
« no previous file with comments | « runtime/vm/BUILD.gn ('k') | utils/compiler/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698