Skip to content

Commit

Permalink
Add --frontend-server-starter-path option to flutter run and `flu…
Browse files Browse the repository at this point in the history
…tter test` (flutter#135038)
  • Loading branch information
derekxu16 authored and Mairramer committed Oct 10, 2023
1 parent 206a652 commit a7bee24
Show file tree
Hide file tree
Showing 18 changed files with 184 additions and 8 deletions.
1 change: 1 addition & 0 deletions packages/flutter_tools/bin/macos_assemble.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ BuildApp() {
"-dSplitDebugInfo=${SPLIT_DEBUG_INFO}"
"-dTrackWidgetCreation=${TRACK_WIDGET_CREATION}"
"-dAction=${ACTION}"
"-dFrontendServerStarterPath=${FRONTEND_SERVER_STARTER_PATH}"
"--DartDefines=${DART_DEFINES}"
"--ExtraGenSnapshotOptions=${EXTRA_GEN_SNAPSHOT_OPTIONS}"
"--ExtraFrontEndOptions=${EXTRA_FRONT_END_OPTIONS}"
Expand Down
3 changes: 3 additions & 0 deletions packages/flutter_tools/bin/tool_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Future<void> main(List<String> arguments) async {

final String? dartDefines = Platform.environment['DART_DEFINES'];
final bool dartObfuscation = Platform.environment['DART_OBFUSCATION'] == 'true';
final String? frontendServerStarterPath = Platform.environment['FRONTEND_SERVER_STARTER_PATH'];
final String? extraFrontEndOptions = Platform.environment['EXTRA_FRONT_END_OPTIONS'];
final String? extraGenSnapshotOptions = Platform.environment['EXTRA_GEN_SNAPSHOT_OPTIONS'];
final String? flutterEngine = Platform.environment['FLUTTER_ENGINE'];
Expand Down Expand Up @@ -106,6 +107,8 @@ or
'--DartDefines=$dartDefines',
if (extraGenSnapshotOptions != null)
'--ExtraGenSnapshotOptions=$extraGenSnapshotOptions',
if (frontendServerStarterPath != null)
'-dFrontendServerStarterPath=$frontendServerStarterPath',
if (extraFrontEndOptions != null)
'--ExtraFrontEndOptions=$extraFrontEndOptions',
target,
Expand Down
1 change: 1 addition & 0 deletions packages/flutter_tools/bin/xcode_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ class Context {
'-dTrackWidgetCreation=${environment['TRACK_WIDGET_CREATION'] ?? ''}',
'-dDartObfuscation=${environment['DART_OBFUSCATION'] ?? ''}',
'-dAction=${environment['ACTION'] ?? ''}',
'-dFrontendServerStarterPath=${environment['FRONTEND_SERVER_STARTER_PATH'] ?? ''}',
'--ExtraGenSnapshotOptions=${environment['EXTRA_GEN_SNAPSHOT_OPTIONS'] ?? ''}',
'--DartDefines=${environment['DART_DEFINES'] ?? ''}',
'--ExtraFrontEndOptions=${environment['EXTRA_FRONT_END_OPTIONS'] ?? ''}',
Expand Down
10 changes: 10 additions & 0 deletions packages/flutter_tools/gradle/src/main/groovy/flutter.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,10 @@ class FlutterPlugin implements Plugin<Project> {
if (project.hasProperty('track-widget-creation')) {
trackWidgetCreationValue = project.property('track-widget-creation').toBoolean()
}
String frontendServerStarterPathValue = null
if (project.hasProperty('frontend-server-starter-path')) {
frontendServerStarterPathValue = project.property('frontend-server-starter-path')
}
String extraFrontEndOptionsValue = null
if (project.hasProperty('extra-front-end-options')) {
extraFrontEndOptionsValue = project.property('extra-front-end-options')
Expand Down Expand Up @@ -1052,6 +1056,7 @@ class FlutterPlugin implements Plugin<Project> {
targetPlatformValues = targetPlatforms
sourceDir getFlutterSourceDirectory()
intermediateDir project.file("${project.buildDir}/$INTERMEDIATES_DIR/flutter/${variant.name}/")
frontendServerStarterPath frontendServerStarterPathValue
extraFrontEndOptions extraFrontEndOptionsValue
extraGenSnapshotOptions extraGenSnapshotOptionsValue
splitDebugInfo splitDebugInfoValue
Expand Down Expand Up @@ -1290,6 +1295,8 @@ abstract class BaseFlutterTask extends DefaultTask {
@Internal
File intermediateDir
@Optional @Input
String frontendServerStarterPath
@Optional @Input
String extraFrontEndOptions
@Optional @Input
String extraGenSnapshotOptions
Expand Down Expand Up @@ -1394,6 +1401,9 @@ abstract class BaseFlutterTask extends DefaultTask {
if (extraGenSnapshotOptions != null) {
args "--ExtraGenSnapshotOptions=${extraGenSnapshotOptions}"
}
if (frontendServerStarterPath != null) {
args "-dFrontendServerStarterPath=${frontendServerStarterPath}"
}
if (extraFrontEndOptions != null) {
args "--ExtraFrontEndOptions=${extraFrontEndOptions}"
}
Expand Down
14 changes: 14 additions & 0 deletions packages/flutter_tools/lib/src/build_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class BuildInfo {
this.mode,
this.flavor, {
this.trackWidgetCreation = false,
this.frontendServerStarterPath,
List<String>? extraFrontEndOptions,
List<String>? extraGenSnapshotOptions,
List<String>? fileSystemRoots,
Expand Down Expand Up @@ -82,6 +83,10 @@ class BuildInfo {
/// Whether the build should track widget creation locations.
final bool trackWidgetCreation;

/// If provided, the frontend server will be started in JIT mode from this
/// file.
final String? frontendServerStarterPath;

/// Extra command-line options for front-end.
final List<String> extraFrontEndOptions;

Expand Down Expand Up @@ -237,6 +242,8 @@ class BuildInfo {
if (dartDefines.isNotEmpty)
kDartDefines: encodeDartDefines(dartDefines),
kDartObfuscation: dartObfuscation.toString(),
if (frontendServerStarterPath != null)
kFrontendServerStarterPath: frontendServerStarterPath!,
if (extraFrontEndOptions.isNotEmpty)
kExtraFrontEndOptions: extraFrontEndOptions.join(','),
if (extraGenSnapshotOptions.isNotEmpty)
Expand Down Expand Up @@ -274,6 +281,8 @@ class BuildInfo {
if (dartDefines.isNotEmpty)
'DART_DEFINES': encodeDartDefines(dartDefines),
'DART_OBFUSCATION': dartObfuscation.toString(),
if (frontendServerStarterPath != null)
'FRONTEND_SERVER_STARTER_PATH': frontendServerStarterPath!,
if (extraFrontEndOptions.isNotEmpty)
'EXTRA_FRONT_END_OPTIONS': extraFrontEndOptions.join(','),
if (extraGenSnapshotOptions.isNotEmpty)
Expand Down Expand Up @@ -310,6 +319,8 @@ class BuildInfo {
if (dartDefines.isNotEmpty)
'-Pdart-defines=${encodeDartDefines(dartDefines)}',
'-Pdart-obfuscation=$dartObfuscation',
if (frontendServerStarterPath != null)
'-Pfrontend-server-starter-path=$frontendServerStarterPath',
if (extraFrontEndOptions.isNotEmpty)
'-Pextra-front-end-options=${extraFrontEndOptions.join(',')}',
if (extraGenSnapshotOptions.isNotEmpty)
Expand Down Expand Up @@ -901,6 +912,9 @@ const String kTargetFile = 'TargetFile';
/// Whether to enable or disable track widget creation.
const String kTrackWidgetCreation = 'TrackWidgetCreation';

/// If provided, the frontend server will be started in JIT mode from this file.
const String kFrontendServerStarterPath = 'FrontendServerStarterPath';

/// Additional configuration passed to the dart front end.
///
/// This is expected to be a comma separated list of strings.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ class KernelSnapshot extends Target {
final TargetPlatform targetPlatform = getTargetPlatformForName(targetPlatformEnvironment);

// This configuration is all optional.
final String? frontendServerStarterPath = environment.defines[kFrontendServerStarterPath];
final List<String> extraFrontEndOptions = decodeCommaSeparated(environment.defines, kExtraFrontEndOptions);
final List<String>? fileSystemRoots = environment.defines[kFileSystemRoots]?.split(',');
final String? fileSystemScheme = environment.defines[kFileSystemScheme];
Expand Down Expand Up @@ -254,6 +255,7 @@ class KernelSnapshot extends Target {
linkPlatformKernelIn: forceLinkPlatform || buildMode.isPrecompiled,
mainPath: targetFileAbsolute,
depFilePath: environment.buildDir.childFile('kernel_snapshot.d').path,
frontendServerStarterPath: frontendServerStarterPath,
extraFrontEndOptions: extraFrontEndOptions,
fileSystemRoots: fileSystemRoots,
fileSystemScheme: fileSystemScheme,
Expand Down
1 change: 1 addition & 0 deletions packages/flutter_tools/lib/src/commands/run.dart
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ class RunCommand extends RunCommandBase {
requiresPubspecYaml();
usesFilesystemOptions(hide: !verboseHelp);
usesExtraDartFlagOptions(verboseHelp: verboseHelp);
usesFrontendServerStarterPathOption(verboseHelp: verboseHelp);
addEnableExperimentation(hide: !verboseHelp);
usesInitializeFromDillOption(hide: !verboseHelp);

Expand Down
1 change: 1 addition & 0 deletions packages/flutter_tools/lib/src/commands/test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts {
requiresPubspecYaml();
usesPubOption();
addNullSafetyModeOptions(hide: !verboseHelp);
usesFrontendServerStarterPathOption(verboseHelp: verboseHelp);
usesTrackWidgetCreation(verboseHelp: verboseHelp);
addEnableExperimentation(hide: !verboseHelp);
usesDartDefineOption();
Expand Down
24 changes: 16 additions & 8 deletions packages/flutter_tools/lib/src/compile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ class KernelCompiler {
TargetModel targetModel = TargetModel.flutter,
bool linkPlatformKernelIn = false,
bool aot = false,
String? frontendServerStarterPath,
List<String>? extraFrontEndOptions,
List<String>? fileSystemRoots,
String? fileSystemScheme,
Expand All @@ -243,10 +244,12 @@ class KernelCompiler {
String? nativeAssets,
}) async {
final TargetPlatform? platform = targetModel == TargetModel.dartdevc ? TargetPlatform.web_javascript : null;
final String frontendServer = _artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk,
platform: platform,
);
final String frontendServer = (frontendServerStarterPath == null || frontendServerStarterPath.isEmpty)
? _artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk,
platform: platform,
)
: frontendServerStarterPath;
// This is a URI, not a file path, so the forward slash is correct even on Windows.
if (!sdkRoot.endsWith('/')) {
sdkRoot = '$sdkRoot/';
Expand Down Expand Up @@ -490,6 +493,7 @@ abstract class ResidentCompiler {
bool assumeInitializeFromDillUpToDate,
TargetModel targetModel,
bool unsafePackageSerialization,
String? frontendServerStarterPath,
List<String> extraFrontEndOptions,
String platformDill,
List<String>? dartDefines,
Expand Down Expand Up @@ -605,6 +609,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
this.assumeInitializeFromDillUpToDate = false,
this.targetModel = TargetModel.flutter,
this.unsafePackageSerialization = false,
this.frontendServerStarterPath,
this.extraFrontEndOptions,
this.platformDill,
List<String>? dartDefines,
Expand Down Expand Up @@ -635,6 +640,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
final String? initializeFromDill;
final bool assumeInitializeFromDillUpToDate;
final bool unsafePackageSerialization;
final String? frontendServerStarterPath;
final List<String>? extraFrontEndOptions;
final List<String> dartDefines;
final String? librariesSpec;
Expand Down Expand Up @@ -771,10 +777,12 @@ class DefaultResidentCompiler implements ResidentCompiler {
String? nativeAssetsUri,
}) async {
final TargetPlatform? platform = (targetModel == TargetModel.dartdevc) ? TargetPlatform.web_javascript : null;
final String frontendServer = artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk,
platform: platform,
);
final String frontendServer = (frontendServerStarterPath == null || frontendServerStarterPath!.isEmpty)
? artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk,
platform: platform,
)
: frontendServerStarterPath!;
final List<String> command = <String>[
artifacts.getArtifactPath(Artifact.engineDartBinary, platform: platform),
'--disable-dart-dev',
Expand Down
3 changes: 3 additions & 0 deletions packages/flutter_tools/lib/src/resident_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class FlutterDevice {
targetModel: targetModel,
dartDefines: buildInfo.dartDefines,
packagesPath: buildInfo.packagesPath,
frontendServerStarterPath: buildInfo.frontendServerStarterPath,
extraFrontEndOptions: buildInfo.extraFrontEndOptions,
artifacts: globals.artifacts!,
processManager: globals.processManager,
Expand Down Expand Up @@ -155,6 +156,7 @@ class FlutterDevice {
),
assumeInitializeFromDillUpToDate: buildInfo.assumeInitializeFromDillUpToDate,
targetModel: TargetModel.dartdevc,
frontendServerStarterPath: buildInfo.frontendServerStarterPath,
extraFrontEndOptions: extraFrontEndOptions,
platformDill: globals.fs.file(platformDillPath).absolute.uri.toString(),
dartDefines: buildInfo.dartDefines,
Expand Down Expand Up @@ -185,6 +187,7 @@ class FlutterDevice {
fileSystemScheme: buildInfo.fileSystemScheme,
targetModel: targetModel,
dartDefines: buildInfo.dartDefines,
frontendServerStarterPath: buildInfo.frontendServerStarterPath,
extraFrontEndOptions: extraFrontEndOptions,
initializeFromDill: buildInfo.initializeFromDill ?? getDefaultCachedKernelPath(
trackWidgetCreation: buildInfo.trackWidgetCreation,
Expand Down
17 changes: 17 additions & 0 deletions packages/flutter_tools/lib/src/runner/flutter_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class FlutterCommandResult {

/// Common flutter command line options.
abstract final class FlutterOptions {
static const String kFrontendServerStarterPath = 'frontend-server-starter-path';
static const String kExtraFrontEndOptions = 'extra-front-end-options';
static const String kExtraGenSnapshotOptions = 'extra-gen-snapshot-options';
static const String kEnableExperiment = 'enable-experiment';
Expand Down Expand Up @@ -849,6 +850,18 @@ abstract class FlutterCommand extends Command<void> {
);
}

void usesFrontendServerStarterPathOption({required bool verboseHelp}) {
argParser.addOption(
FlutterOptions.kFrontendServerStarterPath,
help: 'When this value is provided, the frontend server will be started '
'in JIT mode from the specified file, instead of from the AOT '
'snapshot shipped with the Dart SDK. The specified file can either '
'be a Dart source file, or an AppJIT snapshot. This option does '
'not affect web builds.',
hide: !verboseHelp,
);
}

/// Enables support for the hidden options --extra-front-end-options and
/// --extra-gen-snapshot-options.
void usesExtraDartFlagOptions({ required bool verboseHelp }) {
Expand Down Expand Up @@ -1239,6 +1252,10 @@ abstract class FlutterCommand extends Command<void> {
? stringArg('flavor')
: null,
trackWidgetCreation: trackWidgetCreation,
frontendServerStarterPath: argParser.options
.containsKey(FlutterOptions.kFrontendServerStarterPath)
? stringArg(FlutterOptions.kFrontendServerStarterPath)
: null,
extraFrontEndOptions: extraFrontEndOptions.isNotEmpty
? extraFrontEndOptions
: null,
Expand Down
1 change: 1 addition & 0 deletions packages/flutter_tools/lib/src/test/test_compiler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class TestCompiler {
initializeFromDill: testFilePath,
dartDefines: buildInfo.dartDefines,
packagesPath: buildInfo.packagesPath,
frontendServerStarterPath: buildInfo.frontendServerStarterPath,
extraFrontEndOptions: buildInfo.extraFrontEndOptions,
platform: globals.platform,
testCompilation: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ void main() {
dartDefines: <String>['foo=2', 'bar=2'],
dartObfuscation: true,
splitDebugInfoPath: 'foo/',
frontendServerStarterPath: 'foo/bar/frontend_server_starter.dart',
extraFrontEndOptions: <String>['--enable-experiment=non-nullable', 'bar'],
extraGenSnapshotOptions: <String>['--enable-experiment=non-nullable', 'fizz'],
bundleSkSLPath: 'foo/bar/baz.sksl.json',
Expand All @@ -190,6 +191,7 @@ void main() {
'BuildMode': 'debug',
'DartDefines': 'Zm9vPTI=,YmFyPTI=',
'DartObfuscation': 'true',
'FrontendServerStarterPath': 'foo/bar/frontend_server_starter.dart',
'ExtraFrontEndOptions': '--enable-experiment=non-nullable,bar',
'ExtraGenSnapshotOptions': '--enable-experiment=non-nullable,fizz',
'SplitDebugInfo': 'foo/',
Expand All @@ -211,6 +213,7 @@ void main() {
dartDefines: <String>['foo=2', 'bar=2'],
dartObfuscation: true,
splitDebugInfoPath: 'foo/',
frontendServerStarterPath: 'foo/bar/frontend_server_starter.dart',
extraFrontEndOptions: <String>['--enable-experiment=non-nullable', 'bar'],
extraGenSnapshotOptions: <String>['--enable-experiment=non-nullable', 'fizz'],
bundleSkSLPath: 'foo/bar/baz.sksl.json',
Expand All @@ -226,6 +229,7 @@ void main() {
'DART_DEFINES': 'Zm9vPTI=,YmFyPTI=',
'DART_OBFUSCATION': 'true',
'SPLIT_DEBUG_INFO': 'foo/',
'FRONTEND_SERVER_STARTER_PATH': 'foo/bar/frontend_server_starter.dart',
'EXTRA_FRONT_END_OPTIONS': '--enable-experiment=non-nullable,bar',
'EXTRA_GEN_SNAPSHOT_OPTIONS': '--enable-experiment=non-nullable,fizz',
'BUNDLE_SKSL_PATH': 'foo/bar/baz.sksl.json',
Expand All @@ -242,6 +246,7 @@ void main() {
dartDefineConfigJsonMap: <String, Object>{'baz': '2'},
dartObfuscation: true,
splitDebugInfoPath: 'foo/',
frontendServerStarterPath: 'foo/bar/frontend_server_starter.dart',
extraFrontEndOptions: <String>['--enable-experiment=non-nullable', 'bar'],
extraGenSnapshotOptions: <String>['--enable-experiment=non-nullable', 'fizz'],
bundleSkSLPath: 'foo/bar/baz.sksl.json',
Expand All @@ -253,6 +258,7 @@ void main() {
expect(buildInfo.toGradleConfig(), <String>[
'-Pdart-defines=Zm9vPTI=,YmFyPTI=',
'-Pdart-obfuscation=true',
'-Pfrontend-server-starter-path=foo/bar/frontend_server_starter.dart',
'-Pextra-front-end-options=--enable-experiment=non-nullable,bar',
'-Pextra-gen-snapshot-options=--enable-experiment=non-nullable,fizz',
'-Psplit-debug-info=foo/',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,53 @@ native-assets: {}
expect(processManager, hasNoRemainingExpectations);
});

testWithoutContext('KernelSnapshot correctly forwards FrontendServerStarterPath', () async {
fileSystem.file('.dart_tool/package_config.json')
..createSync(recursive: true)
..writeAsStringSync('{"configVersion": 2, "packages":[]}');
androidEnvironment.buildDir.childFile('native_assets.yaml')
..createSync(recursive: true)
..writeAsStringSync(emptyNativeAssets);
final String build = androidEnvironment.buildDir.path;
final String flutterPatchedSdkPath = artifacts.getArtifactPath(
Artifact.flutterPatchedSdkPath,
platform: TargetPlatform.android_arm,
mode: BuildMode.profile,
);
processManager.addCommands(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getArtifactPath(Artifact.engineDartBinary),
'--disable-dart-dev',
'path/to/frontend_server_starter.dart',
'--sdk-root',
'$flutterPatchedSdkPath/',
'--target=flutter',
'--no-print-incremental-dependencies',
...buildModeOptions(BuildMode.profile, <String>[]),
'--track-widget-creation',
'--aot',
'--tfa',
'--target-os',
'android',
'--packages',
'/.dart_tool/package_config.json',
'--output-dill',
'$build/app.dill',
'--depfile',
'$build/kernel_snapshot.d',
'--native-assets',
'$build/native_assets.yaml',
'--verbosity=error',
'file:///lib/main.dart',
], stdout: 'result $kBoundaryKey\n$kBoundaryKey\n$kBoundaryKey $build/app.dill 0\n'),
]);

await const KernelSnapshot()
.build(androidEnvironment..defines[kFrontendServerStarterPath] = 'path/to/frontend_server_starter.dart');

expect(processManager, hasNoRemainingExpectations);
});

testWithoutContext('KernelSnapshot correctly forwards ExtraFrontEndOptions', () async {
fileSystem.file('.dart_tool/package_config.json')
..createSync(recursive: true)
Expand Down

0 comments on commit a7bee24

Please sign in to comment.