Skip to content

Commit 5b58d5c

Browse files
authored
Exclude armv7 from iOS add-to-app plugins (#101943)
1 parent 607db54 commit 5b58d5c

File tree

4 files changed

+156
-19
lines changed

4 files changed

+156
-19
lines changed

dev/devicelab/bin/tasks/module_test_ios.dart

Lines changed: 109 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,11 +265,36 @@ dependencies:
265265
final File objectiveCAnalyticsOutputFile = File(path.join(tempDir.path, 'analytics-objc.log'));
266266
final Directory objectiveCBuildDirectory = Directory(path.join(tempDir.path, 'build-objc'));
267267

268-
section('Build iOS Objective-C host app');
269-
270268
final File dummyAppFramework = File(path.join(projectDir.path, '.ios', 'Flutter', 'App.framework', 'App'));
271269
checkFileNotExists(dummyAppFramework.path);
272270
await inDirectory(objectiveCHostApp, () async {
271+
section('Validate iOS Objective-C host app Podfile');
272+
273+
final File podfile = File(path.join(objectiveCHostApp.path, 'Podfile'));
274+
String podfileContent = await podfile.readAsString();
275+
final String podFailure = await eval(
276+
'pod',
277+
<String>['install'],
278+
environment: <String, String>{
279+
'LANG': 'en_US.UTF-8',
280+
},
281+
canFail: true,
282+
);
283+
284+
if (!podFailure.contains('Missing `flutter_post_install(installer)` in Podfile `post_install` block')
285+
|| !podFailure.contains('Add `flutter_post_install(installer)` to your Podfile `post_install` block to build Flutter plugins')) {
286+
print(podfileContent);
287+
throw TaskResult.failure('pod install unexpectedly succeed without "flutter_post_install" post_install block');
288+
}
289+
podfileContent = '''
290+
$podfileContent
291+
292+
post_install do |installer|
293+
flutter_post_install(installer)
294+
end
295+
''';
296+
await podfile.writeAsString(podfileContent, flush: true);
297+
273298
await exec(
274299
'pod',
275300
<String>['install'],
@@ -298,6 +323,8 @@ dependencies:
298323
throw TaskResult.failure('Minimum version set to $version, expected 9.0');
299324
}
300325

326+
section('Build iOS Objective-C host app');
327+
301328
await exec(
302329
'xcodebuild',
303330
<String>[
@@ -378,6 +405,86 @@ dependencies:
378405
);
379406
}
380407

408+
section('Archive iOS Objective-C host app');
409+
410+
await inDirectory(objectiveCHostApp, () async {
411+
final Directory objectiveCBuildArchiveDirectory = Directory(path.join(tempDir.path, 'build-objc-archive'));
412+
await exec(
413+
'xcodebuild',
414+
<String>[
415+
'-workspace',
416+
'Host.xcworkspace',
417+
'-scheme',
418+
'Host',
419+
'-configuration',
420+
'Release',
421+
'CODE_SIGNING_ALLOWED=NO',
422+
'CODE_SIGNING_REQUIRED=NO',
423+
'CODE_SIGN_IDENTITY=-',
424+
'EXPANDED_CODE_SIGN_IDENTITY=-',
425+
'-archivePath',
426+
objectiveCBuildArchiveDirectory.path,
427+
'COMPILER_INDEX_STORE_ENABLE=NO',
428+
'archive'
429+
],
430+
environment: <String, String> {
431+
'FLUTTER_ANALYTICS_LOG_FILE': objectiveCAnalyticsOutputFile.path,
432+
},
433+
);
434+
435+
final String archivedAppPath = path.join(
436+
'${objectiveCBuildArchiveDirectory.path}.xcarchive',
437+
'Products',
438+
'Applications',
439+
'Host.app',
440+
);
441+
442+
checkFileExists(path.join(
443+
archivedAppPath,
444+
'Host',
445+
));
446+
447+
checkFileNotExists(path.join(
448+
archivedAppPath,
449+
'Frameworks',
450+
'App.framework',
451+
'flutter_assets',
452+
'isolate_snapshot_data',
453+
));
454+
455+
final String builtFlutterBinary = path.join(
456+
archivedAppPath,
457+
'Frameworks',
458+
'Flutter.framework',
459+
'Flutter',
460+
);
461+
checkFileExists(builtFlutterBinary);
462+
if ((await fileType(builtFlutterBinary)).contains('armv7')) {
463+
throw TaskResult.failure('Unexpected armv7 architecture slice in $builtFlutterBinary');
464+
}
465+
await containsBitcode(builtFlutterBinary);
466+
467+
final String builtAppBinary = path.join(
468+
archivedAppPath,
469+
'Frameworks',
470+
'App.framework',
471+
'App',
472+
);
473+
checkFileExists(builtAppBinary);
474+
if ((await fileType(builtAppBinary)).contains('armv7')) {
475+
throw TaskResult.failure('Unexpected armv7 architecture slice in $builtAppBinary');
476+
}
477+
await containsBitcode(builtAppBinary);
478+
479+
// The host app example builds plugins statically, url_launcher_ios.framework
480+
// should not exist.
481+
checkDirectoryNotExists(path.join(
482+
archivedAppPath,
483+
'Frameworks',
484+
'url_launcher_ios.framework',
485+
));
486+
});
487+
381488
section('Run platform unit tests');
382489

383490
final String resultBundleTemp = Directory.systemTemp.createTempSync('flutter_module_test_ios_xcresult.').path;

dev/integration_tests/ios_add2app_life_cycle/Podfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ target 'ios_add2appTests' do
1313
install_flutter_engine_pod
1414
pod 'EarlGreyTest'
1515
end
16+
17+
post_install do |installer|
18+
flutter_post_install(installer)
19+
end

dev/integration_tests/ios_host_app_swift/Podfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
66
target 'Host' do
77
install_all_flutter_pods flutter_application_path
88
end
9+
10+
post_install do |installer|
11+
flutter_post_install(installer)
12+
end

packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ require 'json'
1515
# Optional, defaults to two levels up from the directory of this script.
1616
# MyApp/my_flutter/.ios/Flutter/../..
1717
def install_all_flutter_pods(flutter_application_path = nil)
18+
# defined_in_file is a Pathname to the Podfile set by CocoaPods.
19+
pod_contents = File.read(defined_in_file)
20+
unless pod_contents.include? 'flutter_post_install'
21+
puts <<~POSTINSTALL
22+
Add `flutter_post_install(installer)` to your Podfile `post_install` block to build Flutter plugins:
23+
24+
post_install do |installer|
25+
flutter_post_install(installer)
26+
end
27+
POSTINSTALL
28+
raise 'Missing `flutter_post_install(installer)` in Podfile `post_install` block'
29+
end
30+
31+
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
32+
1833
flutter_application_path ||= File.join('..', '..')
1934
install_flutter_engine_pod
2035
install_flutter_plugin_pods(flutter_application_path)
@@ -46,7 +61,7 @@ def install_flutter_engine_pod
4661
# Keep pod path relative so it can be checked into Podfile.lock.
4762
# Process will be run from project directory.
4863
engine_pathname = Pathname.new engine_dir
49-
# defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
64+
# defined_in_file is a Pathname to the Podfile set by CocoaPods.
5065
project_directory_pathname = defined_in_file.dirname
5166
relative = engine_pathname.relative_path_from project_directory_pathname
5267

@@ -77,7 +92,9 @@ def install_flutter_plugin_pods(flutter_application_path)
7792
FileUtils.mkdir_p(symlinks_dir)
7893

7994
plugins_file = File.expand_path('.flutter-plugins-dependencies', flutter_application_path)
80-
plugin_pods = flutter_parse_dependencies_file_for_ios_plugin(plugins_file)
95+
96+
# flutter_parse_plugins_file is in Flutter root podhelper.rb
97+
plugin_pods = flutter_parse_plugins_file(plugins_file, 'ios')
8198
plugin_pods.each do |plugin_hash|
8299
plugin_name = plugin_hash['name']
83100
plugin_path = plugin_hash['path']
@@ -127,21 +144,6 @@ def install_flutter_application_pod(flutter_application_path)
127144
:execution_position => :before_compile
128145
end
129146

130-
# .flutter-plugins-dependencies format documented at
131-
# https://flutter.dev/go/plugins-list-migration
132-
def flutter_parse_dependencies_file_for_ios_plugin(file)
133-
file_path = File.expand_path(file)
134-
return [] unless File.exists? file_path
135-
136-
dependencies_file = File.read(file)
137-
dependencies_hash = JSON.parse(dependencies_file)
138-
139-
# dependencies_hash.dig('plugins', 'ios') not available until Ruby 2.3
140-
return [] unless dependencies_hash.has_key?('plugins')
141-
return [] unless dependencies_hash['plugins'].has_key?('ios')
142-
dependencies_hash['plugins']['ios'] || []
143-
end
144-
145147
def flutter_root
146148
generated_xcode_build_settings_path = File.expand_path(File.join('..', '..', 'Flutter', 'Generated.xcconfig'), __FILE__)
147149
unless File.exist?(generated_xcode_build_settings_path)
@@ -155,3 +157,23 @@ def flutter_root
155157
# This should never happen...
156158
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
157159
end
160+
161+
# Run the post-install script to set build settings on Flutter plugins.
162+
#
163+
# @example
164+
# post_install do |installer|
165+
# flutter_post_install(installer)
166+
# end
167+
# @param [Pod::Installer] installer Passed to the `post_install` block.
168+
# @param [boolean] skip Do not change any build configurations. Set to suppress
169+
# "Missing `flutter_post_install" exception.
170+
def flutter_post_install(installer, skip: false)
171+
return if skip
172+
173+
installer.pods_project.targets.each do |target|
174+
target.build_configurations.each do |build_configuration|
175+
# flutter_additional_ios_build_settings is in Flutter root podhelper.rb
176+
flutter_additional_ios_build_settings(target)
177+
end
178+
end
179+
end

0 commit comments

Comments
 (0)