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
e21d8220
Unverified
Commit
e21d8220
authored
Jan 06, 2021
by
Jenn Magder
Committed by
GitHub
Jan 06, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove build ios-framework --universal flag (#73383)
parent
8f07fcce
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
56 additions
and
195 deletions
+56
-195
build_ios_framework_module_test.dart
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
+47
-106
build_ios_framework.dart
...s/flutter_tools/lib/src/commands/build_ios_framework.dart
+9
-89
No files found.
dev/devicelab/bin/tasks/build_ios_framework_module_test.dart
View file @
e21d8220
...
...
@@ -10,7 +10,7 @@ import 'package:flutter_devicelab/framework/task_result.dart';
import
'package:flutter_devicelab/framework/utils.dart'
;
import
'package:path/path.dart'
as
path
;
/// Tests that iOS .
frameworks can be built on module projects
.
/// Tests that iOS .
xcframeworks can be built
.
Future
<
void
>
main
()
async
{
await
task
(()
async
{
...
...
@@ -76,10 +76,10 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
);
});
// First, build the module in Debug to copy the debug version of Flutter.framework.
// This proves "flutter build ios-framework" re-copies the relevant Flutter.framework,
// First, build the module in Debug to copy the debug version of Flutter.
xc
framework.
// This proves "flutter build ios-framework" re-copies the relevant Flutter.
xc
framework,
// otherwise building plugins with bitcode will fail linking because the debug version
// of Flutter.framework does not contain bitcode.
// of Flutter.
xc
framework does not contain bitcode.
await
inDirectory
(
projectDir
,
()
async
{
await
flutter
(
'build'
,
...
...
@@ -101,7 +101,6 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
'build'
,
options:
<
String
>[
'ios-framework'
,
'--universal'
,
'--verbose'
,
'--output=
$outputDirectoryName
'
],
...
...
@@ -110,40 +109,6 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
final
String
outputPath
=
path
.
join
(
projectDir
.
path
,
outputDirectoryName
);
section
(
'Check debug build has Dart snapshot as asset'
);
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
section
(
'Check debug build has no Dart AOT'
);
// There's still an App.framework with a dylib, but it's empty.
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'App'
,
));
final
String
debugAppFrameworkPath
=
path
.
join
(
outputPath
,
'Debug'
,
'App.framework'
,
'App'
,
);
final
String
aotSymbols
=
await
dylibSymbols
(
debugAppFrameworkPath
);
if
(
aotSymbols
.
contains
(
'architecture'
)
||
aotSymbols
.
contains
(
'_kDartVmSnapshot'
))
{
throw
TaskResult
.
failure
(
'Debug App.framework contains AOT'
);
}
await
_checkFrameworkArchs
(
debugAppFrameworkPath
,
true
);
// Xcode changed the name of this generated directory in Xcode 12.
const
String
xcode11ArmDirectoryName
=
'ios-armv7_arm64'
;
const
String
xcode12ArmDirectoryName
=
'ios-arm64_armv7'
;
...
...
@@ -202,26 +167,49 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
throw
const
FileSystemException
(
'Expected Flutter.framework binary to exist.'
);
}
final
String
debugAppFrameworkPath
=
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
localXcodeArmDirectoryName
,
'App.framework'
,
'App'
,
);
checkFileExists
(
debugAppFrameworkPath
);
section
(
'Check debug build has Dart snapshot as asset'
);
checkFileExists
(
path
.
join
(
outputPath
,
'Debug'
,
'App.xcframework'
,
'ios-x86_64-simulator'
,
'App.framework'
,
'App'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
section
(
'Check debug build has no Dart AOT'
);
final
String
aotSymbols
=
await
dylibSymbols
(
debugAppFrameworkPath
);
if
(
aotSymbols
.
contains
(
'architecture'
)
||
aotSymbols
.
contains
(
'_kDartVmSnapshot'
))
{
throw
TaskResult
.
failure
(
'Debug App.framework contains AOT'
);
}
section
(
'Check profile, release builds has Dart AOT dylib'
);
for
(
final
String
mode
in
<
String
>[
'Profile'
,
'Release'
])
{
final
String
appFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
localXcodeArmDirectoryName
,
'App.framework'
,
'App'
,
);
await
_checkFrameworkArchs
(
appFrameworkPath
,
false
);
await
_checkBitcode
(
appFrameworkPath
,
mode
);
final
String
aotSymbols
=
await
dylibSymbols
(
appFrameworkPath
);
...
...
@@ -231,20 +219,13 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
}
checkFileNotExists
(
path
.
join
(
outputPath
,
mode
,
'App.framework'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'App.xcframework'
,
localXcodeArmDirectoryName
,
'App.framework'
,
'App'
,
'flutter_assets'
,
'vm_snapshot_data'
,
));
checkFileNotExists
(
path
.
join
(
...
...
@@ -263,57 +244,46 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
final
String
engineFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'Flutter.xcframework'
,
builderXcodeArmDirectoryName
,
'Flutter.framework'
,
'Flutter'
,
);
await
_checkFrameworkArchs
(
engineFrameworkPath
,
true
);
await
_checkBitcode
(
engineFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'Flutter.xcframework'
,
builderXcodeArmDirectoryName
,
'ios-x86_64-simulator'
,
'Flutter.framework'
,
'Flutter'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'Flutter.xcframework'
,
'ios-x86_64-simulator'
,
'Flutter.framework'
,
'Flutter'
,
'Headers'
,
'Flutter.h'
,
));
}
section
(
"Check all modes' engine header"
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'Flutter.framework'
,
'Headers'
,
'Flutter.h'
));
}
section
(
'Check all modes have plugins'
);
for
(
final
String
mode
in
<
String
>[
'Debug'
,
'Profile'
,
'Release'
])
{
final
String
pluginFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'device_info.framework'
,
'device_info'
,
);
await
_checkFrameworkArchs
(
pluginFrameworkPath
,
mode
==
'Debug'
);
await
_checkBitcode
(
pluginFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'device_info.xcframework'
,
localXcodeArmDirectoryName
,
'device_info.framework'
,
'device_info'
,
));
);
await
_checkBitcode
(
pluginFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
...
...
@@ -362,20 +332,13 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
final
String
registrantFrameworkPath
=
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.xcframework'
,
localXcodeArmDirectoryName
,
'FlutterPluginRegistrant.framework'
,
'FlutterPluginRegistrant'
'FlutterPluginRegistrant'
,
);
await
_checkFrameworkArchs
(
registrantFrameworkPath
,
mode
==
'Debug'
);
await
_checkBitcode
(
registrantFrameworkPath
,
mode
);
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
'Headers'
,
'GeneratedPluginRegistrant.h'
,
));
checkFileExists
(
path
.
join
(
outputPath
,
mode
,
...
...
@@ -412,7 +375,6 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
options:
<
String
>[
'ios-framework'
,
'--cocoapods'
,
'--universal'
,
'--force'
,
// Allow podspec creation on master.
'--output=
$cocoapodsOutputDirectoryName
'
],
...
...
@@ -430,29 +392,29 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'App.framework'
,
'App.
xc
framework'
,
));
if
(
Directory
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'FlutterPluginRegistrant.framework'
,
'FlutterPluginRegistrant.
xc
framework'
,
)).
existsSync
()
!=
isModule
)
{
throw
TaskResult
.
failure
(
'Unexpected FlutterPluginRegistrant.framework.'
);
'Unexpected FlutterPluginRegistrant.
xc
framework.'
);
}
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'device_info.framework'
,
'device_info.
xc
framework'
,
));
checkDirectoryExists
(
path
.
join
(
cocoapodsOutputPath
,
mode
,
'package_info.framework'
,
'package_info.
xc
framework'
,
));
}
...
...
@@ -473,27 +435,6 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
}
}
Future
<
void
>
_checkFrameworkArchs
(
String
frameworkPath
,
bool
shouldContainSimulator
)
async
{
checkFileExists
(
frameworkPath
);
final
String
archs
=
await
fileType
(
frameworkPath
);
if
(!
archs
.
contains
(
'armv7'
))
{
throw
TaskResult
.
failure
(
'
$frameworkPath
armv7 architecture missing'
);
}
if
(!
archs
.
contains
(
'arm64'
))
{
throw
TaskResult
.
failure
(
'
$frameworkPath
arm64 architecture missing'
);
}
final
bool
containsSimulator
=
archs
.
contains
(
'x86_64'
);
// Debug should contain the simulator archs.
// Release and Profile should not.
if
(
containsSimulator
!=
shouldContainSimulator
)
{
throw
TaskResult
.
failure
(
'
$frameworkPath
x86_64 architecture
${shouldContainSimulator ? 'missing' : 'present'}
'
);
}
}
Future
<
void
>
_checkBitcode
(
String
frameworkPath
,
String
mode
)
async
{
checkFileExists
(
frameworkPath
);
...
...
packages/flutter_tools/lib/src/commands/build_ios_framework.dart
View file @
e21d8220
...
...
@@ -73,14 +73,15 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
'By default, all build configurations are built.'
)
..
addFlag
(
'universal'
,
help:
'(Deprecated) Produce universal frameworks that include all valid architectures. '
'This option will be removed in a future version of Flutter.'
,
help:
'(Deprecated) Produce universal frameworks that include all valid architectures.'
,
negatable:
true
,
hide:
true
,
)
..
addFlag
(
'xcframework'
,
help:
'Produce xcframeworks that include all valid architectures.'
,
negatable:
false
,
defaultsTo:
true
,
hide:
true
,
)
..
addFlag
(
'cocoapods'
,
help:
'Produce a Flutter.podspec instead of an engine Flutter.xcframework (recommended if host app uses CocoaPods).'
,
...
...
@@ -115,7 +116,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
final
String
name
=
'ios-framework'
;
@override
final
String
description
=
'Produces .frameworks for a Flutter project '
final
String
description
=
'Produces .
xc
frameworks for a Flutter project '
'and its plugins for integration into existing, plain Xcode projects.
\n
'
'This can only be run on macOS hosts.'
;
...
...
@@ -150,16 +151,8 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
throwToolExit
(
'Building frameworks for iOS is only supported on the Mac.'
);
}
if
(!
boolArg
(
'universal'
)
&&
!
boolArg
(
'xcframework'
))
{
throwToolExit
(
'--xcframework or --universal is required.'
);
}
if
(
boolArg
(
'xcframework'
)
&&
globals
.
xcode
.
majorVersion
<
11
)
{
throwToolExit
(
'--xcframework requires Xcode 11.'
);
}
if
(
boolArg
(
'universal'
))
{
globals
.
printError
(
'--universal has been deprecated to support Apple '
'Silicon ARM simulators and will be removed in a future version of '
'Flutter. Use --xcframework instead.'
);
throwToolExit
(
'--universal has been deprecated, only XCFrameworks are supported.'
);
}
if
((
await
buildInfos
).
isEmpty
)
{
throwToolExit
(
'At least one of "--debug" or "--profile", or "--release" is required.'
);
...
...
@@ -196,7 +189,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
_flutterVersion
??=
globals
.
flutterVersion
;
produceFlutterPodspec
(
buildInfo
.
mode
,
modeDirectory
,
force:
boolArg
(
'force'
));
}
else
{
// Copy Flutter.framework.
// Copy Flutter.
xc
framework.
await
_produceFlutterFramework
(
buildInfo
,
modeDirectory
);
}
...
...
@@ -311,7 +304,7 @@ end
Directory modeDirectory,
) async {
final Status status = globals.logger.startProgress(
'
├─
Populat
ing
Flutter
.
xcframework
...
',
'
├─
Copy
ing
Flutter
.
xcframework
...
',
);
final String engineCacheFlutterFrameworkDirectory = globals.artifacts.getArtifactPath(
Artifact.flutterXcframework,
...
...
@@ -334,8 +327,6 @@ end
} finally {
status.stop();
}
await _produceUniversalFromXCFramework(buildInfo, flutterFrameworkCopy);
}
Future<void> _produceAppFramework(
...
...
@@ -347,7 +338,7 @@ end
const String appFrameworkName = '
App
.
framework
';
final Status status = globals.logger.startProgress(
'
├─
Building
App
.
framework
...
',
'
├─
Building
App
.
xc
framework
...
',
);
final List<EnvironmentType> environmentTypes = <EnvironmentType>[
EnvironmentType.physical,
...
...
@@ -407,14 +398,13 @@ end
in result.exceptions.values) {
globals.printError(measurement.exception.toString());
}
throwToolExit('
The
App
.
framework
build
failed
.
');
throwToolExit('
The
App
.
xc
framework
build
failed
.
');
}
}
} finally {
status.stop();
}
await _produceUniversalFramework(frameworks, '
App
', outputDirectory);
await _produceXCFramework(frameworks, '
App
', outputDirectory);
}
...
...
@@ -520,7 +510,6 @@ end
.childDirectory(podFrameworkName)
];
await _produceUniversalFramework(frameworks, binaryName, modeDirectory);
await _produceXCFramework(frameworks, binaryName, modeDirectory);
}
}
...
...
@@ -529,37 +518,6 @@ end
}
}
Future<void> _produceUniversalFromXCFramework(BuildInfo buildInfo, Directory xcframework) async {
if (boolArg('
universal
')) {
final String frameworkBinaryName =
globals.fs.path.basenameWithoutExtension(xcframework.basename);
final Status status = globals.logger.startProgress(
'
├─
Creating
$frameworkBinaryName
.
framework
...
',
);
try {
final Iterable<Directory> frameworks = xcframework
.listSync()
.whereType<Directory>()
.map((Directory triple) => triple
.listSync()
.whereType<Directory>()
.firstWhere((Directory frameworkDirectory) =>
frameworkDirectory.basename ==
'
$frameworkBinaryName
.
framework
'));
await _produceUniversalFramework(
frameworks, frameworkBinaryName, xcframework.parent);
} finally {
status.stop();
}
}
if (!boolArg('
xcframework
')) {
xcframework.deleteSync(recursive: true);
}
}
Future<void> _produceXCFramework(Iterable<Directory> frameworks,
String frameworkBinaryName, Directory outputDirectory) async {
if (!boolArg('
xcframework
')) {
...
...
@@ -587,42 +545,4 @@ end
'
Unable
to
create
$frameworkBinaryName
.
xcframework
:
$
{
xcframeworkResult
.
stderr
}
');
}
}
Future<void> _produceUniversalFramework(Iterable<Directory> frameworks,
String frameworkBinaryName, Directory outputDirectory) async {
if (!boolArg('
universal
')) {
return;
}
final Directory outputFrameworkDirectory =
outputDirectory.childDirectory('
$frameworkBinaryName
.
framework
');
// Copy the first framework over completely to get headers, resources, etc.
globals.fsUtils.copyDirectorySync(
frameworks.first,
outputFrameworkDirectory,
);
// Recreate the framework binary by lipo'
ing
the
framework
binaries
together
.
final
List
<
String
>
lipoCommand
=
<
String
>[
...
globals
.
xcode
.
xcrunCommand
(),
'lipo'
,
'-create'
,
for
(
Directory
framework
in
frameworks
)
...<
String
>[
framework
.
childFile
(
frameworkBinaryName
).
path
],
'-output'
,
outputFrameworkDirectory
.
childFile
(
frameworkBinaryName
).
path
];
final
RunResult
lipoResult
=
await
globals
.
processUtils
.
run
(
lipoCommand
,
workingDirectory:
outputDirectory
.
path
,
allowReentrantFlutter:
false
,
);
if
(
lipoResult
.
exitCode
!=
0
)
{
throwToolExit
(
'Unable to create
$frameworkBinaryName
.framework:
${lipoResult.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