Unverified Commit d4150d3f authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Adopt Flutter.xcframework in tool (#71495)

parent f67b94bd
......@@ -102,6 +102,7 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
options: <String>[
'ios-framework',
'--universal',
'--verbose',
'--output=$outputDirectoryName'
],
);
......@@ -164,16 +165,43 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
'App',
);
// This seemed easier than an explicit Xcode version check.
String xcodeArmDirectoryName;
// Based on the locally installed version of Xcode.
String localXcodeArmDirectoryName;
if (exists(File(xcode11AppFrameworkDirectory))) {
xcodeArmDirectoryName = xcode11ArmDirectoryName;
localXcodeArmDirectoryName = xcode11ArmDirectoryName;
} else if (exists(File(xcode12AppFrameworkDirectory))) {
xcodeArmDirectoryName = xcode12ArmDirectoryName;
localXcodeArmDirectoryName = xcode12ArmDirectoryName;
} else {
throw const FileSystemException('Expected App.framework binary to exist.');
}
final String xcode11FlutterFrameworkDirectory = path.join(
outputPath,
'Debug',
'Flutter.xcframework',
xcode11ArmDirectoryName,
'Flutter.framework',
'Flutter',
);
final String xcode12FlutterFrameworkDirectory = path.join(
outputPath,
'Debug',
'Flutter.xcframework',
xcode12ArmDirectoryName,
'Flutter.framework',
'Flutter',
);
// Based on the version of Xcode installed on the engine builder.
String builderXcodeArmDirectoryName;
if (exists(File(xcode11FlutterFrameworkDirectory))) {
builderXcodeArmDirectoryName = xcode11ArmDirectoryName;
} else if (exists(File(xcode12FlutterFrameworkDirectory))) {
builderXcodeArmDirectoryName = xcode12ArmDirectoryName;
} else {
throw const FileSystemException('Expected Flutter.framework binary to exist.');
}
checkFileExists(path.join(
outputPath,
'Debug',
......@@ -214,7 +242,7 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
outputPath,
mode,
'App.xcframework',
xcodeArmDirectoryName,
localXcodeArmDirectoryName,
'App.framework',
'App',
));
......@@ -239,30 +267,25 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
'Flutter',
);
await _checkFrameworkArchs(engineFrameworkPath, mode == 'Debug');
await _checkFrameworkArchs(engineFrameworkPath, true);
await _checkBitcode(engineFrameworkPath, mode);
checkFileExists(path.join(
outputPath,
mode,
'Flutter.xcframework',
xcodeArmDirectoryName,
builderXcodeArmDirectoryName,
'Flutter.framework',
'Flutter',
));
final String simulatorFrameworkPath = path.join(
checkFileExists(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");
......@@ -287,7 +310,7 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
outputPath,
mode,
'device_info.xcframework',
xcodeArmDirectoryName,
localXcodeArmDirectoryName,
'device_info.framework',
'device_info',
));
......@@ -296,7 +319,7 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
outputPath,
mode,
'device_info.xcframework',
xcodeArmDirectoryName,
localXcodeArmDirectoryName,
'device_info.framework',
'Headers',
'DeviceInfoPlugin.h',
......@@ -357,7 +380,7 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
outputPath,
mode,
'FlutterPluginRegistrant.xcframework',
xcodeArmDirectoryName,
localXcodeArmDirectoryName,
'FlutterPluginRegistrant.framework',
'Headers',
'GeneratedPluginRegistrant.h',
......
......@@ -22,6 +22,8 @@ Future<bool> containsBitcode(String pathToBinary) async {
// See: https://stackoverflow.com/questions/32755775/how-to-check-a-static-library-is-built-contain-bitcode
final String loadCommands = await eval('otool', <String>[
'-l',
'-arch',
'arm64',
pathToBinary,
]);
if (!loadCommands.contains('__LLVM')) {
......
......@@ -35,13 +35,27 @@ def flutter_additional_ios_build_settings(target)
# This podhelper script is at $FLUTTER_ROOT/packages/flutter_tools/bin.
# Add search paths from $FLUTTER_ROOT/bin/cache/artifacts/engine.
artifacts_dir = File.join('..', '..', '..', '..', 'bin', 'cache', 'artifacts', 'engine')
debug_framework_dir = File.expand_path(File.join(artifacts_dir, 'ios'), __FILE__)
release_framework_dir = File.expand_path(File.join(artifacts_dir, 'ios-release'), __FILE__)
debug_framework_dir = File.expand_path(File.join(artifacts_dir, 'ios', 'Flutter.xcframework'), __FILE__)
unless Dir.exist?(debug_framework_dir)
# iOS artifacts have not been downloaded.
raise "#{debug_framework_dir} must exist. If you're running pod install manually, make sure flutter build ios is executed first"
end
release_framework_dir = File.expand_path(File.join(artifacts_dir, 'ios-release', 'Flutter.xcframework'), __FILE__)
target.build_configurations.each do |build_configuration|
# Profile can't be derived from the CocoaPods build configuration. Use release framework (for linking only).
configuration_engine_dir = build_configuration.type == :debug ? debug_framework_dir : release_framework_dir
build_configuration.build_settings['FRAMEWORK_SEARCH_PATHS'] = "\"#{configuration_engine_dir}\" $(inherited)"
Dir.new(configuration_engine_dir).each_child do |xcframework_file|
if xcframework_file.end_with?("-simulator") # ios-x86_64-simulator
build_configuration.build_settings['FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]'] = "\"#{configuration_engine_dir}/#{xcframework_file}\" $(inherited)"
elsif xcframework_file.start_with?("ios-") # ios-armv7_arm64
build_configuration.build_settings['FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]'] = "\"#{configuration_engine_dir}/#{xcframework_file}\" $(inherited)"
else
# Info.plist or another platform.
end
end
build_configuration.build_settings['OTHER_LDFLAGS'] = '$(inherited) -framework Flutter'
build_configuration.build_settings['CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER'] = 'NO'
......
......@@ -115,7 +115,7 @@ is set to release or run \"flutter build ios --release\", then re-run Archive fr
local framework_path="${FLUTTER_ROOT}/bin/cache/artifacts/engine/${artifact_variant}"
local flutter_engine_flag=""
local local_engine_flag=""
local flutter_framework="${framework_path}/Flutter.framework"
local flutter_framework="${framework_path}/Flutter.xcframework"
if [[ -n "$FLUTTER_ENGINE" ]]; then
flutter_engine_flag="--local-engine-src-path=${FLUTTER_ENGINE}"
......@@ -135,7 +135,7 @@ is set to release or run \"flutter build ios --release\", then re-run Archive fr
exit -1
fi
local_engine_flag="--local-engine=${LOCAL_ENGINE}"
flutter_framework="${FLUTTER_ENGINE}/out/${LOCAL_ENGINE}/Flutter.framework"
flutter_framework="${FLUTTER_ENGINE}/out/${LOCAL_ENGINE}/Flutter.xcframework"
fi
local bitcode_flag=""
......
......@@ -5,6 +5,7 @@
import 'package:meta/meta.dart';
import 'package:process/process.dart';
import 'base/common.dart';
import 'base/file_system.dart';
import 'base/platform.dart';
import 'base/utils.dart';
......@@ -305,12 +306,14 @@ class CachedArtifacts implements Artifacts {
BuildMode mode, EnvironmentType environmentType) {
switch (artifact) {
case Artifact.genSnapshot:
case Artifact.flutterFramework:
case Artifact.flutterXcframework:
case Artifact.frontendServerSnapshotForEngineDartSdk:
final String artifactFileName = _artifactToFileName(artifact);
final String engineDir = _getEngineArtifactsPath(platform, mode);
return _fileSystem.path.join(engineDir, artifactFileName);
case Artifact.flutterFramework:
final String engineDir = _getEngineArtifactsPath(platform, mode);
return _getIosEngineArtifactPath(engineDir, environmentType, _fileSystem);
case Artifact.idevicescreenshot:
case Artifact.idevicesyslog:
final String artifactFileName = _artifactToFileName(artifact);
......@@ -527,6 +530,38 @@ HostPlatform _currentHostPlatformAsHost(Platform platform) {
throw UnimplementedError('Host OS not supported.');
}
String _getIosEngineArtifactPath(String engineDirectory,
EnvironmentType environmentType, FileSystem fileSystem) {
final Directory xcframeworkDirectory = fileSystem
.directory(engineDirectory)
.childDirectory(_artifactToFileName(Artifact.flutterXcframework));
if (!xcframeworkDirectory.existsSync()) {
throwToolExit('No xcframework found at ${xcframeworkDirectory.path}. Try running "flutter build ios".');
}
Directory flutterFrameworkSource;
for (final Directory platformDirectory
in xcframeworkDirectory.listSync().whereType<Directory>()) {
if (!platformDirectory.basename.startsWith('ios-')) {
continue;
}
// ios-x86_64-simulator, ios-armv7_arm64 (Xcode 11), or ios-arm64_armv7 (Xcode 12).
final bool simulatorDirectory =
platformDirectory.basename.endsWith('-simulator');
if ((environmentType == EnvironmentType.simulator && simulatorDirectory) ||
(environmentType == EnvironmentType.physical && !simulatorDirectory)) {
flutterFrameworkSource = platformDirectory;
}
}
if (flutterFrameworkSource == null) {
throwToolExit('No iOS frameworks found in ${xcframeworkDirectory.path}');
}
return flutterFrameworkSource
.childDirectory(_artifactToFileName(Artifact.flutterFramework))
.path;
}
/// Manages the artifacts of a locally built engine.
class LocalEngineArtifacts implements Artifacts {
LocalEngineArtifacts(
......@@ -578,7 +613,8 @@ class LocalEngineArtifacts implements Artifacts {
case Artifact.platformLibrariesJson:
return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), 'lib', artifactFileName);
case Artifact.flutterFramework:
return _fileSystem.path.join(engineOutPath, artifactFileName);
return _getIosEngineArtifactPath(
engineOutPath, environmentType, _fileSystem);
case Artifact.flutterPatchedSdkPath:
// When using local engine always use [BuildMode.debug] regardless of
// what was specified in [mode] argument because local engine will
......
......@@ -249,7 +249,7 @@ abstract class UnpackIOS extends Target {
const Source.pattern(
'{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/ios.dart'),
Source.artifact(
Artifact.flutterFramework,
Artifact.flutterXcframework,
platform: TargetPlatform.ios,
mode: buildMode,
),
......
......@@ -924,14 +924,11 @@ abstract class EngineCachedArtifact extends CachedArtifact {
_makeFilesExecutable(dir, operatingSystemUtils);
const List<String> frameworkNames = <String>['Flutter', 'FlutterMacOS'];
for (final String frameworkName in frameworkNames) {
final File frameworkZip = fileSystem.file(fileSystem.path.join(dir.path, '$frameworkName.framework.zip'));
if (frameworkZip.existsSync()) {
final Directory framework = fileSystem.directory(fileSystem.path.join(dir.path, '$frameworkName.framework'));
framework.createSync();
operatingSystemUtils.unzip(frameworkZip, framework);
}
final File frameworkZip = fileSystem.file(fileSystem.path.join(dir.path, 'FlutterMacOS.framework.zip'));
if (frameworkZip.existsSync()) {
final Directory framework = fileSystem.directory(fileSystem.path.join(dir.path, 'FlutterMacOS.framework'));
framework.createSync();
operatingSystemUtils.unzip(frameworkZip, framework);
}
}
......
......@@ -295,10 +295,7 @@ LICENSE
s.source = { :http => '${_cache.storageBaseUrl}/flutter_infra/flutter/${_cache.engineRevision}/$artifactsMode/artifacts.zip' }
s.documentation_url = 'https://flutter.dev/docs'
s.platform = :ios, '8.0'
s.vendored_frameworks = 'Flutter.framework'
s.prepare_command = <<-CMD
unzip Flutter.framework -d Flutter.framework
CMD
s.vendored_frameworks = 'Flutter.xcframework'
end
''';
......@@ -314,56 +311,31 @@ end
Directory modeDirectory,
) async {
final Status status = globals.logger.startProgress(
' ├─Populating Flutter.framework...',
' ├─Populating Flutter.xcframework...',
);
final String engineCacheFlutterFrameworkDirectory = globals.artifacts.getArtifactPath(
Artifact.flutterFramework,
Artifact.flutterXcframework,
platform: TargetPlatform.ios,
mode: buildInfo.mode,
);
final String flutterFrameworkFileName = globals.fs.path.basename(
engineCacheFlutterFrameworkDirectory,
);
final Directory fatFlutterFrameworkCopy = modeDirectory.childDirectory(
final Directory flutterFrameworkCopy = modeDirectory.childDirectory(
flutterFrameworkFileName,
);
try {
// Copy universal engine cache framework to mode directory.
// Copy xcframework engine cache framework to mode directory.
globals.fsUtils.copyDirectorySync(
globals.fs.directory(engineCacheFlutterFrameworkDirectory),
fatFlutterFrameworkCopy,
flutterFrameworkCopy,
);
if (buildInfo.mode != BuildMode.debug) {
final File fatFlutterFrameworkBinary = fatFlutterFrameworkCopy.childFile('Flutter');
// Remove simulator architecture in profile and release mode.
final List<String> lipoCommand = <String>[
...globals.xcode.xcrunCommand(),
'lipo',
fatFlutterFrameworkBinary.path,
'-remove',
'x86_64',
'-output',
fatFlutterFrameworkBinary.path
];
final RunResult lipoResult = await globals.processUtils.run(
lipoCommand,
allowReentrantFlutter: false,
);
if (lipoResult.exitCode != 0) {
throwToolExit(
'Unable to remove simulator architecture in ${buildInfo.mode}: ${lipoResult.stderr}',
);
}
}
} finally {
status.stop();
}
await _produceXCFrameworkFromUniversal(buildInfo, fatFlutterFrameworkCopy);
await _produceUniversalFromXCFramework(buildInfo, flutterFrameworkCopy);
}
Future<void> _produceAppFramework(
......@@ -558,112 +530,34 @@ end
}
}
Future<void> _produceXCFrameworkFromUniversal(BuildInfo buildInfo, Directory fatFramework) async {
if (boolArg('xcframework')) {
final String frameworkBinaryName = globals.fs.path.basenameWithoutExtension(
fatFramework.basename);
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.xcframework...',
' ├─Creating $frameworkBinaryName.framework...',
);
try {
if (buildInfo.mode == BuildMode.debug) {
await _produceDebugXCFramework(fatFramework, frameworkBinaryName);
} else {
await _produceXCFramework(
<Directory>[fatFramework], frameworkBinaryName,
fatFramework.parent);
}
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('universal')) {
fatFramework.deleteSync(recursive: true);
}
}
Future<void> _produceDebugXCFramework(Directory fatFramework, String frameworkBinaryName) async {
final String frameworkFileName = fatFramework.basename;
final File fatFlutterFrameworkBinary = fatFramework.childFile(
frameworkBinaryName,
);
final Directory temporaryOutput = globals.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);
globals.fsUtils.copyDirectorySync(fatFramework, armFlutterFrameworkDirectory);
// Create iOS framework.
List<String> lipoCommand = <String>[
...globals.xcode.xcrunCommand(),
'lipo',
fatFlutterFrameworkBinary.path,
'-remove',
'x86_64',
'-output',
armFlutterFrameworkBinary.path
];
RunResult lipoResult = await globals.processUtils.run(
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);
globals.fsUtils.copyDirectorySync(fatFramework, simulatorFlutterFrameworkDirectory);
lipoCommand = <String>[
...globals.xcode.xcrunCommand(),
'lipo',
fatFlutterFrameworkBinary.path,
'-thin',
'x86_64',
'-output',
simulatorFlutterFrameworkBinary.path
];
lipoResult = await globals.processUtils.run(
lipoCommand,
allowReentrantFlutter: false,
);
if (lipoResult.exitCode != 0) {
throwToolExit(
'Unable to create simulator framework: ${lipoResult.stderr}');
}
// Create XCFramework from iOS and simulator frameworks.
await _produceXCFramework(
<Directory>[
armFlutterFrameworkDirectory,
simulatorFlutterFrameworkDirectory
],
frameworkBinaryName,
fatFramework.parent,
);
} finally {
temporaryOutput.deleteSync(recursive: true);
if (!boolArg('xcframework')) {
xcframework.deleteSync(recursive: true);
}
}
......
......@@ -13,16 +13,14 @@ import '../macos/xcode.dart';
const bool kBitcodeEnabledDefault = false;
Future<void> validateBitcode(BuildMode buildMode, TargetPlatform targetPlatform) async {
Future<void> validateBitcode(BuildMode buildMode, TargetPlatform targetPlatform, EnvironmentType environmentType) async {
final Artifacts localArtifacts = globals.artifacts;
final String flutterFrameworkPath = localArtifacts.getArtifactPath(
Artifact.flutterFramework,
mode: buildMode,
platform: targetPlatform,
environmentType: environmentType,
);
if (!globals.fs.isDirectorySync(flutterFrameworkPath)) {
throwToolExit('Flutter.framework not found at $flutterFrameworkPath');
}
final Xcode xcode = context.get<Xcode>();
final RunResult clangResult = await xcode.clang(<String>['--version']);
......
......@@ -4,6 +4,7 @@
import '../base/fingerprint.dart';
import '../build_info.dart';
import '../cache.dart';
import '../globals.dart' as globals;
import '../plugins.dart';
import '../project.dart';
......@@ -28,6 +29,13 @@ Future<void> processPodsIfNeeded(
xcodeProject.xcodeProjectInfoFile.path,
xcodeProject.podfile.path,
xcodeProject.generatedXcodePropertiesFile.path,
globals.fs.path.join(
Cache.flutterRoot,
'packages',
'flutter_tools',
'bin',
'podhelper.rb',
),
],
fileSystem: globals.fs,
logger: globals.logger,
......
......@@ -659,7 +659,7 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
// to be in this location.
final Directory framework = globals.fs.directory(
globals.artifacts.getArtifactPath(
Artifact.flutterFramework,
Artifact.flutterXcframework,
platform: TargetPlatform.ios,
mode: mode,
environmentType: environmentType,
......@@ -668,7 +668,7 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject {
if (framework.existsSync()) {
globals.fsUtils.copyDirectorySync(
framework,
engineCopyDirectory.childDirectory('Flutter.framework'),
engineCopyDirectory.childDirectory('Flutter.xcframework'),
);
}
}
......
......@@ -14,5 +14,5 @@ Flutter provides an easy and productive way to build and deploy high-performance
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.vendored_frameworks = 'Flutter.framework'
s.vendored_frameworks = 'Flutter.xcframework'
end
......@@ -30,7 +30,7 @@ end
def install_flutter_engine_pod
current_directory = File.expand_path('..', __FILE__)
engine_dir = File.expand_path('engine', current_directory)
framework_name = 'Flutter.framework'
framework_name = 'Flutter.xcframework'
copied_engine = File.expand_path(framework_name, engine_dir)
if !File.exist?(copied_engine)
# Copy the debug engine to have something to link against if the xcode backend script has not run yet.
......
......@@ -42,9 +42,67 @@ void main() {
});
testWithoutContext('getArtifactPath', () {
final String xcframeworkPath = artifacts.getArtifactPath(
Artifact.flutterXcframework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
);
expect(
xcframeworkPath,
fileSystem.path.join(
'root',
'bin',
'cache',
'artifacts',
'engine',
'ios-release',
'Flutter.xcframework',
),
);
expect(
artifacts.getArtifactPath(Artifact.flutterFramework, platform: TargetPlatform.ios, mode: BuildMode.release),
fileSystem.path.join('root', 'bin', 'cache', 'artifacts', 'engine', 'ios-release', 'Flutter.framework'),
() => artifacts.getArtifactPath(
Artifact.flutterFramework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
environmentType: EnvironmentType.simulator,
),
throwsToolExit(
message:
'No xcframework found at $xcframeworkPath. Try running "flutter build ios".'),
);
fileSystem.directory(xcframeworkPath).createSync(recursive: true);
expect(
() => artifacts.getArtifactPath(
Artifact.flutterFramework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
environmentType: EnvironmentType.simulator,
),
throwsToolExit(message: 'No iOS frameworks found in $xcframeworkPath'),
);
fileSystem
.directory(xcframeworkPath)
.childDirectory('ios-x86_64-simulator')
.childDirectory('Flutter.framework')
.createSync(recursive: true);
fileSystem
.directory(xcframeworkPath)
.childDirectory('ios-armv7_arm64')
.childDirectory('Flutter.framework')
.createSync(recursive: true);
expect(
artifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
environmentType: EnvironmentType.simulator),
fileSystem.path
.join(xcframeworkPath, 'ios-x86_64-simulator', 'Flutter.framework'),
);
expect(
artifacts.getArtifactPath(Artifact.flutterFramework,
platform: TargetPlatform.ios, mode: BuildMode.release, environmentType: EnvironmentType.physical),
fileSystem.path.join(xcframeworkPath, 'ios-armv7_arm64', 'Flutter.framework'),
);
expect(
artifacts.getArtifactPath(Artifact.flutterXcframework, platform: TargetPlatform.ios, mode: BuildMode.release),
......@@ -136,13 +194,78 @@ void main() {
});
testWithoutContext('getArtifactPath', () {
final String xcframeworkPath = artifacts.getArtifactPath(
Artifact.flutterXcframework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
);
expect(
artifacts.getArtifactPath(Artifact.flutterFramework, platform: TargetPlatform.ios, mode: BuildMode.release),
fileSystem.path.join('/out', 'android_debug_unopt', 'Flutter.framework'),
xcframeworkPath,
fileSystem.path
.join('/out', 'android_debug_unopt', 'Flutter.xcframework'),
);
expect(
artifacts.getArtifactPath(Artifact.flutterXcframework, platform: TargetPlatform.ios, mode: BuildMode.release),
fileSystem.path.join('/out', 'android_debug_unopt', 'Flutter.xcframework'),
() => artifacts.getArtifactPath(
Artifact.flutterFramework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
environmentType: EnvironmentType.simulator,
),
throwsToolExit(
message:
'No xcframework found at /out/android_debug_unopt/Flutter.xcframework. Try running "flutter build ios".'),
);
fileSystem.directory(xcframeworkPath).createSync(recursive: true);
expect(
() => artifacts.getArtifactPath(
Artifact.flutterFramework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
environmentType: EnvironmentType.simulator,
),
throwsToolExit(
message:
'No iOS frameworks found in /out/android_debug_unopt/Flutter.xcframework'),
);
fileSystem
.directory(xcframeworkPath)
.childDirectory('ios-x86_64-simulator')
.childDirectory('Flutter.framework')
.createSync(recursive: true);
fileSystem
.directory(xcframeworkPath)
.childDirectory('ios-armv7_arm64')
.childDirectory('Flutter.framework')
.createSync(recursive: true);
expect(
artifacts.getArtifactPath(
Artifact.flutterFramework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
environmentType: EnvironmentType.simulator,
),
fileSystem.path
.join(xcframeworkPath, 'ios-x86_64-simulator', 'Flutter.framework'),
);
expect(
artifacts.getArtifactPath(
Artifact.flutterFramework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
environmentType: EnvironmentType.physical,
),
fileSystem.path
.join(xcframeworkPath, 'ios-armv7_arm64', 'Flutter.framework'),
);
expect(
artifacts.getArtifactPath(
Artifact.flutterXcframework,
platform: TargetPlatform.ios,
mode: BuildMode.release,
),
fileSystem.path
.join('/out', 'android_debug_unopt', 'Flutter.xcframework'),
);
expect(
artifacts.getArtifactPath(Artifact.flutterTester),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment