diff --git a/packages/flutter_tools/gradle/flutter.gradle b/packages/flutter_tools/gradle/flutter.gradle index 72ebf84f83a..04783d267de 100644 --- a/packages/flutter_tools/gradle/flutter.gradle +++ b/packages/flutter_tools/gradle/flutter.gradle @@ -227,6 +227,15 @@ class FlutterPlugin implements Plugin { previewDart2Value = project.property('preview-dart-2') } + String extraFrontEndOptionsValue = null + if (project.hasProperty('extra-front-end-options')) { + extraFrontEndOptionsValue = project.property('extra-front-end-options') + } + String extraGenSnapshotOptionsValue = null + if (project.hasProperty('extra-gen-snapshot-options')) { + extraGenSnapshotOptionsValue = project.property('extra-gen-snapshot-options') + } + project.android.applicationVariants.all { variant -> String flutterBuildMode = buildModeFor(variant.buildType) if (flutterBuildMode == 'debug' && project.tasks.findByName('flutterBuildX86Jar')) { @@ -259,6 +268,8 @@ class FlutterPlugin implements Plugin { previewDart2 previewDart2Value sourceDir project.file(project.flutter.source) intermediateDir project.file("${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/flutter/${variant.name}") + extraFrontEndOptions extraFrontEndOptionsValue + extraGenSnapshotOptions extraGenSnapshotOptionsValue } Task copyFlxTask = project.tasks.create(name: "copyFlutterAssets${variant.name.capitalize()}", type: Copy) { @@ -285,10 +296,14 @@ abstract class BaseFlutterTask extends DefaultTask { String localEngineSrcPath @Input String targetPath - @Optional + @Optional @Input Boolean previewDart2 File sourceDir File intermediateDir + @Optional @Input + String extraFrontEndOptions + @Optional @Input + String extraGenSnapshotOptions @OutputFile File getDependenciesFile() { @@ -322,6 +337,12 @@ abstract class BaseFlutterTask extends DefaultTask { if (previewDart2) { args "--preview-dart-2" } + if (extraFrontEndOptions != null) { + args "--extra-front-end-options", "${extraFrontEndOptions}" + } + if (extraGenSnapshotOptions != null) { + args "--extra-gen-snapshot-options", "${extraGenSnapshotOptions}" + } args "--${buildMode}" } } diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart index db4acac9bf5..6a867c6a6ca 100644 --- a/packages/flutter_tools/lib/src/android/gradle.dart +++ b/packages/flutter_tools/lib/src/android/gradle.dart @@ -291,6 +291,10 @@ Future _buildGradleProjectV2(String gradle, BuildInfo buildInfo, String ta } if (buildInfo.previewDart2) command.add('-Ppreview-dart-2=true'); + if (buildInfo.extraFrontEndOptions != null) + command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions}'); + if (buildInfo.extraGenSnapshotOptions != null) + command.add('-Pextra-gen-snapshot-options=${buildInfo.extraGenSnapshotOptions}'); command.add(assembleTask); final int exitCode = await runCommandAndStreamOutput( command, diff --git a/packages/flutter_tools/lib/src/build_info.dart b/packages/flutter_tools/lib/src/build_info.dart index b4be334fa55..672c43bc56d 100644 --- a/packages/flutter_tools/lib/src/build_info.dart +++ b/packages/flutter_tools/lib/src/build_info.dart @@ -10,7 +10,10 @@ import 'globals.dart'; /// Information about a build to be performed or used. class BuildInfo { - const BuildInfo(this.mode, this.flavor, { this.previewDart2 }); + const BuildInfo(this.mode, this.flavor, + {this.previewDart2, + this.extraFrontEndOptions, + this.extraGenSnapshotOptions}); final BuildMode mode; /// Represents a custom Android product flavor or an Xcode scheme, null for @@ -24,6 +27,12 @@ class BuildInfo { // Whether build should be done using Dart2 Frontend parser. final bool previewDart2; + /// Extra command-line options for front-end. + final String extraFrontEndOptions; + + /// Extra command-line options for gen_snapshot. + final String extraGenSnapshotOptions; + static const BuildInfo debug = const BuildInfo(BuildMode.debug, null); static const BuildInfo profile = const BuildInfo(BuildMode.profile, null); static const BuildInfo release = const BuildInfo(BuildMode.release, null); diff --git a/packages/flutter_tools/lib/src/commands/build_aot.dart b/packages/flutter_tools/lib/src/commands/build_aot.dart index 01f1ef627db..0e30bd46fe8 100644 --- a/packages/flutter_tools/lib/src/commands/build_aot.dart +++ b/packages/flutter_tools/lib/src/commands/build_aot.dart @@ -17,6 +17,7 @@ import '../compile.dart'; import '../dart/package_map.dart'; import '../globals.dart'; import '../resident_runner.dart'; +import '../runner/flutter_command.dart'; import 'build.dart'; // Files generated by the ahead-of-time snapshot builder. @@ -37,7 +38,17 @@ class BuildAotCommand extends BuildSubCommand { ) ..addFlag('interpreter') ..addFlag('quiet', defaultsTo: false) - ..addFlag('preview-dart-2', negatable: false); + ..addFlag('preview-dart-2', negatable: false) + ..addOption(FlutterOptions.kExtraFrontEndOptions, + allowMultiple: true, + splitCommas: true, + hide: true, + ) + ..addOption(FlutterOptions.kExtraGenSnapshotOptions, + allowMultiple: true, + splitCommas: true, + hide: true, + ); } @override @@ -67,6 +78,8 @@ class BuildAotCommand extends BuildSubCommand { outputPath: argResults['output-dir'], interpreter: argResults['interpreter'], previewDart2: argResults['preview-dart-2'], + extraFrontEndOptions: argResults[FlutterOptions.kExtraFrontEndOptions], + extraGenSnapshotOptions: argResults[FlutterOptions.kExtraGenSnapshotOptions], ); status?.stop(); @@ -95,6 +108,8 @@ Future buildAotSnapshot( String outputPath, bool interpreter: false, bool previewDart2: false, + List extraFrontEndOptions, + List extraGenSnapshotOptions, }) async { outputPath ??= getAotBuildDirectory(); try { @@ -105,6 +120,8 @@ Future buildAotSnapshot( outputPath: outputPath, interpreter: interpreter, previewDart2: previewDart2, + extraFrontEndOptions: extraFrontEndOptions, + extraGenSnapshotOptions: extraGenSnapshotOptions, ); } on String catch (error) { // Catch the String exceptions thrown from the `runCheckedSync` methods below. @@ -121,6 +138,8 @@ Future _buildAotSnapshot( String outputPath, bool interpreter: false, bool previewDart2: false, + List extraFrontEndOptions, + List extraGenSnapshotOptions, }) async { outputPath ??= getAotBuildDirectory(); if (!isAotBuildMode(buildMode) && !interpreter) { @@ -220,6 +239,14 @@ Future _buildAotSnapshot( '--causal_async_stacks', ]; + if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty) + printTrace("Extra front-end options: $extraFrontEndOptions"); + + if ((extraGenSnapshotOptions != null) && extraGenSnapshotOptions.isNotEmpty) { + printTrace("Extra gen-snapshot options: $extraGenSnapshotOptions"); + genSnapshotCmd.addAll(extraGenSnapshotOptions); + } + if (!interpreter) { genSnapshotCmd.add('--embedder_entry_points_manifest=$vmEntryPoints'); genSnapshotCmd.add('--embedder_entry_points_manifest=$ioEntryPoints'); @@ -280,6 +307,7 @@ Future _buildAotSnapshot( mainPath = await compile( sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath), mainPath: mainPath, + extraFrontEndOptions: extraFrontEndOptions, ); } diff --git a/packages/flutter_tools/lib/src/commands/run.dart b/packages/flutter_tools/lib/src/commands/run.dart index 6afefa96627..9d2cf3638b5 100644 --- a/packages/flutter_tools/lib/src/commands/run.dart +++ b/packages/flutter_tools/lib/src/commands/run.dart @@ -155,6 +155,9 @@ class RunCommand extends RunCommandBase { 'measure the startup time and the app restart time, write the\n' 'results out to "refresh_benchmark.json", and exit. This flag is\n' 'intended for use in generating automated flutter benchmarks.'); + + argParser.addOption(FlutterOptions.kExtraFrontEndOptions, hide: true); + argParser.addOption(FlutterOptions.kExtraGenSnapshotOptions, hide: true); } List devices; diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart index 961c5a6afae..b927f5a4e0f 100644 --- a/packages/flutter_tools/lib/src/compile.dart +++ b/packages/flutter_tools/lib/src/compile.dart @@ -56,7 +56,10 @@ class _StdoutHandler { } } -Future compile({String sdkRoot, String mainPath}) async { +Future compile( + {String sdkRoot, + String mainPath, + List extraFrontEndOptions}) async { final String frontendServer = artifacts.getArtifactPath( Artifact.frontendServerSnapshotForEngineDartSdk ); @@ -64,13 +67,18 @@ Future compile({String sdkRoot, String mainPath}) async { // This is a URI, not a file path, so the forward slash is correct even on Windows. if (!sdkRoot.endsWith('/')) sdkRoot = '$sdkRoot/'; - final Process server = await processManager.start([ + final List command = [ _dartExecutable(), frontendServer, '--sdk-root', sdkRoot, - mainPath - ]).catchError((dynamic error, StackTrace stack) { + ]; + if (extraFrontEndOptions != null) + command.addAll(extraFrontEndOptions); + command.add(mainPath); + final Process server = await processManager + .start(command) + .catchError((dynamic error, StackTrace stack) { printTrace('Failed to start frontend server $error, $stack'); }); diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 1a98e5a7aee..5a42245154a 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -54,6 +54,12 @@ class FlutterCommandResult { final DateTime endTimeOverride; } +/// Common flutter command line options. +class FlutterOptions { + static const String kExtraFrontEndOptions = 'extra-front-end-options'; + static const String kExtraGenSnapshotOptions = 'extra-gen-snapshot-options'; +} + abstract class FlutterCommand extends Command { @override FlutterCommandRunner get runner => super.runner; @@ -149,7 +155,13 @@ abstract class FlutterCommand extends Command { : null, previewDart2: argParser.options.containsKey('preview-dart-2') ? argResults['preview-dart-2'] - : false); + : false, + extraFrontEndOptions: argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions) + ? argResults[FlutterOptions.kExtraFrontEndOptions] + : null, + extraGenSnapshotOptions: argParser.options.containsKey(FlutterOptions.kExtraGenSnapshotOptions) + ? argResults[FlutterOptions.kExtraGenSnapshotOptions] + : null); } void setupApplicationPackages() {