Add hidden options --extra-front-end-options and --extra-gen-snapshot-options to flutter tool (#12219)
This CL introduces 2 hidden options to 'flutter build aot' and 'flutter run' for passing arbitrary arguments to front-end server and to gen_snapshot tool when building and running flutter app in --profile or --release modes.
The ability to pass arbitrary options simplifies various experiments, as it removes the need to change defaults and rebuild flutter engine for every tested configuration.
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index db4acac..6a867c6 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -291,6 +291,10 @@
}
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 b4be334..672c43b 100644
--- a/packages/flutter_tools/lib/src/build_info.dart
+++ b/packages/flutter_tools/lib/src/build_info.dart
@@ -10,7 +10,10 @@
/// 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 @@
// 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 01f1ef6..0e30bd4 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 '../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 @@
)
..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 @@
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 @@
String outputPath,
bool interpreter: false,
bool previewDart2: false,
+ List<String> extraFrontEndOptions,
+ List<String> extraGenSnapshotOptions,
}) async {
outputPath ??= getAotBuildDirectory();
try {
@@ -105,6 +120,8 @@
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 @@
String outputPath,
bool interpreter: false,
bool previewDart2: false,
+ List<String> extraFrontEndOptions,
+ List<String> extraGenSnapshotOptions,
}) async {
outputPath ??= getAotBuildDirectory();
if (!isAotBuildMode(buildMode) && !interpreter) {
@@ -220,6 +239,14 @@
'--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 @@
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 6afefa9..9d2cf36 100644
--- a/packages/flutter_tools/lib/src/commands/run.dart
+++ b/packages/flutter_tools/lib/src/commands/run.dart
@@ -155,6 +155,9 @@
'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<Device> devices;
diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart
index 961c5a6..b927f5a 100644
--- a/packages/flutter_tools/lib/src/compile.dart
+++ b/packages/flutter_tools/lib/src/compile.dart
@@ -56,7 +56,10 @@
}
}
-Future<String> compile({String sdkRoot, String mainPath}) async {
+Future<String> compile(
+ {String sdkRoot,
+ String mainPath,
+ List<String> extraFrontEndOptions}) async {
final String frontendServer = artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk
);
@@ -64,13 +67,18 @@
// 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(<String>[
+ final List<String> command = <String>[
_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 1a98e5a..5a42245 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 @@
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<Null> {
@override
FlutterCommandRunner get runner => super.runner;
@@ -149,7 +155,13 @@
: 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() {