Skip to content

Commit 0f67c99

Browse files
authored
[flutter_tools] build ios-frameworks: option to exclude plugin frameworks from the build (#129739)
A lot of details are written in the feature request: flutter/flutter#114692. tl;dr: Options B & C from the add2app iOS guide have a limitation (build error) in case the Flutter plugin and native iOS app have a shared dependency. We can use a workaround to avoid the issue, but in this case we don't need to build frameworks for plugins. Closes flutter/flutter#114692 Part of flutter/flutter#130220
1 parent f387b77 commit 0f67c99

3 files changed

Lines changed: 94 additions & 2 deletions

File tree

dev/devicelab/bin/tasks/build_ios_framework_module_test.dart

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,12 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
493493
isModule) {
494494
throw TaskResult.failure('Unexpected GeneratedPluginRegistrant.m.');
495495
}
496+
497+
section('Build frameworks without plugins');
498+
await _testBuildFrameworksWithoutPlugins(projectDir, platform: 'ios');
499+
500+
section('check --static cannot be used with the --no-plugins flag');
501+
await _testStaticAndNoPlugins(projectDir);
496502
}
497503

498504

@@ -816,6 +822,83 @@ Future<void> _testBuildMacOSFramework(Directory projectDir) async {
816822
outputPath,
817823
'GeneratedPluginRegistrant.swift',
818824
));
825+
826+
section('Build frameworks without plugins');
827+
await _testBuildFrameworksWithoutPlugins(projectDir, platform: 'macos');
828+
}
829+
830+
Future<void> _testBuildFrameworksWithoutPlugins(Directory projectDir, { required String platform}) async {
831+
const String noPluginsOutputDir = 'flutter-frameworks-no-plugins';
832+
833+
await inDirectory(projectDir, () async {
834+
await flutter(
835+
'build',
836+
options: <String>[
837+
'$platform-framework',
838+
'--cocoapods',
839+
'--force', // Allow podspec creation on master.
840+
'--output=$noPluginsOutputDir',
841+
'--no-plugins',
842+
],
843+
);
844+
});
845+
846+
final String noPluginsOutputPath = path.join(projectDir.path, noPluginsOutputDir);
847+
for (final String mode in <String>['Debug', 'Profile', 'Release']) {
848+
checkFileExists(path.join(
849+
noPluginsOutputPath,
850+
mode,
851+
'Flutter${platform == 'macos' ? 'MacOS' : ''}.podspec',
852+
));
853+
checkDirectoryExists(path.join(
854+
noPluginsOutputPath,
855+
mode,
856+
'App.xcframework',
857+
));
858+
859+
checkDirectoryNotExists(path.join(
860+
noPluginsOutputPath,
861+
mode,
862+
'package_info.xcframework',
863+
));
864+
865+
checkDirectoryNotExists(path.join(
866+
noPluginsOutputPath,
867+
mode,
868+
'connectivity.xcframework',
869+
));
870+
871+
checkDirectoryNotExists(path.join(
872+
noPluginsOutputPath,
873+
mode,
874+
'Reachability.xcframework',
875+
));
876+
}
877+
}
878+
879+
Future<void> _testStaticAndNoPlugins(Directory projectDir) async {
880+
const String noPluginsOutputDir = 'flutter-frameworks-no-plugins-static';
881+
final ProcessResult result = await inDirectory(projectDir, () async {
882+
return executeFlutter(
883+
'build',
884+
options: <String>[
885+
'ios-framework',
886+
'--cocoapods',
887+
'--force', // Allow podspec creation on master.
888+
'--output=$noPluginsOutputDir',
889+
'--no-plugins',
890+
'--static'
891+
],
892+
canFail: true
893+
);
894+
});
895+
if (result.exitCode == 0) {
896+
throw TaskResult.failure('Build framework command did not exit with error as expected');
897+
}
898+
final String output = '${result.stdout}\n${result.stderr}';
899+
if (!output.contains('--static cannot be used with the --no-plugins flag')) {
900+
throw TaskResult.failure(output);
901+
}
819902
}
820903

821904
Future<void> _checkDylib(String pathToLibrary) async {

packages/flutter_tools/lib/src/commands/build_ios_framework.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ abstract class BuildFrameworkCommand extends BuildSubCommand {
6868
..addFlag('cocoapods',
6969
help: 'Produce a Flutter.podspec instead of an engine Flutter.xcframework (recommended if host app uses CocoaPods).',
7070
)
71+
..addFlag('plugins',
72+
defaultsTo: true,
73+
help: 'Whether to produce frameworks for the plugins. '
74+
'This is intended for cases where plugins are already being built separately.',
75+
)
7176
..addFlag('static',
7277
help: 'Build plugins as static frameworks. Link on, but do not embed these frameworks in the existing Xcode project.',
7378
)
@@ -135,6 +140,10 @@ abstract class BuildFrameworkCommand extends BuildSubCommand {
135140
if ((await getBuildInfos()).isEmpty) {
136141
throwToolExit('At least one of "--debug" or "--profile", or "--release" is required.');
137142
}
143+
144+
if (!boolArg('plugins') && boolArg('static')) {
145+
throwToolExit('--static cannot be used with the --no-plugins flag');
146+
}
138147
}
139148

140149
static Future<void> produceXCFramework(
@@ -264,7 +273,7 @@ class BuildIOSFrameworkCommand extends BuildFrameworkCommand {
264273

265274
// Build and copy plugins.
266275
await processPodsIfNeeded(project.ios, getIosBuildDirectory(), buildInfo.mode);
267-
if (hasPlugins(project)) {
276+
if (boolArg('plugins') && hasPlugins(project)) {
268277
await _producePlugins(buildInfo.mode, xcodeBuildConfiguration, iPhoneBuildOutput, simulatorBuildOutput, modeDirectory);
269278
}
270279

packages/flutter_tools/lib/src/commands/build_macos_framework.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class BuildMacOSFrameworkCommand extends BuildFrameworkCommand {
9191
// Build and copy plugins.
9292
final Directory buildOutput = modeDirectory.childDirectory('macos');
9393
await processPodsIfNeeded(project.macos, getMacOSBuildDirectory(), buildInfo.mode);
94-
if (hasPlugins(project)) {
94+
if (boolArg('plugins') && hasPlugins(project)) {
9595
await _producePlugins(xcodeBuildConfiguration, buildOutput, modeDirectory);
9696
}
9797

0 commit comments

Comments
 (0)