Skip to content

Commit 22fe15a

Browse files
authored
Set MinimumOSVersion in iOS Info.plist based on buildroot setting (flutter#28743)
1 parent a1400b4 commit 22fe15a

File tree

7 files changed

+96
-17
lines changed

7 files changed

+96
-17
lines changed

build/copy_info_plist.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@
1010
1111
Precondition: $CWD/../../flutter is the path to the flutter engine repo.
1212
13-
usage: copy_info_plist.py <src_path> <dest_path> --bitcode=<enable_bitcode>
13+
usage: copy_info_plist.py --source <src_path> --destination <dest_path> --bitcode --minversion=<deployment_target>
1414
"""
1515

16-
17-
18-
1916
import subprocess
2017

18+
import argparse
2119
import sys
2220
import git_revision
2321
import os
@@ -30,13 +28,25 @@ def GetClangVersion(bitcode) :
3028
return version.splitlines()[0]
3129

3230
def main():
33-
text = open(sys.argv[1]).read()
31+
32+
parser = argparse.ArgumentParser(
33+
description='Copies the Info.plist and adds extra fields to it like the git hash of the engine')
34+
35+
parser.add_argument('--source', help='Path to Info.plist source template', type=str, required=True)
36+
parser.add_argument('--destination', help='Path to destination Info.plist', type=str, required=True)
37+
parser.add_argument('--bitcode', help='Built with bitcode', action='store_true')
38+
parser.add_argument('--minversion', help='Minimum device OS version like "9.0"', type=str)
39+
40+
args = parser.parse_args()
41+
42+
text = open(args.source).read()
3443
engine_path = os.path.join(os.getcwd(), "..", "..", "flutter")
3544
revision = git_revision.GetRepositoryVersion(engine_path)
36-
clang_version = GetClangVersion(sys.argv[3] == "--bitcode=true")
37-
text = text.format(revision, clang_version)
45+
bitcode = args.bitcode is not None;
46+
clang_version = GetClangVersion(bitcode)
47+
text = text.format(revision = revision, clang_version = clang_version, min_version = args.minversion)
3848

39-
with open(sys.argv[2], "w") as outfile:
49+
with open(args.destination, "w") as outfile:
4050
outfile.write(text)
4151

4252
if __name__ == "__main__":

shell/platform/darwin/ios/BUILD.gn

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,10 +323,16 @@ action("copy_framework_info_plist") {
323323
sources = [ "framework/Info.plist" ]
324324
outputs = [ "$_flutter_framework_dir/Info.plist" ]
325325
args = [
326+
"--source",
326327
rebase_path(sources[0]),
328+
"--destination",
327329
rebase_path(outputs[0]),
328-
"--bitcode=$enable_bitcode",
330+
"--minversion",
331+
ios_deployment_target,
329332
]
333+
if (enable_bitcode) {
334+
args += [ "--bitcode" ]
335+
}
330336
}
331337

332338
copy("copy_framework_module_map") {

shell/platform/darwin/ios/framework/Info.plist

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@
2121
<key>CFBundleVersion</key>
2222
<string>1.0</string>
2323
<key>MinimumOSVersion</key>
24-
<string>9.0</string>
24+
<string>{min_version}</string>
2525
<key>FlutterEngine</key>
26-
<string>{0}</string>
26+
<string>{revision}</string>
2727
<key>ClangVersion</key>
28-
<string>{1}</string>
28+
<string>{clang_version}</string>
2929
</dict>
3030
</plist>

shell/platform/darwin/ios/framework/Source/FlutterEngineTest.mm

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
#import <Foundation/Foundation.h>
56
#import <OCMock/OCMock.h>
67
#import <XCTest/XCTest.h>
78

@@ -30,6 +31,62 @@ - (void)testCreate {
3031
XCTAssertNotNil(engine);
3132
}
3233

34+
- (void)testInfoPlist {
35+
// Check the embedded Flutter.framework Info.plist, not the linked dylib.
36+
NSURL* flutterFrameworkURL =
37+
[NSBundle.mainBundle.privateFrameworksURL URLByAppendingPathComponent:@"Flutter.framework"];
38+
NSBundle* flutterBundle = [NSBundle bundleWithURL:flutterFrameworkURL];
39+
XCTAssertEqualObjects(flutterBundle.bundleIdentifier, @"io.flutter.flutter");
40+
41+
NSDictionary<NSString*, id>* infoDictionary = flutterBundle.infoDictionary;
42+
43+
// OS version can have one, two, or three digits: "8", "8.0", "8.0.0"
44+
NSError* regexError = NULL;
45+
NSRegularExpression* osVersionRegex =
46+
[NSRegularExpression regularExpressionWithPattern:@"((0|[1-9]\\d*)\\.)*(0|[1-9]\\d*)"
47+
options:NSRegularExpressionCaseInsensitive
48+
error:&regexError];
49+
XCTAssertNil(regexError);
50+
51+
// Smoke test the test regex.
52+
NSString* testString = @"9";
53+
NSUInteger versionMatches =
54+
[osVersionRegex numberOfMatchesInString:testString
55+
options:NSMatchingAnchored
56+
range:NSMakeRange(0, testString.length)];
57+
XCTAssertEqual(versionMatches, 1UL);
58+
testString = @"9.1";
59+
versionMatches = [osVersionRegex numberOfMatchesInString:testString
60+
options:NSMatchingAnchored
61+
range:NSMakeRange(0, testString.length)];
62+
XCTAssertEqual(versionMatches, 1UL);
63+
testString = @"9.0.1";
64+
versionMatches = [osVersionRegex numberOfMatchesInString:testString
65+
options:NSMatchingAnchored
66+
range:NSMakeRange(0, testString.length)];
67+
XCTAssertEqual(versionMatches, 1UL);
68+
testString = @".0.1";
69+
versionMatches = [osVersionRegex numberOfMatchesInString:testString
70+
options:NSMatchingAnchored
71+
range:NSMakeRange(0, testString.length)];
72+
XCTAssertEqual(versionMatches, 0UL);
73+
74+
// Test Info.plist values.
75+
NSString* minimumOSVersion = infoDictionary[@"MinimumOSVersion"];
76+
versionMatches = [osVersionRegex numberOfMatchesInString:minimumOSVersion
77+
options:NSMatchingAnchored
78+
range:NSMakeRange(0, minimumOSVersion.length)];
79+
XCTAssertEqual(versionMatches, 1UL);
80+
81+
// SHA length is 40.
82+
XCTAssertEqual(((NSString*)infoDictionary[@"FlutterEngine"]).length, 40UL);
83+
84+
// {clang_version} placeholder is 15 characters. The clang string version
85+
// is longer than that, so check if the placeholder has been replaced, without
86+
// actually checking a literal string, which could be different on various machines.
87+
XCTAssertTrue(((NSString*)infoDictionary[@"ClangVersion"]).length > 15UL);
88+
}
89+
3390
- (void)testDeallocated {
3491
__weak FlutterEngine* weakEngine = nil;
3592
{

shell/platform/embedder/BUILD.gn

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,14 @@ if (is_mac && !embedder_for_target) {
320320
outputs =
321321
[ "$_flutter_embedder_framework_dir/Versions/A/Resources/Info.plist" ]
322322
args = [
323+
"--source",
323324
rebase_path(sources[0]),
325+
"--destination",
324326
rebase_path(outputs[0]),
325-
"--bitcode=$enable_bitcode",
326327
]
328+
if (enable_bitcode) {
329+
args += [ "--bitcode" ]
330+
}
327331
}
328332

329333
copy("copy_module_map") {

shell/platform/embedder/assets/EmbedderInfo.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
<key>NSHumanReadableCopyright</key>
2626
<string>Copyright 2013 The Flutter Authors. All rights reserved.</string>
2727
<key>FlutterEngine</key>
28-
<string>{0}</string>
28+
<string>{revision}</string>
2929
<key>ClangVersion</key>
30-
<string>{1}</string>
30+
<string>{clang_version}</string>
3131
</dict>
3232
</plist>

testing/ios/IosUnitTests/IosUnitTests.xcodeproj/project.pbxproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
0D6AB6BE22BB05E200EEE540 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0D6AB6BD22BB05E200EEE540 /* Assets.xcassets */; };
1515
0D6AB6C122BB05E200EEE540 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0D6AB6BF22BB05E200EEE540 /* LaunchScreen.storyboard */; };
1616
0D6AB6C422BB05E200EEE540 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D6AB6C322BB05E200EEE540 /* main.m */; };
17-
0D6AB73F22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 0D6AB73E22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig */; };
1817
F7521D7826BB68BC005F15C5 /* libios_test_flutter.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = F7521D7226BB671E005F15C5 /* libios_test_flutter.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
1918
F7521D7926BB68BC005F15C5 /* libocmock_shared.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = F7521D7526BB673E005F15C5 /* libocmock_shared.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
19+
F77E081926FA9CE6003E6E4C /* Flutter.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = F77E081726FA9CE6003E6E4C /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
2020
/* End PBXBuildFile section */
2121

2222
/* Begin PBXContainerItemProxy section */
@@ -37,6 +37,7 @@
3737
dstSubfolderSpec = 10;
3838
files = (
3939
F7521D7826BB68BC005F15C5 /* libios_test_flutter.dylib in Embed Libraries */,
40+
F77E081926FA9CE6003E6E4C /* Flutter.framework in Embed Libraries */,
4041
F7521D7926BB68BC005F15C5 /* libocmock_shared.dylib in Embed Libraries */,
4142
);
4243
name = "Embed Libraries";
@@ -70,6 +71,7 @@
7071
0D6AB73E22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = FlutterEngineConfig.xcconfig; sourceTree = "<group>"; };
7172
F7521D7226BB671E005F15C5 /* libios_test_flutter.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libios_test_flutter.dylib; path = "../../../../out/$(FLUTTER_ENGINE)/libios_test_flutter.dylib"; sourceTree = "<group>"; };
7273
F7521D7526BB673E005F15C5 /* libocmock_shared.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libocmock_shared.dylib; path = "../../../../out/$(FLUTTER_ENGINE)/libocmock_shared.dylib"; sourceTree = "<group>"; };
74+
F77E081726FA9CE6003E6E4C /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = "../../../../out/$(FLUTTER_ENGINE)/Flutter.framework"; sourceTree = "<group>"; };
7375
F7A3FDE026B9E0A300EADD61 /* FlutterAppDelegateTest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FlutterAppDelegateTest.mm; sourceTree = "<group>"; };
7476
/* End PBXFileReference section */
7577

@@ -167,6 +169,7 @@
167169
0D6AB6FC22BC1BC300EEE540 /* Frameworks */ = {
168170
isa = PBXGroup;
169171
children = (
172+
F77E081726FA9CE6003E6E4C /* Flutter.framework */,
170173
F7521D7226BB671E005F15C5 /* libios_test_flutter.dylib */,
171174
F7521D7526BB673E005F15C5 /* libocmock_shared.dylib */,
172175
);
@@ -264,7 +267,6 @@
264267
isa = PBXResourcesBuildPhase;
265268
buildActionMask = 2147483647;
266269
files = (
267-
0D6AB73F22BD8F0200EEE540 /* FlutterEngineConfig.xcconfig in Resources */,
268270
);
269271
runOnlyForDeploymentPostprocessing = 0;
270272
};

0 commit comments

Comments
 (0)