Index: tools/patch_sdk.dart |
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart |
index e51e843fc9e54871d3999c2ef5b80726ec1bc942..bd6654fc0a75f6559a333eac2f82d4e43e240dbb 100644 |
--- a/tools/patch_sdk.dart |
+++ b/tools/patch_sdk.dart |
@@ -74,14 +74,18 @@ void usage(String mode) { |
exit(1); |
} |
+const validModes = const ['vm', 'dart2js', 'flutter']; |
+String mode; |
+bool get forVm => mode == 'vm'; |
+bool get forFlutter => mode == 'flutter'; |
+bool get forDart2js => mode == 'dart2js'; |
+ |
Future _main(List<String> argv) async { |
- if (argv.isEmpty) usage('[vm|dart2js]'); |
- var mode = argv.first; |
- if (mode != 'vm' && mode != 'dart2js') usage('[vm|dart2js]'); |
+ if (argv.isEmpty) usage('[${validModes.join('|')}]'); |
+ mode = argv.first; |
+ if (!validModes.contains(mode)) usage('[${validModes.join('|')}]'); |
if (argv.length != 5) usage(mode); |
- bool forVm = mode == 'vm'; |
- bool forDart2js = mode == 'dart2js'; |
var input = argv[1]; |
var sdkLibIn = path.join(input, 'lib'); |
var patchIn = argv[2]; |
@@ -93,39 +97,44 @@ Future _main(List<String> argv) async { |
// Parse libraries.dart |
var libContents = readInputFile(path.join( |
sdkLibIn, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart')); |
- if (forVm) libContents = _updateLibraryMetadata(sdkOut, libContents); |
- var sdkLibraries = _getSdkLibraries(libContents, forDart2js); |
+ libContents = _updateLibraryMetadata(sdkOut, libContents); |
+ var sdkLibraries = _getSdkLibraries(libContents); |
Map<String, String> locations = <String, String>{}; |
// Enumerate core libraries and apply patches |
for (SdkLibrary library in sdkLibraries) { |
if (forDart2js && library.isVmLibrary) continue; |
- if (forVm && library.isDart2JsLibrary) continue; |
+ if (!forDart2js && library.isDart2JsLibrary) continue; |
_applyPatch(library, sdkLibIn, patchIn, sdkOut, locations); |
} |
- if (forVm) _copyExtraVmLibraries(sdkOut, locations); |
+ _copyExtraLibraries(sdkOut, locations); |
Uri platform = outDirUri.resolve('platform.dill.tmp'); |
Uri outline = outDirUri.resolve('outline.dill'); |
- Uri vmserviceIo = outDirUri.resolve('vmservice_io.dill'); |
Uri librariesJson = outDirUri.resolve("lib/libraries.json"); |
Uri packages = Uri.base.resolveUri(new Uri.file(packagesFile)); |
await _writeSync( |
librariesJson.toFilePath(), JSON.encode({"libraries": locations})); |
- if (forVm) { |
+ if (forVm || forFlutter) { |
+ var vmserviceName = forVm ? 'vmservice_io' : 'vmservice_sky'; |
+ var targetName = forVm ? 'vm_fasta' : 'flutter_fasta'; |
+ Uri vmserviceUri = outDirUri.resolve('$vmserviceName.dill'); |
await fasta.compilePlatform(outDirUri, platform, |
- packages: packages, outlineOutput: outline); |
+ packages: packages, |
+ outlineOutput: outline, |
+ backendTarget: forVm ? 'vm_fasta' : 'flutter_fasta'); |
await fasta.compile([ |
- "--sdk=${outDirUri.toString()}", |
- "--platform=${outline.toString()}", |
- "--packages=${packages.toString()}", |
- "dart:vmservice_io", |
+ "--sdk=$outDirUri", |
+ "--platform=$outline", |
+ "--target=$targetName", |
+ "--packages=$packages", |
+ "dart:$vmserviceName", |
"-o", |
- vmserviceIo.toString() |
+ "$vmserviceUri", |
]); |
} else { |
await dart2js.compilePlatform(outDirUri, platform, |
@@ -134,24 +143,48 @@ Future _main(List<String> argv) async { |
Uri platformFinalLocation = outDirUri.resolve('platform.dill'); |
- // To properly regenerate the patched_sdk, patched_dart2js_sdk, and |
- // platform.dill only when necessary, we track dependencies as follows: |
- // - inputs like the sdk libraries and patch files are covered by the |
- // extraDependencies argument. |
- // - this script and its script dependencies are handled by writeDepsFile |
- // here. |
- // - the internal platform libraries that may affect how this script |
- // runs in the VM are discovered by providing the `platform` argument |
- // below. Regardless of patched_sdk or patched_dart2js_sdk we provide below |
- // the .dill file of patched_sdk (since the script runs in the VM and not |
- // in dart2js). At the BUILD.gn level we have a dependency from |
- // patched_dart2js_sdk to patched_sdk to ensure that file already exists. |
+ // We generate a dependency file for GN to properly regenerate the patched sdk |
+ // folder, outline.dill and platform.dill files when necessary: either when |
+ // the sdk sources change or when this script is updated. In particular: |
+ // |
+ // - sdk changes: we track the actual sources we are compiling. If we are |
+ // building the dart2js sdk, this includes the dart2js-specific patch |
+ // files. |
+ // |
+ // These files are tracked by [deps] and passed below to [writeDepsFile] in |
+ // the extraDependencies argument. |
+ // |
+ // - script updates: we track this script file and any code it imports (even |
+ // sdk libraries). Note that this script runs on the standalone VM, so any |
+ // sdk library used by this script indirectly depends on a VM-specific |
+ // patch file. |
+ // |
+ // These set of files is discovered by `writeDepsFile` below, and the |
+ // [platformForDeps] is always the VM-specific `platform.dill` file. |
+ // |
+ // TODO(sigmund): we should change this: |
+ // - we should rewrite writeDepsFile: fasta could provide an API to crawl |
+ // the dependencies, but anything that is GN specific, should be on |
+ // this file instead. |
+ // |
+ // - We don't need to include sdk dependencies of the script because |
+ // those are already included indirectly (either in [deps] when |
+ // building the sdk for the VM, or via the .GN dependencies in the |
+ // build files for dart2js and flutter). |
+ var platformForDeps = platform; |
+ var sdkDir = outDirUri; |
+ if (forDart2js || forFlutter) { |
+ // Note: this would fail if `../patched_sdk/platform.dill` doesn't exist. We |
+ // added an explicit dependency in the .GN rules so patched_dart2js_sdk (and |
+ // patched_flutter_sdk) depend on patched_sdk to ensure that it exists. |
+ platformForDeps = outDirUri.resolve('../patched_sdk/platform.dill'); |
+ sdkDir = outDirUri.resolve('../patched_sdk/'); |
+ } |
await fasta.writeDepsFile(Platform.script, |
Uri.base.resolveUri(new Uri.file("$outDir.d")), platformFinalLocation, |
- sdk: outDirUri, |
+ sdk: sdkDir, |
packages: packages, |
- platform: |
- forVm ? platform : outDirUri.resolve('../patched_sdk/platform.dill'), |
+ platform: platformForDeps, |
extraDependencies: deps); |
await new File.fromUri(platform).rename(platformFinalLocation.toFilePath()); |
@@ -161,11 +194,9 @@ Future _main(List<String> argv) async { |
/// sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart to include |
/// declarations for vm internal libraries. |
String _updateLibraryMetadata(String sdkOut, String libContents) { |
- // Copy and patch libraries.dart and version |
- libContents = libContents.replaceAll( |
- ' libraries = const {', |
- ''' libraries = const { |
- |
+ if (!forVm && !forFlutter) return libContents; |
+ var extraLibraries = new StringBuffer(); |
+ extraLibraries.write(''' |
"_builtin": const LibraryInfo( |
"_builtin/_builtin.dart", |
categories: "Client,Server", |
@@ -177,7 +208,21 @@ String _updateLibraryMetadata(String sdkOut, String libContents) { |
"profiler/profiler.dart", |
maturity: Maturity.DEPRECATED, |
documented: false), |
-'''); |
+ '''); |
+ |
+ if (forFlutter) { |
+ extraLibraries.write(''' |
+ "ui": const LibraryInfo( |
+ "ui/ui.dart", |
+ categories: "Client,Server", |
+ implementation: true, |
+ documented: false, |
+ platforms: VM_PLATFORM), |
+ '''); |
+ } |
+ |
+ libContents = libContents.replaceAll( |
+ ' libraries = const {', ' libraries = const { $extraLibraries'); |
_writeSync( |
path.join( |
sdkOut, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'), |
@@ -185,32 +230,44 @@ String _updateLibraryMetadata(String sdkOut, String libContents) { |
return libContents; |
} |
-/// Copy internal libraries that are developed under 'runtime/bin/' to the |
-/// patched_sdk folder. |
-_copyExtraVmLibraries(String sdkOut, Map<String, String> locations) { |
+/// Copy internal libraries that are developed outside the sdk folder into the |
+/// patched_sdk folder. For the VM< this includes files under 'runtime/bin/', |
+/// for flutter, this is includes also the ui library. |
+_copyExtraLibraries(String sdkOut, Map<String, String> locations) { |
+ if (forDart2js) return; |
var base = path.fromUri(Platform.script); |
var dartDir = path.dirname(path.dirname(path.absolute(base))); |
- for (var tuple in [ |
- ['_builtin', 'builtin.dart'] |
- ]) { |
- var vmLibrary = tuple[0]; |
- var dartFile = tuple[1]; |
- |
- // The "dart:_builtin" library is only available for the DartVM. |
- var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', dartFile); |
- var builtinLibraryOut = path.join(sdkOut, vmLibrary, '${vmLibrary}.dart'); |
- _writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn)); |
- locations[vmLibrary] = path.join(vmLibrary, '${vmLibrary}.dart'); |
- } |
+ var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', 'builtin.dart'); |
+ var builtinLibraryOut = path.join(sdkOut, '_builtin', '_builtin.dart'); |
+ _writeSync(builtinLibraryOut, readInputFile(builtinLibraryIn)); |
+ locations['_builtin'] = path.join('_builtin', '_builtin.dart'); |
for (var file in ['loader.dart', 'server.dart', 'vmservice_io.dart']) { |
var libraryIn = path.join(dartDir, 'runtime', 'bin', 'vmservice', file); |
var libraryOut = path.join(sdkOut, 'vmservice_io', file); |
_writeSync(libraryOut, readInputFile(libraryIn)); |
} |
- locations["vmservice_io"] = "vmservice_io/vmservice_io.dart"; |
- locations["_vmservice"] = "vmservice/vmservice.dart"; |
+ |
+ locations[forVm ? "vmservice_io" : "vmservice_sky"] = |
+ path.join('vmservice_io', 'vmservice_io.dart'); |
+ locations["_vmservice"] = path.join('vmservice', 'vmservice.dart'); |
+ |
+ if (forFlutter) { |
+ // Flutter repo has this layout: |
+ // engine/src/ |
+ // dart/ |
+ // flutter/ |
+ var srcDir = path.dirname(path.dirname(path.dirname(path.absolute(base)))); |
+ var uiLibraryInDir = path.join(srcDir, 'flutter', 'lib', 'ui'); |
+ for (var file in new Directory(uiLibraryInDir).listSync()) { |
+ if (!file.path.endsWith('.dart')) continue; |
+ var name = path.basename(file.path); |
+ var uiLibraryOut = path.join(sdkOut, 'ui', name); |
+ _writeSync(uiLibraryOut, readInputFile(file.path)); |
+ } |
+ locations['ui'] = 'ui/ui.dart'; |
+ } |
} |
_applyPatch(SdkLibrary library, String sdkLibIn, String patchIn, String sdkOut, |
@@ -621,8 +678,8 @@ class _StringEdit implements Comparable<_StringEdit> { |
} |
} |
-List<SdkLibrary> _getSdkLibraries(String contents, bool useDart2js) { |
- var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(useDart2js); |
+List<SdkLibrary> _getSdkLibraries(String contents) { |
+ var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(forDart2js); |
parseCompilationUnit(contents).accept(libraryBuilder); |
return libraryBuilder.librariesMap.sdkLibraries; |
} |