From 7138541d232ec39aebc01c442bbfb751cd62dd8e Mon Sep 17 00:00:00 2001 From: Dan Rubel Date: Wed, 15 Feb 2017 17:37:00 -0500 Subject: [PATCH] new --kernel option for flutter run to use precompiled kernel code (#8191) --- .../lib/src/android/android_device.dart | 3 +++ .../lib/src/commands/build_apk.dart | 5 +++++ .../flutter_tools/lib/src/commands/run.dart | 6 ++++++ packages/flutter_tools/lib/src/device.dart | 2 ++ packages/flutter_tools/lib/src/flx.dart | 19 +++++++++++++++++++ .../flutter_tools/lib/src/ios/devices.dart | 2 ++ .../flutter_tools/lib/src/ios/simulators.dart | 2 ++ packages/flutter_tools/lib/src/run_hot.dart | 8 ++++++++ 8 files changed, 47 insertions(+) diff --git a/packages/flutter_tools/lib/src/android/android_device.dart b/packages/flutter_tools/lib/src/android/android_device.dart index cc6d21ae335..ff6389fef25 100644 --- a/packages/flutter_tools/lib/src/android/android_device.dart +++ b/packages/flutter_tools/lib/src/android/android_device.dart @@ -15,6 +15,7 @@ import '../base/process.dart'; import '../base/process_manager.dart'; import '../build_info.dart'; import '../commands/build_apk.dart'; +import '../devfs.dart'; import '../device.dart'; import '../globals.dart'; import '../protocol_discovery.dart'; @@ -268,6 +269,7 @@ class AndroidDevice extends Device { String route, DebuggingOptions debuggingOptions, Map platformArgs, + DevFSContent kernelContent, bool prebuiltApplication: false, bool applicationNeedsRebuild: false, }) async { @@ -287,6 +289,7 @@ class AndroidDevice extends Device { await buildApk(platform, target: mainPath, buildMode: debuggingOptions.buildMode, + kernelContent: kernelContent, applicationNeedsRebuild: applicationNeedsRebuild ); } diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart index 19b74d4c57f..8f64bea660d 100644 --- a/packages/flutter_tools/lib/src/commands/build_apk.dart +++ b/packages/flutter_tools/lib/src/commands/build_apk.dart @@ -15,6 +15,7 @@ import '../base/process.dart'; import '../base/process_manager.dart'; import '../base/utils.dart'; import '../build_info.dart'; +import '../devfs.dart'; import '../flx.dart' as flx; import '../globals.dart'; import '../resident_runner.dart'; @@ -481,6 +482,7 @@ Future buildAndroid( String target, String flxPath, String aotPath, + DevFSContent kernelContent, ApkKeystoreInfo keystore, bool applicationNeedsRebuild: false }) async { @@ -545,6 +547,7 @@ Future buildAndroid( // Build the FLX. flxPath = await flx.buildFlx( mainPath: findMainDartFile(target), + kernelContent: kernelContent, precompiledSnapshot: isAotBuildMode(buildMode), includeRobotoFonts: false); @@ -614,6 +617,7 @@ Future buildApk( TargetPlatform platform, { String target, BuildMode buildMode: BuildMode.debug, + DevFSContent kernelContent, bool applicationNeedsRebuild: false, }) async { if (isProjectUsingGradle()) { @@ -632,6 +636,7 @@ Future buildApk( buildMode, force: false, target: target, + kernelContent: kernelContent, applicationNeedsRebuild: applicationNeedsRebuild, ); } diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index 38385b30273..154cf5b4ee4 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -94,6 +94,11 @@ class RunCommand extends RunCommandBase { argParser.addOption('use-application-binary', hide: !verboseHelp, help: 'Specify a pre-built application binary to use when running.'); + argParser.addOption('kernel', + hide: !verboseHelp, + help: 'Path to a pre-built kernel blob to use when running.\n' + 'This option only exists for testing new kernel code execution on devices\n' + 'and is not needed during normal application development.'); argParser.addOption('snapshotter', hide: !verboseHelp, help: 'Specify the path to the sky_snapshot binary.'); @@ -259,6 +264,7 @@ class RunCommand extends RunCommandBase { debuggingOptions: options, benchmarkMode: argResults['benchmark'], applicationBinary: argResults['use-application-binary'], + kernelFilePath: argResults['kernel'], projectRootPath: argResults['project-root'], packagesFilePath: argResults['packages'], projectAssets: argResults['project-assets'], diff --git a/packages/flutter_tools/lib/src/device.dart b/packages/flutter_tools/lib/src/device.dart index 2f74b9caf7c..6a0f76f542c 100644 --- a/packages/flutter_tools/lib/src/device.dart +++ b/packages/flutter_tools/lib/src/device.dart @@ -13,6 +13,7 @@ import 'base/file_system.dart'; import 'base/os.dart'; import 'base/utils.dart'; import 'build_info.dart'; +import 'devfs.dart'; import 'globals.dart'; import 'ios/devices.dart'; import 'ios/simulators.dart'; @@ -207,6 +208,7 @@ abstract class Device { String route, DebuggingOptions debuggingOptions, Map platformArgs, + DevFSContent kernelContent, bool prebuiltApplication: false, bool applicationNeedsRebuild: false }); diff --git a/packages/flutter_tools/lib/src/flx.dart b/packages/flutter_tools/lib/src/flx.dart index 4d7e541d7a4..73b3fee470c 100644 --- a/packages/flutter_tools/lib/src/flx.dart +++ b/packages/flutter_tools/lib/src/flx.dart @@ -21,8 +21,10 @@ const String defaultManifestPath = 'pubspec.yaml'; String get defaultFlxOutputPath => fs.path.join(getBuildDirectory(), 'app.flx'); String get defaultSnapshotPath => fs.path.join(getBuildDirectory(), 'snapshot_blob.bin'); String get defaultDepfilePath => fs.path.join(getBuildDirectory(), 'snapshot_blob.bin.d'); +String get defaultKernelPath => fs.path.join(getBuildDirectory(), 'kernel_blob.bin'); const String defaultPrivateKeyPath = 'privatekey.der'; +const String _kKernelKey = 'kernel_blob.bin'; const String _kSnapshotKey = 'snapshot_blob.bin'; Future createSnapshot({ @@ -55,6 +57,7 @@ Future createSnapshot({ /// Return `null` on failure. Future buildFlx({ String mainPath: defaultMainPath, + DevFSContent kernelContent, bool precompiledSnapshot: false, bool includeRobotoFonts: true }) async { @@ -62,6 +65,7 @@ Future buildFlx({ snapshotPath: defaultSnapshotPath, outputPath: defaultFlxOutputPath, mainPath: mainPath, + kernelContent: kernelContent, precompiledSnapshot: precompiledSnapshot, includeRobotoFonts: includeRobotoFonts ); @@ -78,18 +82,29 @@ Future build({ String privateKeyPath: defaultPrivateKeyPath, String workingDirPath, String packagesPath, + String kernelPath, + DevFSContent kernelContent, bool precompiledSnapshot: false, bool includeRobotoFonts: true, bool reportLicensedPackages: false }) async { snapshotterPath ??= tools.getHostToolPath(HostTool.SkySnapshot); outputPath ??= defaultFlxOutputPath; + kernelPath ??= defaultKernelPath; snapshotPath ??= defaultSnapshotPath; depfilePath ??= defaultDepfilePath; workingDirPath ??= getAssetBuildDirectory(); packagesPath ??= fs.path.absolute(PackageMap.globalPackagesPath); File snapshotFile; + File kernelFile; + if (kernelContent != null) { + // TODO(danrubel) in the future, call the VM to generate this file + kernelFile = fs.file(kernelPath); + IOSink sink = kernelFile.openWrite(); + await sink.addStream(kernelContent.contentsAsStream()); + sink.close(); + } if (!precompiledSnapshot) { ensureDirectoryExists(snapshotPath); @@ -110,6 +125,7 @@ Future build({ return assemble( manifestPath: manifestPath, + kernelFile: kernelFile, snapshotFile: snapshotFile, outputPath: outputPath, privateKeyPath: privateKeyPath, @@ -122,6 +138,7 @@ Future build({ Future assemble({ String manifestPath, + File kernelFile, File snapshotFile, String outputPath, String privateKeyPath: defaultPrivateKeyPath, @@ -154,6 +171,8 @@ Future assemble({ // Add all entries from the asset bundle. zipBuilder.entries.addAll(assetBundle.entries); + if (kernelFile != null) + zipBuilder.entries[_kKernelKey] = new DevFSFileContent(kernelFile); if (snapshotFile != null) zipBuilder.entries[_kSnapshotKey] = new DevFSFileContent(snapshotFile); diff --git a/packages/flutter_tools/lib/src/ios/devices.dart b/packages/flutter_tools/lib/src/ios/devices.dart index 4fd931ebdc5..f15a9db9f95 100644 --- a/packages/flutter_tools/lib/src/ios/devices.dart +++ b/packages/flutter_tools/lib/src/ios/devices.dart @@ -13,6 +13,7 @@ import '../base/platform.dart' as p; import '../base/process.dart'; import '../base/process_manager.dart'; import '../build_info.dart'; +import '../devfs.dart'; import '../device.dart'; import '../doctor.dart'; import '../globals.dart'; @@ -188,6 +189,7 @@ class IOSDevice extends Device { DebuggingOptions debuggingOptions, Map platformArgs, bool prebuiltApplication: false, + DevFSContent kernelContent, bool applicationNeedsRebuild: false, }) async { if (!prebuiltApplication) { diff --git a/packages/flutter_tools/lib/src/ios/simulators.dart b/packages/flutter_tools/lib/src/ios/simulators.dart index 432f373835b..69143fdc6b0 100644 --- a/packages/flutter_tools/lib/src/ios/simulators.dart +++ b/packages/flutter_tools/lib/src/ios/simulators.dart @@ -15,6 +15,7 @@ import '../base/platform.dart' as p; import '../base/process.dart'; import '../base/process_manager.dart'; import '../build_info.dart'; +import '../devfs.dart'; import '../device.dart'; import '../flx.dart' as flx; import '../globals.dart'; @@ -414,6 +415,7 @@ class IOSSimulator extends Device { String route, DebuggingOptions debuggingOptions, Map platformArgs, + DevFSContent kernelContent, bool prebuiltApplication: false, bool applicationNeedsRebuild: false, }) async { diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index e4724299e91..b731c329f4f 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -42,6 +42,7 @@ class HotRunner extends ResidentRunner { bool usesTerminalUI: true, this.benchmarkMode: false, this.applicationBinary, + this.kernelFilePath, String projectRootPath, String packagesFilePath, String projectAssets, @@ -64,6 +65,7 @@ class HotRunner extends ResidentRunner { final Map benchmarkData = new Map(); // The initial launch is from a snapshot. bool _runningFromSnapshot = true; + String kernelFilePath; @override Future run({ @@ -156,6 +158,11 @@ class HotRunner extends ResidentRunner { String modeName = getModeName(debuggingOptions.buildMode); printStatus('Launching ${getDisplayPath(mainPath)} on ${device.name} in $modeName mode...'); + // Include kernel code + DevFSContent kernelContent; + if (kernelFilePath != null) + kernelContent = new DevFSFileContent(fs.file(kernelFilePath)); + // Start the application. Future futureResult = device.startApp( package, @@ -165,6 +172,7 @@ class HotRunner extends ResidentRunner { platformArgs: platformArgs, route: route, prebuiltApplication: prebuiltMode, + kernelContent: kernelContent, applicationNeedsRebuild: shouldBuild || hasDirtyDependencies() );