Expose extra frontend options through build apk/ios/macOS (#53273)

This will allow experimenting with the remove to string transformer before we're ready to turn it on by default. This doesn't work for web yet since we use dart2js instead of the frontend_server for producing kernel
This commit is contained in:
Jonah Williams 2020-03-25 16:56:41 -07:00 committed by GitHub
parent 1376746237
commit e23c4796a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 119 additions and 10 deletions

View File

@ -84,6 +84,7 @@ RunCommand "${FLUTTER_ROOT}/bin/flutter" --suppress-analytics \
-dDartObfuscation="${dart_obfuscation_flag}" \
-dSplitDebugInfo="${SPLIT_DEBUG_INFO}" \
-dDartDefines="${DART_DEFINES}" \
-dExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \
--build-inputs="${build_inputs_path}" \
--build-outputs="${build_outputs_path}" \
--output="${ephemeral_dir}" \

View File

@ -187,6 +187,7 @@ BuildApp() {
-dDartObfuscation="${dart_obfuscation_flag}" \
-dEnableBitcode="${bitcode_flag}" \
-dDartDefines="${DART_DEFINES}" \
-dExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \
"${build_mode}_ios_bundle_flutter_assets"
if [[ $? -ne 0 ]]; then

View File

@ -313,7 +313,7 @@ Future<void> buildGradleApp({
command.add('-Ptrack-widget-creation=${buildInfo.trackWidgetCreation}');
if (buildInfo.extraFrontEndOptions != null) {
command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions}');
command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions.join(',')}');
}
if (buildInfo.extraGenSnapshotOptions != null) {
command.add('-Pextra-gen-snapshot-options=${buildInfo.extraGenSnapshotOptions}');

View File

@ -204,7 +204,10 @@ class KernelSnapshot extends Target {
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
// This configuration is all optional.
final List<String> extraFrontEndOptions = environment.defines[kExtraFrontEndOptions]?.split(',');
final String rawFrontEndOption = environment.defines[kExtraFrontEndOptions];
final List<String> extraFrontEndOptions = (rawFrontEndOption?.isNotEmpty ?? false)
? rawFrontEndOption?.split(',')
: null;
final List<String> fileSystemRoots = environment.defines[kFileSystemRoots]?.split(',');
final String fileSystemScheme = environment.defines[kFileSystemScheme];

View File

@ -20,6 +20,7 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
addBuildModeFlags();
usesPubOption();
usesDartDefineOption();
usesExtraFrontendOptions();
argParser
..addOption('output-dir', defaultsTo: getAotBuildDirectory())
..addOption('target-platform',
@ -33,10 +34,6 @@ class BuildAotCommand extends BuildSubCommand with TargetPlatformBasedDevelopmen
allowed: DarwinArch.values.map<String>(getNameForDarwinArch),
help: 'iOS architectures to build.',
)
..addMultiOption(FlutterOptions.kExtraFrontEndOptions,
splitCommas: true,
hide: true,
)
..addMultiOption(FlutterOptions.kExtraGenSnapshotOptions,
splitCommas: true,
hide: true,

View File

@ -29,6 +29,7 @@ class BuildApkCommand extends BuildSubCommand {
addSplitDebugInfoOption();
addDartObfuscationOption();
usesDartDefineOption();
usesExtraFrontendOptions();
argParser
..addFlag('split-per-abi',
negatable: false,

View File

@ -27,6 +27,7 @@ class BuildAppBundleCommand extends BuildSubCommand {
addSplitDebugInfoOption();
addDartObfuscationOption();
usesDartDefineOption();
usesExtraFrontendOptions();
argParser
..addFlag('track-widget-creation', negatable: false, hide: !verboseHelp)
..addMultiOption('target-platform',

View File

@ -21,6 +21,7 @@ class BuildBundleCommand extends BuildSubCommand {
usesFilesystemOptions(hide: !verboseHelp);
usesBuildNumberOption();
addBuildModeFlags(verboseHelp: verboseHelp);
usesExtraFrontendOptions();
argParser
..addFlag(
'precompiled',
@ -49,10 +50,6 @@ class BuildBundleCommand extends BuildSubCommand {
'windows-x64',
],
)
..addMultiOption(FlutterOptions.kExtraFrontEndOptions,
splitCommas: true,
hide: true,
)
..addOption('asset-dir', defaultsTo: getAssetBuildDirectory())
..addMultiOption(FlutterOptions.kExtraGenSnapshotOptions,
splitCommas: true,

View File

@ -28,6 +28,7 @@ class BuildIOSCommand extends BuildSubCommand {
usesBuildNameOption();
addDartObfuscationOption();
usesDartDefineOption();
usesExtraFrontendOptions();
argParser
..addFlag('simulator',
help: 'Build for the iOS simulator instead of the device.',

View File

@ -51,6 +51,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
usesDartDefineOption();
addSplitDebugInfoOption();
addDartObfuscationOption();
usesExtraFrontendOptions();
argParser
..addFlag('debug',
negatable: true,

View File

@ -22,6 +22,7 @@ class BuildMacosCommand extends BuildSubCommand {
usesTargetOption();
addBuildModeFlags();
addDartObfuscationOption();
usesExtraFrontendOptions();
}
@override

View File

@ -239,6 +239,10 @@ List<String> _xcodeBuildSettingsLines({
xcodeBuildSettings.add('DART_DEFINES=${jsonEncode(buildInfo.dartDefines)}');
}
if (buildInfo.extraFrontEndOptions?.isNotEmpty ?? false) {
xcodeBuildSettings.add('EXTRA_FRONT_END_OPTIONS=${buildInfo.extraFrontEndOptions.join(',')}');
}
return xcodeBuildSettings;
}

View File

@ -429,6 +429,13 @@ abstract class FlutterCommand extends Command<void> {
);
}
void usesExtraFrontendOptions() {
argParser.addMultiOption(FlutterOptions.kExtraFrontEndOptions,
splitCommas: true,
hide: true,
);
}
void usesFuchsiaOptions({ bool hide = false }) {
argParser.addOption(
'target-model',

View File

@ -130,6 +130,68 @@ void main() {
expect(processManager.hasRemainingExpectations, false);
}));
test('KernelSnapshot correctly handles an empty string in ExtraFrontEndOptions', () => testbed.run(() async {
globals.fs.file('.packages').writeAsStringSync('\n');
final String build = androidEnvironment.buildDir.path;
processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getArtifactPath(Artifact.engineDartBinary),
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
'--target=flutter',
'-Ddart.developer.causal_async_stacks=false',
...buildModeOptions(BuildMode.profile),
'--aot',
'--tfa',
'--packages',
'/.packages',
'--output-dill',
'$build/app.dill',
'--depfile',
'$build/kernel_snapshot.d',
'/lib/main.dart',
], stdout: 'result $kBoundaryKey\n$kBoundaryKey\n$kBoundaryKey $build/app.dill 0\n'),
]);
await const KernelSnapshot()
.build(androidEnvironment..defines[kExtraFrontEndOptions] = '');
expect(processManager.hasRemainingExpectations, false);
}));
test('KernelSnapshot correctly forwards ExtraFrontEndOptions', () => testbed.run(() async {
globals.fs.file('.packages').writeAsStringSync('\n');
final String build = androidEnvironment.buildDir.path;
processManager = FakeProcessManager.list(<FakeCommand>[
FakeCommand(command: <String>[
artifacts.getArtifactPath(Artifact.engineDartBinary),
artifacts.getArtifactPath(Artifact.frontendServerSnapshotForEngineDartSdk),
'--sdk-root',
artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath) + '/',
'--target=flutter',
'-Ddart.developer.causal_async_stacks=false',
...buildModeOptions(BuildMode.profile),
'--aot',
'--tfa',
'--packages',
'/.packages',
'--output-dill',
'$build/app.dill',
'--depfile',
'$build/kernel_snapshot.d',
'foo',
'bar',
'/lib/main.dart',
], stdout: 'result $kBoundaryKey\n$kBoundaryKey\n$kBoundaryKey $build/app.dill 0\n'),
]);
await const KernelSnapshot()
.build(androidEnvironment..defines[kExtraFrontEndOptions] = 'foo,bar');
expect(processManager.hasRemainingExpectations, false);
}));
test('KernelSnapshot can disable track-widget-creation on debug builds', () => testbed.run(() async {
globals.fs.file('.packages').writeAsStringSync('\n');
final String build = androidEnvironment.buildDir.path;

View File

@ -279,6 +279,38 @@ void main() {
ProcessManager: () => mockProcessManager,
});
testUsingContext('--extra-front-end-options are provided to gradle project', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--template=app']);
await expectLater(() async {
await runBuildApkCommand(projectPath, arguments: <String>[
'--extra-front-end-options=foo',
'--extra-front-end-options=bar',
]);
}, throwsToolExit(message: 'Gradle task assembleRelease failed with exit code 1'));
verify(mockProcessManager.start(
<String>[
gradlew,
'-q',
'-Ptarget-platform=android-arm,android-arm64,android-x64',
'-Ptarget=${globals.fs.path.join(tempDir.path, 'flutter_project', 'lib', 'main.dart')}',
'-Ptrack-widget-creation=true',
'-Pextra-front-end-options=foo,bar',
'-Pshrink=true',
'assembleRelease',
],
workingDirectory: anyNamed('workingDirectory'),
environment: anyNamed('environment'),
)).called(1);
},
overrides: <Type, Generator>{
AndroidSdk: () => mockAndroidSdk,
FlutterProjectFactory: () => FakeFlutterProjectFactory(tempDir),
ProcessManager: () => mockProcessManager,
});
testUsingContext('shrinking is disabled when --no-shrink is passed', () async {
final String projectPath = await createProject(tempDir,
arguments: <String>['--no-pub', '--template=app']);