Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
dc99d61e
Commit
dc99d61e
authored
Jan 02, 2020
by
Jenn Magder
Committed by
Flutter GitHub Bot
Jan 02, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove simulator arch in Profile and Release, App.xcframework (#48002)
parent
a6c3ffe1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
293 additions
and
124 deletions
+293
-124
build_ios_framework_module_test.dart
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
+101
-43
build_ios_framework.dart
...s/flutter_tools/lib/src/commands/build_ios_framework.dart
+192
-81
No files found.
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
View file @
dc99d61e
...
...
@@ -80,61 +80,51 @@ Future<void> main() async {
'App'
,
));
final
String
a
ppFrameworkPath
=
path
.
join
(
final
String
debugA
ppFrameworkPath
=
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'App'
,
);
final
String
aotSymbols
=
await
dylibSymbols
(
a
ppFrameworkPath
);
final
String
aotSymbols
=
await
dylibSymbols
(
debugA
ppFrameworkPath
);
if
(
aotSymbols
.
contains
(
'architecture'
)
||
aotSymbols
.
contains
(
'_kDartVmSnapshot'
))
{
throw
TaskResult
.
failure
(
'Debug App.framework contains AOT'
);
}
await
_checkFrameworkArchs
(
debugAppFrameworkPath
,
'Debug'
);
final
String
debugAppArchs
=
await
fileType
(
appFrameworkPath
);
if
(!
debugAppArchs
.
contains
(
'armv7'
))
{
throw
TaskResult
.
failure
(
'Debug App.framework armv7 architecture missing'
);
}
if
(!
debugAppArchs
.
contains
(
'arm64'
))
{
throw
TaskResult
.
failure
(
'Debug App.framework arm64 architecture missing'
);
}
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
'ios-armv7_arm64'
,
'App.framework'
,
'App'
,
));
if
(!
debugAppArchs
.
contains
(
'x86_64'
))
{
throw
TaskResult
.
failure
(
'Debug App.framework x86_64 architecture missing'
);
}
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
'ios-x86_64-simulator'
,
'App.framework'
,
'App'
,
));
section
(
'Check profile, release builds has Dart AOT dylib'
);
for
(
String
mode
in
<
String
>[
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'App'
,
));
final
String
aotSymbols
=
await
dylibSymbols
(
path
.
join
(
final
String
appFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'App'
,
)
)
;
);
if
(!
aotSymbols
.
contains
(
'armv7'
))
{
throw
TaskResult
.
failure
(
'
$mode
App.framework armv7 architecture missing'
);
}
await
_checkFrameworkArchs
(
appFrameworkPath
,
mode
);
if
(!
aotSymbols
.
contains
(
'arm64'
))
{
throw
TaskResult
.
failure
(
'
$mode
App.framework arm64 architecture missing'
);
}
if
(
aotSymbols
.
contains
(
'x86_64'
))
{
throw
TaskResult
.
failure
(
'
$mode
App.framework contains x86_64 architecture'
);
}
final
String
aotSymbols
=
await
dylibSymbols
(
appFrameworkPath
);
if
(!
aotSymbols
.
contains
(
'_kDartVmSnapshot'
))
{
throw
TaskResult
.
failure
(
'
$mode
App.framework missing Dart AOT'
);
...
...
@@ -147,17 +137,38 @@ Future<void> main() async {
'flutter_assets'
,
'vm_snapshot_data'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
'ios-armv7_arm64'
,
'App.framework'
,
'App'
,
));
checkFileNotExists
(
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
'ios-x86_64-simulator'
,
'App.framework'
,
'App'
,
));
}
section
(
"Check all modes' engine dylib"
);
for
(
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
final
String
engineFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'Flutter.framework'
,
'Flutter'
,
));
);
await
_checkFrameworkArchs
(
engineFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
...
...
@@ -166,14 +177,19 @@ Future<void> main() async {
'Flutter.framework'
,
'Flutter'
,
));
checkFileExists
(
path
.
join
(
final
String
simulatorFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'Flutter.xcframework'
,
'ios-x86_64-simulator'
,
'Flutter.framework'
,
'Flutter'
,
));
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorFrameworkPath
);
}
else
{
checkFileNotExists
(
simulatorFrameworkPath
);
}
}
section
(
"Check all modes' engine header"
);
...
...
@@ -188,12 +204,14 @@ Future<void> main() async {
section
(
"Check all modes' have plugin dylib"
);
for
(
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
final
String
pluginFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.framework'
,
'device_info'
,
));
);
await
_checkFrameworkArchs
(
pluginFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
...
...
@@ -202,19 +220,33 @@ Future<void> main() async {
'device_info.framework'
,
'device_info'
,
));
checkFileExists
(
path
.
join
(
final
String
simulatorFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
'ios-x86_64-simulator'
,
'device_info.framework'
,
'device_info'
,
));
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorFrameworkPath
);
}
else
{
checkFileNotExists
(
simulatorFrameworkPath
);
}
}
section
(
"Check all modes' have generated plugin registrant"
);
for
(
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
final
String
registrantFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
'FlutterPluginRegistrant'
);
await
_checkFrameworkArchs
(
registrantFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
...
...
@@ -231,7 +263,7 @@ Future<void> main() async {
'Headers'
,
'GeneratedPluginRegistrant.h'
,
));
checkFileExists
(
path
.
join
(
final
String
simulatorHeaderPath
=
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.xcframework'
,
...
...
@@ -239,7 +271,12 @@ Future<void> main() async {
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
));
);
if
(
mode
==
'Debug'
)
{
checkFileExists
(
simulatorHeaderPath
);
}
else
{
checkFileNotExists
(
simulatorHeaderPath
);
}
}
return
TaskResult
.
success
(
null
);
...
...
@@ -252,3 +289,24 @@ Future<void> main() async {
}
});
}
Future
<
void
>
_checkFrameworkArchs
(
String
frameworkPath
,
String
mode
)
async
{
checkFileExists
(
frameworkPath
);
final
String
archs
=
await
fileType
(
frameworkPath
);
if
(!
archs
.
contains
(
'armv7'
))
{
throw
TaskResult
.
failure
(
'
$mode
$frameworkPath
armv7 architecture missing'
);
}
if
(!
archs
.
contains
(
'arm64'
))
{
throw
TaskResult
.
failure
(
'
$mode
$frameworkPath
arm64 architecture missing'
);
}
final
bool
containsSimulator
=
archs
.
contains
(
'x86_64'
);
final
bool
isDebug
=
mode
==
'Debug'
;
// Debug should contain the simulator archs.
// Release and Profile should not.
if
(
containsSimulator
!=
isDebug
)
{
throw
TaskResult
.
failure
(
'
$mode
$frameworkPath
x86_64 architecture
${isDebug ? 'missing' : 'present'}
'
);
}
}
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
View file @
dc99d61e
...
...
@@ -185,7 +185,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
// Build and copy plugins.
await
processPodsIfNeeded
(
_project
.
ios
,
getIosBuildDirectory
(),
mode
);
if
(
hasPlugins
(
_project
))
{
await
_producePlugins
(
xcodeBuildConfiguration
,
iPhoneBuildOutput
,
simulatorBuildOutput
,
modeDirectory
,
outputDirectory
);
await
_producePlugins
(
mode
,
xcodeBuildConfiguration
,
iPhoneBuildOutput
,
simulatorBuildOutput
,
modeDirectory
,
outputDirectory
);
}
final
Status
status
=
logger
.
startProgress
(
' └─Moving to
${fs.path.relative(modeDirectory.path)}
'
,
timeout:
timeoutConfiguration
.
slowOperation
);
...
...
@@ -268,80 +268,42 @@ end
Future<void> _produceFlutterFramework(Directory outputDirectory, BuildMode mode, Directory iPhoneBuildOutput, Directory simulatorBuildOutput, Directory modeDirectory) async {
final Status status = logger.startProgress('
├─
Populating
Flutter
.
framework
...
', timeout: timeoutConfiguration.slowOperation);
try {
final String engineCacheFlutterFrameworkDirectory = artifacts.getArtifactPath(Artifact.flutterFramework, platform: TargetPlatform.ios, mode: mode);
final String engineCacheFlutterFrameworkDirectory = artifacts.getArtifactPath(Artifact.flutterFramework, platform: TargetPlatform.ios, mode: mode);
final String flutterFrameworkFileName = fs.path.basename(engineCacheFlutterFrameworkDirectory);
final Directory fatFlutterFrameworkCopy = modeDirectory.childDirectory(flutterFrameworkFileName);
try {
// Copy universal engine cache framework to mode directory.
final String flutterFrameworkFileName = fs.path.basename(engineCacheFlutterFrameworkDirectory);
final Directory fatFlutterFrameworkCopy = modeDirectory.childDirectory(flutterFrameworkFileName);
copyDirectorySync(fs.directory(engineCacheFlutterFrameworkDirectory), fatFlutterFrameworkCopy);
if (boolArg('
xcframework
')) {
// Copy universal framework to variant directory.
final Directory armFlutterFrameworkDirectory = iPhoneBuildOutput.childDirectory(flutterFrameworkFileName);
final File armFlutterFrameworkBinary = armFlutterFrameworkDirectory.childFile('
Flutter
');
if (mode != BuildMode.debug) {
final File fatFlutterFrameworkBinary = fatFlutterFrameworkCopy.childFile('
Flutter
');
copyDirectorySync(fatFlutterFrameworkCopy, armFlutterFrameworkDirectory);
// Create iOS framework.
List<String> lipoCommand = <String>['
xcrun
', '
lipo
', fatFlutterFrameworkBinary.path, '
-
remove
', '
x86_64
', '
-
output
', armFlutterFrameworkBinary.path];
RunResult lipoResult = processUtils.runSync(
lipoCommand,
workingDirectory: outputDirectory.path,
allowReentrantFlutter: false,
);
if (lipoResult.exitCode != 0) {
throwToolExit('
Unable
to
create
ARM
engine
framework:
$
{
lipoResult
.
stderr
}
');
}
// Create simulator framework.
final Directory simulatorFlutterFrameworkDirectory = simulatorBuildOutput.childDirectory(flutterFrameworkFileName);
final File simulatorFlutterFrameworkBinary = simulatorFlutterFrameworkDirectory.childFile('
Flutter
');
copyDirectorySync(fatFlutterFrameworkCopy, simulatorFlutterFrameworkDirectory);
lipoCommand = <String>['
xcrun
', '
lipo
', fatFlutterFrameworkBinary.path, '
-
thin
', '
x86_64
', '
-
output
', simulatorFlutterFrameworkBinary.path];
lipoResult = processUtils.runSync(
lipoCommand,
workingDirectory: outputDirectory.path,
allowReentrantFlutter: false,
);
if (lipoResult.exitCode != 0) {
throwToolExit('
Unable
to
create
simulator
engine
framework:
$
{
lipoResult
.
stderr
}
');
}
// Create XCFramework from iOS and simulator frameworks.
final List<String> xcframeworkCommand = <String>[
// Remove simulator architecture in profile and release mode.
final List<String> lipoCommand = <String>[
'
xcrun
',
'
xcodebuild
',
'
-
create
-
xcframework
',
'
-
framework
', armFlutterFrameworkDirectory.path,
'
-
framework
', simulatorFlutterFrameworkDirectory.path,
'
-
output
', modeDirectory
.childFile('
Flutter
.
xcframework
')
.path
'
lipo
',
fatFlutterFrameworkBinary.path,
'
-
remove
',
'
x86_64
',
'
-
output
',
fatFlutterFrameworkBinary.path
];
final RunResult xcframeworkResult = processUtils.runSync(
xcframeworkCommand,
workingDirectory: outputDirectory.path,
final RunResult lipoResult = processUtils.runSync(
lipoCommand,
allowReentrantFlutter: false,
);
if (xcframeworkResult.exitCode != 0) {
throwToolExit('
Unable
to
create
engine
XCFramework:
$
{
xcframeworkResult
.
stderr
}
');
if (lipoResult.exitCode != 0) {
throwToolExit(
'
Unable
to
remove
simulator
architecture
in
$mode
:
$
{
lipoResult
.
stderr
}
');
}
}
if (!boolArg('
universal
')) {
fatFlutterFrameworkCopy.deleteSync(recursive: true);
}
} finally {
status.stop();
}
_produceXCFramework(mode, fatFlutterFrameworkCopy);
}
Future<void> _produceAppFramework(BuildMode mode, Directory iPhoneBuildOutput, Directory simulatorBuildOutput, Directory modeDirectory) async {
...
...
@@ -378,6 +340,7 @@ end
} finally {
status.stop();
}
_produceXCFramework(mode, destinationAppFrameworkDirectory);
}
Future<void> _produceStubAppFrameworkIfNeeded(BuildMode mode, Directory iPhoneBuildOutput, Directory simulatorBuildOutput, Directory destinationAppFrameworkDirectory) async {
...
...
@@ -442,6 +405,7 @@ end
}
Future<void> _producePlugins(
BuildMode mode,
String xcodeBuildConfiguration,
Directory iPhoneBuildOutput,
Directory simulatorBuildOutput,
...
...
@@ -472,27 +436,32 @@ end
throwToolExit('
Unable
to
build
plugin
frameworks:
$
{
buildPluginsResult
.
stderr
}
');
}
pluginsBuildCommand = <String>[
'
xcrun
',
'
xcodebuild
',
'
-
alltargets
',
'
-
sdk
',
'
iphonesimulator
',
'
-
configuration
',
xcodeBuildConfiguration,
'
SYMROOT
=
$
{
simulatorBuildOutput
.
path
}
',
'
ARCHS
=
x86_64
',
'
ONLY_ACTIVE_ARCH
=
NO
' // No device targeted, so build all valid architectures.
];
if (mode == BuildMode.debug) {
pluginsBuildCommand = <String>[
'
xcrun
',
'
xcodebuild
',
'
-
alltargets
',
'
-
sdk
',
'
iphonesimulator
',
'
-
configuration
',
xcodeBuildConfiguration,
'
SYMROOT
=
$
{
simulatorBuildOutput
.
path
}
',
'
ARCHS
=
x86_64
',
'
ONLY_ACTIVE_ARCH
=
NO
'
// No device targeted, so build all valid architectures.
];
buildPluginsResult = processUtils.runSync(
pluginsBuildCommand,
workingDirectory: _project.ios.hostAppRoot.childDirectory('
Pods
').path,
allowReentrantFlutter: false,
);
buildPluginsResult = processUtils.runSync(
pluginsBuildCommand,
workingDirectory: _project.ios.hostAppRoot
.childDirectory('
Pods
')
.path,
allowReentrantFlutter: false,
);
if (buildPluginsResult.exitCode != 0) {
throwToolExit('
Unable
to
build
plugin
frameworks
for
simulator:
$
{
buildPluginsResult
.
stderr
}
');
if (buildPluginsResult.exitCode != 0) {
throwToolExit('
Unable
to
build
plugin
frameworks
for
simulator:
$
{
buildPluginsResult
.
stderr
}
');
}
}
final Directory iPhoneBuildConfiguration = iPhoneBuildOutput.childDirectory('
$xcodeBuildConfiguration
-
iphoneos
');
...
...
@@ -510,7 +479,8 @@ end
'
lipo
',
'
-
create
',
fs.path.join(podProduct.path, binaryName),
simulatorBuildConfiguration.childDirectory(binaryName).childDirectory(podFrameworkName).childFile(binaryName).path,
if (mode == BuildMode.debug)
simulatorBuildConfiguration.childDirectory(binaryName).childDirectory(podFrameworkName).childFile(binaryName).path,
'
-
output
',
modeDirectory.childDirectory(podFrameworkName).childFile(binaryName).path
];
...
...
@@ -533,8 +503,10 @@ end
'
-
create
-
xcframework
',
'
-
framework
',
podProduct.path,
'
-
framework
',
simulatorBuildConfiguration.childDirectory(binaryName).childDirectory(podFrameworkName).path,
if (mode == BuildMode.debug)
'
-
framework
',
if (mode == BuildMode.debug)
simulatorBuildConfiguration.childDirectory(binaryName).childDirectory(podFrameworkName).path,
'
-
output
',
modeDirectory.childFile('
$binaryName
.
xcframework
').path
];
...
...
@@ -556,4 +528,143 @@ end
status.stop();
}
}
void _produceXCFramework(BuildMode mode, Directory fatFramework) {
if (boolArg('
xcframework
')) {
final String frameworkBinaryName = fs.path.basenameWithoutExtension(
fatFramework.basename);
final Status status = logger.startProgress('
├─
Creating
$frameworkBinaryName
.
xcframework
...
', timeout: timeoutConfiguration.fastOperation);
try {
if (mode == BuildMode.debug) {
_produceDebugXCFramework(fatFramework, frameworkBinaryName);
} else {
_produceNonDebugXCFramework(mode, fatFramework, frameworkBinaryName);
}
} finally {
status.stop();
}
}
if (!boolArg('
universal
')) {
fatFramework.deleteSync(recursive: true);
}
}
void _produceDebugXCFramework(Directory fatFramework, String frameworkBinaryName) {
final String frameworkFileName = fatFramework.basename;
final File fatFlutterFrameworkBinary = fatFramework.childFile(
frameworkBinaryName);
final Directory temporaryOutput = fs.systemTempDirectory.createTempSync(
'
flutter_tool_build_ios_framework
.
');
try {
// Copy universal framework to variant directory.
final Directory iPhoneBuildOutput = temporaryOutput.childDirectory(
'
ios
')
..createSync(recursive: true);
final Directory simulatorBuildOutput = temporaryOutput.childDirectory(
'
simulator
')
..createSync(recursive: true);
final Directory armFlutterFrameworkDirectory = iPhoneBuildOutput
.childDirectory(frameworkFileName);
final File armFlutterFrameworkBinary = armFlutterFrameworkDirectory
.childFile(frameworkBinaryName);
copyDirectorySync(fatFramework, armFlutterFrameworkDirectory);
// Create iOS framework.
List<String> lipoCommand = <String>[
'
xcrun
',
'
lipo
',
fatFlutterFrameworkBinary.path,
'
-
remove
',
'
x86_64
',
'
-
output
',
armFlutterFrameworkBinary.path
];
RunResult lipoResult = processUtils.runSync(
lipoCommand,
allowReentrantFlutter: false,
);
if (lipoResult.exitCode != 0) {
throwToolExit('
Unable
to
create
ARM
framework:
$
{
lipoResult
.
stderr
}
');
}
// Create simulator framework.
final Directory simulatorFlutterFrameworkDirectory = simulatorBuildOutput
.childDirectory(frameworkFileName);
final File simulatorFlutterFrameworkBinary = simulatorFlutterFrameworkDirectory
.childFile(frameworkBinaryName);
copyDirectorySync(fatFramework, simulatorFlutterFrameworkDirectory);
lipoCommand = <String>[
'
xcrun
',
'
lipo
',
fatFlutterFrameworkBinary.path,
'
-
thin
',
'
x86_64
',
'
-
output
',
simulatorFlutterFrameworkBinary.path
];
lipoResult = processUtils.runSync(
lipoCommand,
allowReentrantFlutter: false,
);
if (lipoResult.exitCode != 0) {
throwToolExit(
'
Unable
to
create
simulator
framework:
$
{
lipoResult
.
stderr
}
');
}
// Create XCFramework from iOS and simulator frameworks.
final List<String> xcframeworkCommand = <String>[
'
xcrun
',
'
xcodebuild
',
'
-
create
-
xcframework
',
'
-
framework
', armFlutterFrameworkDirectory.path,
'
-
framework
', simulatorFlutterFrameworkDirectory.path,
'
-
output
', fatFramework.parent
.childFile('
$frameworkBinaryName
.
xcframework
')
.path
];
final RunResult xcframeworkResult = processUtils.runSync(
xcframeworkCommand,
allowReentrantFlutter: false,
);
if (xcframeworkResult.exitCode != 0) {
throwToolExit(
'
Unable
to
create
XCFramework:
$
{
xcframeworkResult
.
stderr
}
');
}
} finally {
temporaryOutput.deleteSync(recursive: true);
}
}
void _produceNonDebugXCFramework(BuildMode mode, Directory fatFramework, String frameworkBinaryName) {
// Simulator is only supported in Debug mode.
// "Fat" framework here must only contain arm.
final List<String> xcframeworkCommand = <String>[
'
xcrun
',
'
xcodebuild
',
'
-
create
-
xcframework
',
'
-
framework
', fatFramework.path,
'
-
output
', fatFramework.parent
.childFile('
$frameworkBinaryName
.
xcframework
')
.path
];
final RunResult xcframeworkResult = processUtils.runSync(
xcframeworkCommand,
allowReentrantFlutter: false,
);
if (xcframeworkResult.exitCode != 0) {
throwToolExit(
'
Unable
to
create
XCFramework:
$
{
xcframeworkResult
.
stderr
}
');
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment