mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Remove build ios-framework --universal flag (#73383)
This commit is contained in:
parent
8f07fccee8
commit
e21d822074
@ -10,7 +10,7 @@ import 'package:flutter_devicelab/framework/task_result.dart';
|
|||||||
import 'package:flutter_devicelab/framework/utils.dart';
|
import 'package:flutter_devicelab/framework/utils.dart';
|
||||||
import 'package:path/path.dart' as path;
|
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 {
|
Future<void> main() async {
|
||||||
await task(() 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.
|
// First, build the module in Debug to copy the debug version of Flutter.xcframework.
|
||||||
// This proves "flutter build ios-framework" re-copies the relevant Flutter.framework,
|
// This proves "flutter build ios-framework" re-copies the relevant Flutter.xcframework,
|
||||||
// otherwise building plugins with bitcode will fail linking because the debug version
|
// otherwise building plugins with bitcode will fail linking because the debug version
|
||||||
// of Flutter.framework does not contain bitcode.
|
// of Flutter.xcframework does not contain bitcode.
|
||||||
await inDirectory(projectDir, () async {
|
await inDirectory(projectDir, () async {
|
||||||
await flutter(
|
await flutter(
|
||||||
'build',
|
'build',
|
||||||
@ -101,7 +101,6 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
|||||||
'build',
|
'build',
|
||||||
options: <String>[
|
options: <String>[
|
||||||
'ios-framework',
|
'ios-framework',
|
||||||
'--universal',
|
|
||||||
'--verbose',
|
'--verbose',
|
||||||
'--output=$outputDirectoryName'
|
'--output=$outputDirectoryName'
|
||||||
],
|
],
|
||||||
@ -110,40 +109,6 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
|||||||
|
|
||||||
final String outputPath = path.join(projectDir.path, outputDirectoryName);
|
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.
|
// Xcode changed the name of this generated directory in Xcode 12.
|
||||||
const String xcode11ArmDirectoryName = 'ios-armv7_arm64';
|
const String xcode11ArmDirectoryName = 'ios-armv7_arm64';
|
||||||
const String xcode12ArmDirectoryName = 'ios-arm64_armv7';
|
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.');
|
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(
|
checkFileExists(path.join(
|
||||||
outputPath,
|
outputPath,
|
||||||
'Debug',
|
'Debug',
|
||||||
'App.xcframework',
|
'App.xcframework',
|
||||||
'ios-x86_64-simulator',
|
'ios-x86_64-simulator',
|
||||||
'App.framework',
|
'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');
|
section('Check profile, release builds has Dart AOT dylib');
|
||||||
|
|
||||||
for (final String mode in <String>['Profile', 'Release']) {
|
for (final String mode in <String>['Profile', 'Release']) {
|
||||||
final String appFrameworkPath = path.join(
|
final String appFrameworkPath = path.join(
|
||||||
outputPath,
|
outputPath,
|
||||||
mode,
|
mode,
|
||||||
|
'App.xcframework',
|
||||||
|
localXcodeArmDirectoryName,
|
||||||
'App.framework',
|
'App.framework',
|
||||||
'App',
|
'App',
|
||||||
);
|
);
|
||||||
|
|
||||||
await _checkFrameworkArchs(appFrameworkPath, false);
|
|
||||||
await _checkBitcode(appFrameworkPath, mode);
|
await _checkBitcode(appFrameworkPath, mode);
|
||||||
|
|
||||||
final String aotSymbols = await dylibSymbols(appFrameworkPath);
|
final String aotSymbols = await dylibSymbols(appFrameworkPath);
|
||||||
@ -231,20 +219,13 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkFileNotExists(path.join(
|
checkFileNotExists(path.join(
|
||||||
outputPath,
|
|
||||||
mode,
|
|
||||||
'App.framework',
|
|
||||||
'flutter_assets',
|
|
||||||
'vm_snapshot_data',
|
|
||||||
));
|
|
||||||
|
|
||||||
checkFileExists(path.join(
|
|
||||||
outputPath,
|
outputPath,
|
||||||
mode,
|
mode,
|
||||||
'App.xcframework',
|
'App.xcframework',
|
||||||
localXcodeArmDirectoryName,
|
localXcodeArmDirectoryName,
|
||||||
'App.framework',
|
'App.framework',
|
||||||
'App',
|
'flutter_assets',
|
||||||
|
'vm_snapshot_data',
|
||||||
));
|
));
|
||||||
|
|
||||||
checkFileNotExists(path.join(
|
checkFileNotExists(path.join(
|
||||||
@ -261,23 +242,16 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
|||||||
|
|
||||||
for (final String mode in <String>['Debug', 'Profile', 'Release']) {
|
for (final String mode in <String>['Debug', 'Profile', 'Release']) {
|
||||||
final String engineFrameworkPath = path.join(
|
final String engineFrameworkPath = path.join(
|
||||||
outputPath,
|
|
||||||
mode,
|
|
||||||
'Flutter.framework',
|
|
||||||
'Flutter',
|
|
||||||
);
|
|
||||||
|
|
||||||
await _checkFrameworkArchs(engineFrameworkPath, true);
|
|
||||||
await _checkBitcode(engineFrameworkPath, mode);
|
|
||||||
|
|
||||||
checkFileExists(path.join(
|
|
||||||
outputPath,
|
outputPath,
|
||||||
mode,
|
mode,
|
||||||
'Flutter.xcframework',
|
'Flutter.xcframework',
|
||||||
builderXcodeArmDirectoryName,
|
builderXcodeArmDirectoryName,
|
||||||
'Flutter.framework',
|
'Flutter.framework',
|
||||||
'Flutter',
|
'Flutter',
|
||||||
));
|
);
|
||||||
|
|
||||||
|
await _checkBitcode(engineFrameworkPath, mode);
|
||||||
|
|
||||||
checkFileExists(path.join(
|
checkFileExists(path.join(
|
||||||
outputPath,
|
outputPath,
|
||||||
mode,
|
mode,
|
||||||
@ -286,34 +260,30 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
|||||||
'Flutter.framework',
|
'Flutter.framework',
|
||||||
'Flutter',
|
'Flutter',
|
||||||
));
|
));
|
||||||
}
|
|
||||||
|
|
||||||
section("Check all modes' engine header");
|
checkFileExists(path.join(
|
||||||
|
outputPath,
|
||||||
for (final String mode in <String>['Debug', 'Profile', 'Release']) {
|
mode,
|
||||||
checkFileExists(path.join(outputPath, mode, 'Flutter.framework', 'Headers', 'Flutter.h'));
|
'Flutter.xcframework',
|
||||||
|
'ios-x86_64-simulator',
|
||||||
|
'Flutter.framework',
|
||||||
|
'Headers',
|
||||||
|
'Flutter.h',
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
section('Check all modes have plugins');
|
section('Check all modes have plugins');
|
||||||
|
|
||||||
for (final String mode in <String>['Debug', 'Profile', 'Release']) {
|
for (final String mode in <String>['Debug', 'Profile', 'Release']) {
|
||||||
final String pluginFrameworkPath = path.join(
|
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,
|
outputPath,
|
||||||
mode,
|
mode,
|
||||||
'device_info.xcframework',
|
'device_info.xcframework',
|
||||||
localXcodeArmDirectoryName,
|
localXcodeArmDirectoryName,
|
||||||
'device_info.framework',
|
'device_info.framework',
|
||||||
'device_info',
|
'device_info',
|
||||||
));
|
);
|
||||||
|
await _checkBitcode(pluginFrameworkPath, mode);
|
||||||
|
|
||||||
checkFileExists(path.join(
|
checkFileExists(path.join(
|
||||||
outputPath,
|
outputPath,
|
||||||
@ -362,20 +332,13 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
|||||||
final String registrantFrameworkPath = path.join(
|
final String registrantFrameworkPath = path.join(
|
||||||
outputPath,
|
outputPath,
|
||||||
mode,
|
mode,
|
||||||
|
'FlutterPluginRegistrant.xcframework',
|
||||||
|
localXcodeArmDirectoryName,
|
||||||
'FlutterPluginRegistrant.framework',
|
'FlutterPluginRegistrant.framework',
|
||||||
'FlutterPluginRegistrant'
|
'FlutterPluginRegistrant',
|
||||||
);
|
);
|
||||||
|
|
||||||
await _checkFrameworkArchs(registrantFrameworkPath, mode == 'Debug');
|
|
||||||
await _checkBitcode(registrantFrameworkPath, mode);
|
await _checkBitcode(registrantFrameworkPath, mode);
|
||||||
|
|
||||||
checkFileExists(path.join(
|
|
||||||
outputPath,
|
|
||||||
mode,
|
|
||||||
'FlutterPluginRegistrant.framework',
|
|
||||||
'Headers',
|
|
||||||
'GeneratedPluginRegistrant.h',
|
|
||||||
));
|
|
||||||
checkFileExists(path.join(
|
checkFileExists(path.join(
|
||||||
outputPath,
|
outputPath,
|
||||||
mode,
|
mode,
|
||||||
@ -412,7 +375,6 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
|||||||
options: <String>[
|
options: <String>[
|
||||||
'ios-framework',
|
'ios-framework',
|
||||||
'--cocoapods',
|
'--cocoapods',
|
||||||
'--universal',
|
|
||||||
'--force', // Allow podspec creation on master.
|
'--force', // Allow podspec creation on master.
|
||||||
'--output=$cocoapodsOutputDirectoryName'
|
'--output=$cocoapodsOutputDirectoryName'
|
||||||
],
|
],
|
||||||
@ -430,29 +392,29 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
|||||||
checkDirectoryExists(path.join(
|
checkDirectoryExists(path.join(
|
||||||
cocoapodsOutputPath,
|
cocoapodsOutputPath,
|
||||||
mode,
|
mode,
|
||||||
'App.framework',
|
'App.xcframework',
|
||||||
));
|
));
|
||||||
|
|
||||||
if (Directory(path.join(
|
if (Directory(path.join(
|
||||||
cocoapodsOutputPath,
|
cocoapodsOutputPath,
|
||||||
mode,
|
mode,
|
||||||
'FlutterPluginRegistrant.framework',
|
'FlutterPluginRegistrant.xcframework',
|
||||||
)).existsSync() !=
|
)).existsSync() !=
|
||||||
isModule) {
|
isModule) {
|
||||||
throw TaskResult.failure(
|
throw TaskResult.failure(
|
||||||
'Unexpected FlutterPluginRegistrant.framework.');
|
'Unexpected FlutterPluginRegistrant.xcframework.');
|
||||||
}
|
}
|
||||||
|
|
||||||
checkDirectoryExists(path.join(
|
checkDirectoryExists(path.join(
|
||||||
cocoapodsOutputPath,
|
cocoapodsOutputPath,
|
||||||
mode,
|
mode,
|
||||||
'device_info.framework',
|
'device_info.xcframework',
|
||||||
));
|
));
|
||||||
|
|
||||||
checkDirectoryExists(path.join(
|
checkDirectoryExists(path.join(
|
||||||
cocoapodsOutputPath,
|
cocoapodsOutputPath,
|
||||||
mode,
|
mode,
|
||||||
'package_info.framework',
|
'package_info.xcframework',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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 {
|
Future<void> _checkBitcode(String frameworkPath, String mode) async {
|
||||||
checkFileExists(frameworkPath);
|
checkFileExists(frameworkPath);
|
||||||
|
|
||||||
|
@ -73,14 +73,15 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
|
|||||||
'By default, all build configurations are built.'
|
'By default, all build configurations are built.'
|
||||||
)
|
)
|
||||||
..addFlag('universal',
|
..addFlag('universal',
|
||||||
help: '(Deprecated) Produce universal frameworks that include all valid architectures. '
|
help: '(Deprecated) Produce universal frameworks that include all valid architectures.',
|
||||||
'This option will be removed in a future version of Flutter.',
|
|
||||||
negatable: true,
|
negatable: true,
|
||||||
hide: true,
|
hide: true,
|
||||||
)
|
)
|
||||||
..addFlag('xcframework',
|
..addFlag('xcframework',
|
||||||
help: 'Produce xcframeworks that include all valid architectures.',
|
help: 'Produce xcframeworks that include all valid architectures.',
|
||||||
|
negatable: false,
|
||||||
defaultsTo: true,
|
defaultsTo: true,
|
||||||
|
hide: true,
|
||||||
)
|
)
|
||||||
..addFlag('cocoapods',
|
..addFlag('cocoapods',
|
||||||
help: 'Produce a Flutter.podspec instead of an engine Flutter.xcframework (recommended if host app uses 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';
|
final String name = 'ios-framework';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String description = 'Produces .frameworks for a Flutter project '
|
final String description = 'Produces .xcframeworks for a Flutter project '
|
||||||
'and its plugins for integration into existing, plain Xcode projects.\n'
|
'and its plugins for integration into existing, plain Xcode projects.\n'
|
||||||
'This can only be run on macOS hosts.';
|
'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.');
|
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')) {
|
if (boolArg('universal')) {
|
||||||
globals.printError('--universal has been deprecated to support Apple '
|
throwToolExit('--universal has been deprecated, only XCFrameworks are supported.');
|
||||||
'Silicon ARM simulators and will be removed in a future version of '
|
|
||||||
'Flutter. Use --xcframework instead.');
|
|
||||||
}
|
}
|
||||||
if ((await buildInfos).isEmpty) {
|
if ((await buildInfos).isEmpty) {
|
||||||
throwToolExit('At least one of "--debug" or "--profile", or "--release" is required.');
|
throwToolExit('At least one of "--debug" or "--profile", or "--release" is required.');
|
||||||
@ -196,7 +189,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand {
|
|||||||
_flutterVersion ??= globals.flutterVersion;
|
_flutterVersion ??= globals.flutterVersion;
|
||||||
produceFlutterPodspec(buildInfo.mode, modeDirectory, force: boolArg('force'));
|
produceFlutterPodspec(buildInfo.mode, modeDirectory, force: boolArg('force'));
|
||||||
} else {
|
} else {
|
||||||
// Copy Flutter.framework.
|
// Copy Flutter.xcframework.
|
||||||
await _produceFlutterFramework(buildInfo, modeDirectory);
|
await _produceFlutterFramework(buildInfo, modeDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +304,7 @@ end
|
|||||||
Directory modeDirectory,
|
Directory modeDirectory,
|
||||||
) async {
|
) async {
|
||||||
final Status status = globals.logger.startProgress(
|
final Status status = globals.logger.startProgress(
|
||||||
' ├─Populating Flutter.xcframework...',
|
' ├─Copying Flutter.xcframework...',
|
||||||
);
|
);
|
||||||
final String engineCacheFlutterFrameworkDirectory = globals.artifacts.getArtifactPath(
|
final String engineCacheFlutterFrameworkDirectory = globals.artifacts.getArtifactPath(
|
||||||
Artifact.flutterXcframework,
|
Artifact.flutterXcframework,
|
||||||
@ -334,8 +327,6 @@ end
|
|||||||
} finally {
|
} finally {
|
||||||
status.stop();
|
status.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
await _produceUniversalFromXCFramework(buildInfo, flutterFrameworkCopy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _produceAppFramework(
|
Future<void> _produceAppFramework(
|
||||||
@ -347,7 +338,7 @@ end
|
|||||||
const String appFrameworkName = 'App.framework';
|
const String appFrameworkName = 'App.framework';
|
||||||
|
|
||||||
final Status status = globals.logger.startProgress(
|
final Status status = globals.logger.startProgress(
|
||||||
' ├─Building App.framework...',
|
' ├─Building App.xcframework...',
|
||||||
);
|
);
|
||||||
final List<EnvironmentType> environmentTypes = <EnvironmentType>[
|
final List<EnvironmentType> environmentTypes = <EnvironmentType>[
|
||||||
EnvironmentType.physical,
|
EnvironmentType.physical,
|
||||||
@ -407,14 +398,13 @@ end
|
|||||||
in result.exceptions.values) {
|
in result.exceptions.values) {
|
||||||
globals.printError(measurement.exception.toString());
|
globals.printError(measurement.exception.toString());
|
||||||
}
|
}
|
||||||
throwToolExit('The App.framework build failed.');
|
throwToolExit('The App.xcframework build failed.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
status.stop();
|
status.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
await _produceUniversalFramework(frameworks, 'App', outputDirectory);
|
|
||||||
await _produceXCFramework(frameworks, 'App', outputDirectory);
|
await _produceXCFramework(frameworks, 'App', outputDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,7 +510,6 @@ end
|
|||||||
.childDirectory(podFrameworkName)
|
.childDirectory(podFrameworkName)
|
||||||
];
|
];
|
||||||
|
|
||||||
await _produceUniversalFramework(frameworks, binaryName, modeDirectory);
|
|
||||||
await _produceXCFramework(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,
|
Future<void> _produceXCFramework(Iterable<Directory> frameworks,
|
||||||
String frameworkBinaryName, Directory outputDirectory) async {
|
String frameworkBinaryName, Directory outputDirectory) async {
|
||||||
if (!boolArg('xcframework')) {
|
if (!boolArg('xcframework')) {
|
||||||
@ -587,42 +545,4 @@ end
|
|||||||
'Unable to create $frameworkBinaryName.xcframework: ${xcframeworkResult.stderr}');
|
'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}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user