mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Enable Swift Package Manager by default on master channel (#152049)
Changes: 1. Enables Swift Package Manager by default on the main/master channel 2. Fixes tests that fail if Swift Package Manager is enabled Corresponding docs change: https://github.com/flutter/website/pull/10938 Addresses https://github.com/flutter/flutter/issues/151567
This commit is contained in:
parent
0d504914c7
commit
08d8a7fa81
@ -151,7 +151,7 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
||||
|
||||
section('Check debug build has no Dart AOT');
|
||||
|
||||
final String aotSymbols = await _dylibSymbols(debugAppFrameworkPath);
|
||||
final String aotSymbols = await dumpSymbolTable(debugAppFrameworkPath);
|
||||
|
||||
if (aotSymbols.contains('architecture') ||
|
||||
aotSymbols.contains('_kDartVmSnapshot')) {
|
||||
@ -172,7 +172,7 @@ Future<void> _testBuildIosFramework(Directory projectDir, { bool isModule = fals
|
||||
|
||||
await _checkDylib(appFrameworkPath);
|
||||
|
||||
final String aotSymbols = await _dylibSymbols(appFrameworkPath);
|
||||
final String aotSymbols = await dumpSymbolTable(appFrameworkPath);
|
||||
|
||||
if (!aotSymbols.contains('_kDartVmSnapshot')) {
|
||||
throw TaskResult.failure('$mode App.framework missing Dart AOT');
|
||||
@ -562,7 +562,7 @@ Future<void> _testBuildMacOSFramework(Directory projectDir) async {
|
||||
|
||||
section('Check debug build has no Dart AOT');
|
||||
|
||||
final String aotSymbols = await _dylibSymbols(debugAppFrameworkPath);
|
||||
final String aotSymbols = await dumpSymbolTable(debugAppFrameworkPath);
|
||||
|
||||
if (aotSymbols.contains('architecture') ||
|
||||
aotSymbols.contains('_kDartVmSnapshot')) {
|
||||
@ -583,7 +583,7 @@ Future<void> _testBuildMacOSFramework(Directory projectDir) async {
|
||||
|
||||
await _checkDylib(appFrameworkPath);
|
||||
|
||||
final String aotSymbols = await _dylibSymbols(appFrameworkPath);
|
||||
final String aotSymbols = await dumpSymbolTable(appFrameworkPath);
|
||||
|
||||
if (!aotSymbols.contains('_kDartVmSnapshot')) {
|
||||
throw TaskResult.failure('$mode App.framework missing Dart AOT');
|
||||
@ -939,15 +939,6 @@ Future<void> _checkStatic(String pathToLibrary) async {
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> _dylibSymbols(String pathToDylib) {
|
||||
return eval('nm', <String>[
|
||||
'-g',
|
||||
pathToDylib,
|
||||
'-arch',
|
||||
'arm64',
|
||||
]);
|
||||
}
|
||||
|
||||
Future<bool> _linksOnFlutter(String pathToBinary) async {
|
||||
final String loadCommands = await eval('otool', <String>[
|
||||
'-l',
|
||||
|
@ -703,13 +703,7 @@ Future<bool> _isAppAotBuild(Directory app) async {
|
||||
'App',
|
||||
);
|
||||
|
||||
final String symbolTable = await eval(
|
||||
'nm',
|
||||
<String> [
|
||||
'-gU',
|
||||
binary,
|
||||
],
|
||||
);
|
||||
final String symbolTable = await dumpSymbolTable(binary);
|
||||
|
||||
return symbolTable.contains('kDartIsolateSnapshotInstructions');
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_devicelab/framework/framework.dart';
|
||||
import 'package:flutter_devicelab/framework/ios.dart';
|
||||
import 'package:flutter_devicelab/framework/task_result.dart';
|
||||
import 'package:flutter_devicelab/framework/utils.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
@ -209,6 +210,7 @@ public class DummyPluginAClass {
|
||||
final String flutterPluginsDependenciesFileContent = flutterPluginsDependenciesFile.readAsStringSync();
|
||||
|
||||
final Map<String, dynamic> jsonContent = json.decode(flutterPluginsDependenciesFileContent) as Map<String, dynamic>;
|
||||
final bool swiftPackageManagerEnabled = jsonContent['swift_package_manager_enabled'] as bool? ?? false;
|
||||
|
||||
// Verify the dependencyGraph object is valid. The rest of the contents of this file are not relevant to the
|
||||
// dependency graph and are tested by unit tests.
|
||||
@ -302,28 +304,35 @@ public class DummyPluginAClass {
|
||||
return TaskResult.failure('Failed to build plugin A example iOS app');
|
||||
}
|
||||
|
||||
checkDirectoryExists(path.join(
|
||||
appBundle.path,
|
||||
'Frameworks',
|
||||
'plugin_a.framework',
|
||||
));
|
||||
checkDirectoryExists(path.join(
|
||||
appBundle.path,
|
||||
'Frameworks',
|
||||
'plugin_b.framework',
|
||||
));
|
||||
checkDirectoryExists(path.join(
|
||||
appBundle.path,
|
||||
'Frameworks',
|
||||
'plugin_c.framework',
|
||||
));
|
||||
if (swiftPackageManagerEnabled) {
|
||||
// Check plugins are built statically if using SwiftPM.
|
||||
final String executable = path.join(appBundle.path, 'Runner');
|
||||
final String symbols = await dumpSymbolTable(executable);
|
||||
|
||||
// Plugin D is Android only and should not be embedded.
|
||||
checkDirectoryNotExists(path.join(
|
||||
appBundle.path,
|
||||
'Frameworks',
|
||||
'plugin_d.framework',
|
||||
));
|
||||
final bool foundA = symbols.contains('plugin_a');
|
||||
final bool foundB = symbols.contains('plugin_b');
|
||||
final bool foundC = symbols.contains('plugin_c');
|
||||
final bool foundD = symbols.contains('plugin_d');
|
||||
|
||||
if (!foundA || !foundB || !foundC) {
|
||||
return TaskResult.failure(
|
||||
'Failed to find plugins_a, plugin_b, or plugin_c symbols in the app'
|
||||
);
|
||||
}
|
||||
|
||||
if (foundD) {
|
||||
return TaskResult.failure(
|
||||
'Found Android plugin_d symbols in iOS app'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Check plugins are built dynamically if using CocoaPods.
|
||||
checkDirectoryExists(path.join(appBundle.path, 'Frameworks', 'plugin_a.framework'));
|
||||
checkDirectoryExists(path.join(appBundle.path, 'Frameworks', 'plugin_b.framework'));
|
||||
checkDirectoryExists(path.join(appBundle.path, 'Frameworks', 'plugin_c.framework'));
|
||||
|
||||
checkDirectoryNotExists(path.join(appBundle.path, 'Frameworks', 'plugin_d.framework'));
|
||||
}
|
||||
}
|
||||
|
||||
return TaskResult.success(null);
|
||||
|
@ -308,3 +308,17 @@ File? _createDisabledSandboxEntitlementFile(
|
||||
|
||||
return disabledSandboxEntitlementFile;
|
||||
}
|
||||
|
||||
/// Returns global (external) symbol table entries, delimited by new lines.
|
||||
Future<String> dumpSymbolTable(String filePath) {
|
||||
return eval(
|
||||
'nm',
|
||||
<String>[
|
||||
'--extern-only',
|
||||
'--just-symbol-name',
|
||||
filePath,
|
||||
'-arch',
|
||||
'arm64',
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -77,6 +77,11 @@ class PluginTest {
|
||||
final _FlutterProject app = await _FlutterProject.create(tempDir, options, buildTarget,
|
||||
name: 'plugintestapp', template: 'app', environment: appCreateEnvironment);
|
||||
try {
|
||||
if (cocoapodsTransitiveFlutterDependency) {
|
||||
section('Disable Swift Package Manager');
|
||||
await app.disableSwiftPackageManager();
|
||||
}
|
||||
|
||||
section('Add plugins');
|
||||
await app.addPlugin('plugintest',
|
||||
pluginPath: path.join('..', 'plugintest'));
|
||||
@ -147,6 +152,20 @@ class _FlutterProject {
|
||||
return _FlutterProject(Directory(path.join(rootPath)), 'example');
|
||||
}
|
||||
|
||||
Future<void> disableSwiftPackageManager() async {
|
||||
final File pubspec = pubspecFile;
|
||||
String content = await pubspec.readAsString();
|
||||
content = content.replaceFirst(
|
||||
'# The following section is specific to Flutter packages.\n'
|
||||
'flutter:\n',
|
||||
'# The following section is specific to Flutter packages.\n'
|
||||
'flutter:\n'
|
||||
'\n'
|
||||
' disable-swift-package-manager: true\n'
|
||||
);
|
||||
await pubspec.writeAsString(content, flush: true);
|
||||
}
|
||||
|
||||
Future<void> addPlugin(String plugin, {String? pluginPath}) async {
|
||||
final File pubspec = pubspecFile;
|
||||
String content = await pubspec.readAsString();
|
||||
@ -244,9 +263,14 @@ class $dartPluginClass {
|
||||
await podspec.writeAsString(podspecContent, flush: true);
|
||||
|
||||
// Make PlugintestPlugin.swift compile on iOS and macOS with target conditionals.
|
||||
// If SwiftPM is disabled, the file will be in `darwin/Classes/`.
|
||||
// Otherwise, the file will be in `darwin/<plugin>/Sources/<plugin>/`.
|
||||
final String pluginClass = '${name[0].toUpperCase()}${name.substring(1)}Plugin';
|
||||
print('pluginClass: $pluginClass');
|
||||
final File pluginRegister = File(path.join(darwinDir.path, 'Classes', '$pluginClass.swift'));
|
||||
File pluginRegister = File(path.join(darwinDir.path, 'Classes', '$pluginClass.swift'));
|
||||
if (!pluginRegister.existsSync()) {
|
||||
pluginRegister = File(path.join(darwinDir.path, name, 'Sources', name, '$pluginClass.swift'));
|
||||
}
|
||||
final String pluginRegisterContent = '''
|
||||
#if os(macOS)
|
||||
import FlutterMacOS
|
||||
@ -494,42 +518,55 @@ s.dependency 'AppAuth', '1.6.0'
|
||||
}
|
||||
|
||||
if (validateNativeBuildProject) {
|
||||
final File podsProject = File(path.join(rootPath, target, 'Pods', 'Pods.xcodeproj', 'project.pbxproj'));
|
||||
if (!podsProject.existsSync()) {
|
||||
throw TaskResult.failure('Xcode Pods project file missing at ${podsProject.path}');
|
||||
}
|
||||
final File generatedSwiftManifest = File(path.join(
|
||||
rootPath,
|
||||
target,
|
||||
'Flutter',
|
||||
'ephemeral',
|
||||
'Packages',
|
||||
'FlutterGeneratedPluginSwiftPackage',
|
||||
'Package.swift'
|
||||
));
|
||||
final bool swiftPackageManagerEnabled = generatedSwiftManifest.existsSync();
|
||||
|
||||
final String podsProjectContent = podsProject.readAsStringSync();
|
||||
if (target == 'ios') {
|
||||
// Plugins with versions lower than the app version should not have IPHONEOS_DEPLOYMENT_TARGET set.
|
||||
// The plugintest plugin target should not have IPHONEOS_DEPLOYMENT_TARGET set since it has been lowered
|
||||
// in _reduceDarwinPluginMinimumVersion to 10, which is below the target version of 11.
|
||||
if (podsProjectContent.contains('IPHONEOS_DEPLOYMENT_TARGET = 10')) {
|
||||
throw TaskResult.failure('Plugin build setting IPHONEOS_DEPLOYMENT_TARGET not removed');
|
||||
if (!swiftPackageManagerEnabled) {
|
||||
final File podsProject = File(path.join(rootPath, target, 'Pods', 'Pods.xcodeproj', 'project.pbxproj'));
|
||||
if (!podsProject.existsSync()) {
|
||||
throw TaskResult.failure('Xcode Pods project file missing at ${podsProject.path}');
|
||||
}
|
||||
// Transitive dependency AppAuth targeting too-low 8.0 was not fixed.
|
||||
if (podsProjectContent.contains('IPHONEOS_DEPLOYMENT_TARGET = 8')) {
|
||||
throw TaskResult.failure('Transitive dependency build setting IPHONEOS_DEPLOYMENT_TARGET=8 not removed');
|
||||
}
|
||||
if (!podsProjectContent.contains(r'"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "$(inherited) i386";')) {
|
||||
throw TaskResult.failure(r'EXCLUDED_ARCHS is not "$(inherited) i386"');
|
||||
}
|
||||
} else if (target == 'macos') {
|
||||
// Same for macOS deployment target, but 10.8.
|
||||
// The plugintest target should not have MACOSX_DEPLOYMENT_TARGET set.
|
||||
if (podsProjectContent.contains('MACOSX_DEPLOYMENT_TARGET = 10.8')) {
|
||||
throw TaskResult.failure('Plugin build setting MACOSX_DEPLOYMENT_TARGET not removed');
|
||||
}
|
||||
// Transitive dependency AppAuth targeting too-low 10.9 was not fixed.
|
||||
if (podsProjectContent.contains('MACOSX_DEPLOYMENT_TARGET = 10.9')) {
|
||||
throw TaskResult.failure('Transitive dependency build setting MACOSX_DEPLOYMENT_TARGET=10.9 not removed');
|
||||
}
|
||||
}
|
||||
|
||||
if (localEngine != null) {
|
||||
final RegExp localEngineSearchPath = RegExp('FRAMEWORK_SEARCH_PATHS\\s*=[^;]*${localEngine.path}');
|
||||
if (!localEngineSearchPath.hasMatch(podsProjectContent)) {
|
||||
throw TaskResult.failure('FRAMEWORK_SEARCH_PATHS does not contain the --local-engine path');
|
||||
final String podsProjectContent = podsProject.readAsStringSync();
|
||||
if (target == 'ios') {
|
||||
// Plugins with versions lower than the app version should not have IPHONEOS_DEPLOYMENT_TARGET set.
|
||||
// The plugintest plugin target should not have IPHONEOS_DEPLOYMENT_TARGET set since it has been lowered
|
||||
// in _reduceDarwinPluginMinimumVersion to 10, which is below the target version of 11.
|
||||
if (podsProjectContent.contains('IPHONEOS_DEPLOYMENT_TARGET = 10')) {
|
||||
throw TaskResult.failure('Plugin build setting IPHONEOS_DEPLOYMENT_TARGET not removed');
|
||||
}
|
||||
// Transitive dependency AppAuth targeting too-low 8.0 was not fixed.
|
||||
if (podsProjectContent.contains('IPHONEOS_DEPLOYMENT_TARGET = 8')) {
|
||||
throw TaskResult.failure('Transitive dependency build setting IPHONEOS_DEPLOYMENT_TARGET=8 not removed');
|
||||
}
|
||||
if (!podsProjectContent.contains(r'"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "$(inherited) i386";')) {
|
||||
throw TaskResult.failure(r'EXCLUDED_ARCHS is not "$(inherited) i386"');
|
||||
}
|
||||
} else if (target == 'macos') {
|
||||
// Same for macOS deployment target, but 10.8.
|
||||
// The plugintest target should not have MACOSX_DEPLOYMENT_TARGET set.
|
||||
if (podsProjectContent.contains('MACOSX_DEPLOYMENT_TARGET = 10.8')) {
|
||||
throw TaskResult.failure('Plugin build setting MACOSX_DEPLOYMENT_TARGET not removed');
|
||||
}
|
||||
// Transitive dependency AppAuth targeting too-low 10.9 was not fixed.
|
||||
if (podsProjectContent.contains('MACOSX_DEPLOYMENT_TARGET = 10.9')) {
|
||||
throw TaskResult.failure('Transitive dependency build setting MACOSX_DEPLOYMENT_TARGET=10.9 not removed');
|
||||
}
|
||||
}
|
||||
|
||||
if (localEngine != null) {
|
||||
final RegExp localEngineSearchPath = RegExp('FRAMEWORK_SEARCH_PATHS\\s*=[^;]*${localEngine.path}');
|
||||
if (!localEngineSearchPath.hasMatch(podsProjectContent)) {
|
||||
throw TaskResult.failure('FRAMEWORK_SEARCH_PATHS does not contain the --local-engine path');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +186,7 @@ const Feature swiftPackageManager = Feature(
|
||||
environmentOverride: 'SWIFT_PACKAGE_MANAGER',
|
||||
master: FeatureChannelSetting(
|
||||
available: true,
|
||||
enabledByDefault: true,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -693,7 +693,7 @@ void main() {
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('kotlin/swift plugin project', () async {
|
||||
testUsingContext('kotlin/swift plugin project without Swift Package Manager', () async {
|
||||
return _createProject(
|
||||
projectDir,
|
||||
<String>['--no-pub', '--template=plugin', '-a', 'kotlin', '--ios-language', 'swift', '--platforms', 'ios,android'],
|
||||
@ -718,6 +718,9 @@ void main() {
|
||||
'ios/Classes/FlutterProjectPlugin.m',
|
||||
],
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
// Test flags disable Swift Package Manager.
|
||||
FeatureFlags: () => TestFeatureFlags(),
|
||||
});
|
||||
|
||||
testUsingContext('swift plugin project with Swift Package Manager', () async {
|
||||
@ -1944,7 +1947,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testUsingContext('can re-gen plugin ios/ and example/ folders, reusing custom org', () async {
|
||||
testUsingContext('can re-gen plugin ios/ and example/ folders, reusing custom org, without Swift Package Manager', () async {
|
||||
await _createProject(
|
||||
projectDir,
|
||||
<String>[
|
||||
@ -1969,6 +1972,7 @@ void main() {
|
||||
unexpectedPaths: <String>[
|
||||
'example/android/app/src/main/java/com/example/flutter_project_example/MainActivity.java',
|
||||
'android/src/main/java/com/example/flutter_project/FlutterProjectPlugin.java',
|
||||
'ios/flutter_project/Sources/flutter_project/include/flutter_project/FlutterProjectPlugin.h',
|
||||
],
|
||||
);
|
||||
final FlutterProject project = FlutterProject.fromDirectory(projectDir);
|
||||
@ -1976,6 +1980,48 @@ void main() {
|
||||
await project.example.ios.productBundleIdentifier(BuildInfo.debug),
|
||||
'com.bar.foo.flutterProjectExample',
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
// Test flags disable Swift Package Manager.
|
||||
FeatureFlags: () => TestFeatureFlags(),
|
||||
});
|
||||
|
||||
testUsingContext('can re-gen plugin ios/ and example/ folders, reusing custom org, with Swift Package Manager', () async {
|
||||
await _createProject(
|
||||
projectDir,
|
||||
<String>[
|
||||
'--no-pub',
|
||||
'--template=plugin',
|
||||
'--org', 'com.bar.foo',
|
||||
'-i', 'objc',
|
||||
'-a', 'java',
|
||||
'--platforms', 'ios,android',
|
||||
],
|
||||
<String>[],
|
||||
);
|
||||
projectDir.childDirectory('example').deleteSync(recursive: true);
|
||||
projectDir.childDirectory('ios').deleteSync(recursive: true);
|
||||
await _createProject(
|
||||
projectDir,
|
||||
<String>['--no-pub', '--template=plugin', '-i', 'objc', '-a', 'java', '--platforms', 'ios,android'],
|
||||
<String>[
|
||||
'example/android/app/src/main/java/com/bar/foo/flutter_project_example/MainActivity.java',
|
||||
'ios/flutter_project/Sources/flutter_project/include/flutter_project/FlutterProjectPlugin.h',
|
||||
],
|
||||
unexpectedPaths: <String>[
|
||||
'example/android/app/src/main/java/com/example/flutter_project_example/MainActivity.java',
|
||||
'android/src/main/java/com/example/flutter_project/FlutterProjectPlugin.java',
|
||||
'ios/Classes/FlutterProjectPlugin.h',
|
||||
],
|
||||
);
|
||||
final FlutterProject project = FlutterProject.fromDirectory(projectDir);
|
||||
expect(
|
||||
await project.example.ios.productBundleIdentifier(BuildInfo.debug),
|
||||
'com.bar.foo.flutterProjectExample',
|
||||
);
|
||||
}, overrides: <Type, Generator>{
|
||||
FeatureFlags: () => TestFeatureFlags(
|
||||
isSwiftPackageManagerEnabled: true,
|
||||
),
|
||||
});
|
||||
|
||||
testUsingContext('fails to re-gen without specified org when org is ambiguous', () async {
|
||||
|
@ -404,7 +404,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('${swiftPackageManager.name} availability and default enabled', () {
|
||||
expect(swiftPackageManager.master.enabledByDefault, false);
|
||||
expect(swiftPackageManager.master.enabledByDefault, true);
|
||||
expect(swiftPackageManager.master.available, true);
|
||||
expect(swiftPackageManager.beta.enabledByDefault, false);
|
||||
expect(swiftPackageManager.beta.available, false);
|
||||
|
@ -87,6 +87,7 @@ void main() {
|
||||
late File outputFlutterFrameworkBinary;
|
||||
late Directory outputAppFramework;
|
||||
late File outputAppFrameworkBinary;
|
||||
late File outputRunnerBinary;
|
||||
late File outputPluginFrameworkBinary;
|
||||
late Directory buildPath;
|
||||
late Directory buildAppFrameworkDsym;
|
||||
@ -122,6 +123,10 @@ void main() {
|
||||
outputAppFramework = frameworkDirectory.childDirectory('App.framework');
|
||||
outputAppFrameworkBinary = outputAppFramework.childFile('App');
|
||||
|
||||
outputRunnerBinary = outputApp.childFile('Runner');
|
||||
|
||||
// Exists only if the plugin is built as a dynamic framework.
|
||||
// This is is the default for CocoaPods but not Swift Package Manager.
|
||||
outputPluginFrameworkBinary = frameworkDirectory.childDirectory('hello.framework').childFile('hello');
|
||||
|
||||
buildPath = fileSystem.directory(fileSystem.path.join(
|
||||
@ -141,7 +146,18 @@ void main() {
|
||||
printOnFailure(buildResult.stderr.toString());
|
||||
expect(buildResult.exitCode, 0);
|
||||
|
||||
expect(outputPluginFrameworkBinary, exists);
|
||||
// Plugins are built either as a static library (SwiftPM's default)
|
||||
// or as a dynamic library (CocoaPods's default).
|
||||
// If built as a dynamic library, the plugin will have a .framework.
|
||||
// If built as static library, the plugin's symbols will be in the
|
||||
// Runner binary.
|
||||
final bool helloDynamic = outputPluginFrameworkBinary.existsSync();
|
||||
final bool helloStatic = AppleTestUtils
|
||||
.getExportedSymbols(outputRunnerBinary.path)
|
||||
.any((String symbol) => symbol.contains('HelloPlugin') && symbol.contains('handle'));
|
||||
|
||||
// Plugin is a dynamic xor static framework.
|
||||
expect(helloDynamic != helloStatic, isTrue);
|
||||
|
||||
expect(outputAppFrameworkBinary, exists);
|
||||
expect(outputAppFramework.childFile('Info.plist'), exists);
|
||||
@ -300,6 +316,19 @@ void main() {
|
||||
);
|
||||
expect(buildSimulator.exitCode, 0);
|
||||
|
||||
// Plugins are built either as a static library (SwiftPM's default)
|
||||
// or as a dynamic library (CocoaPods's default).
|
||||
// If built as a dynamic library, the plugin will have a .framework.
|
||||
// If built as static library, the plugin's symbols will be in the
|
||||
// Runner binary.
|
||||
final File runnerBinary = fileSystem.file(fileSystem.path.join(
|
||||
projectRoot,
|
||||
'build',
|
||||
'ios',
|
||||
'iphonesimulator',
|
||||
'Runner.app',
|
||||
'Runner',
|
||||
));
|
||||
final File pluginFrameworkBinary = fileSystem.file(fileSystem.path.join(
|
||||
projectRoot,
|
||||
'build',
|
||||
@ -310,12 +339,21 @@ void main() {
|
||||
'hello.framework',
|
||||
'hello',
|
||||
));
|
||||
expect(pluginFrameworkBinary, exists);
|
||||
final ProcessResult archs = processManager.runSync(
|
||||
<String>['file', pluginFrameworkBinary.path],
|
||||
);
|
||||
expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library x86_64'));
|
||||
expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library arm64'));
|
||||
final bool helloDynamic = pluginFrameworkBinary.existsSync();
|
||||
final bool helloStatic = AppleTestUtils
|
||||
.getExportedSymbols(runnerBinary.path)
|
||||
.any((String symbol) => symbol.contains('HelloPlugin') && symbol.contains('handle'));
|
||||
|
||||
// Plugin is a dynamic xor static framework.
|
||||
expect(helloDynamic != helloStatic, isTrue);
|
||||
|
||||
if (helloDynamic) {
|
||||
final ProcessResult archs = processManager.runSync(
|
||||
<String>['file', pluginFrameworkBinary.path],
|
||||
);
|
||||
expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library x86_64'));
|
||||
expect(archs.stdout, contains('Mach-O 64-bit dynamically linked shared library arm64'));
|
||||
}
|
||||
});
|
||||
|
||||
testWithoutContext('build for simulator with all available architectures', () {
|
||||
|
Loading…
Reference in New Issue
Block a user