Embed Flutter and App frameworks for add-to-app on iOS (#102538)
This commit is contained in:
parent
d75d54c904
commit
36be63ba19
@ -59,7 +59,8 @@ Future<void> main() async {
|
||||
);
|
||||
});
|
||||
|
||||
checkDirectoryExists(path.join(projectDir.path, '.ios', 'Flutter', 'engine', 'Flutter.xcframework'));
|
||||
// Check the tool is no longer copying to the legacy xcframework location.
|
||||
checkDirectoryNotExists(path.join(projectDir.path, '.ios', 'Flutter', 'engine', 'Flutter.xcframework'));
|
||||
|
||||
final Directory ephemeralIOSHostApp = Directory(path.join(
|
||||
projectDir.path,
|
||||
@ -79,32 +80,6 @@ Future<void> main() async {
|
||||
);
|
||||
}
|
||||
|
||||
section('Build ephemeral host app when SDK is on external disk');
|
||||
|
||||
// Pretend the SDK was on an external drive with stray "._" files in the xcframework
|
||||
// and build again.
|
||||
Directory(path.join(
|
||||
projectDir.path,
|
||||
'.ios',
|
||||
'Flutter',
|
||||
'engine',
|
||||
'Flutter.xcframework',
|
||||
'._ios-arm64_x86_64-simulator',
|
||||
)).createSync(recursive: true);
|
||||
|
||||
await inDirectory(projectDir, () async {
|
||||
await flutter(
|
||||
'build',
|
||||
options: <String>['ios', '--no-codesign', '--simulator', '--debug'],
|
||||
);
|
||||
});
|
||||
|
||||
section('Clean build');
|
||||
|
||||
await inDirectory(projectDir, () async {
|
||||
await flutter('clean');
|
||||
});
|
||||
|
||||
section('Build ephemeral host app in profile mode without CocoaPods');
|
||||
|
||||
await inDirectory(projectDir, () async {
|
||||
@ -114,8 +89,6 @@ Future<void> main() async {
|
||||
);
|
||||
});
|
||||
|
||||
checkDirectoryExists(path.join(projectDir.path, '.ios', 'Flutter', 'engine', 'Flutter.xcframework'));
|
||||
|
||||
if (!exists(ephemeralIOSHostApp)) {
|
||||
return TaskResult.failure('Failed to build ephemeral host .app');
|
||||
}
|
||||
@ -211,7 +184,6 @@ dependencies:
|
||||
options: <String>['ios', '--no-codesign', '-v'],
|
||||
);
|
||||
});
|
||||
checkDirectoryExists(path.join(projectDir.path, '.ios', 'Flutter', 'engine', 'Flutter.xcframework'));
|
||||
|
||||
final bool ephemeralHostAppWithCocoaPodsBuilt = exists(ephemeralIOSHostApp);
|
||||
|
||||
@ -265,8 +237,6 @@ dependencies:
|
||||
final File objectiveCAnalyticsOutputFile = File(path.join(tempDir.path, 'analytics-objc.log'));
|
||||
final Directory objectiveCBuildDirectory = Directory(path.join(tempDir.path, 'build-objc'));
|
||||
|
||||
final File dummyAppFramework = File(path.join(projectDir.path, '.ios', 'Flutter', 'App.framework', 'App'));
|
||||
checkFileNotExists(dummyAppFramework.path);
|
||||
await inDirectory(objectiveCHostApp, () async {
|
||||
section('Validate iOS Objective-C host app Podfile');
|
||||
|
||||
@ -305,7 +275,7 @@ end
|
||||
|
||||
final File hostPodfileLockFile = File(path.join(objectiveCHostApp.path, 'Podfile.lock'));
|
||||
final String hostPodfileLockOutput = hostPodfileLockFile.readAsStringSync();
|
||||
if (!hostPodfileLockOutput.contains(':path: "../hello/.ios/Flutter/engine"')
|
||||
if (!hostPodfileLockOutput.contains(':path: "../hello/.ios/Flutter"')
|
||||
|| !hostPodfileLockOutput.contains(':path: "../hello/.ios/Flutter/FlutterPluginRegistrant"')
|
||||
|| !hostPodfileLockOutput.contains(':path: "../hello/.ios/.symlinks/plugins/url_launcher_ios/ios"')
|
||||
|| !hostPodfileLockOutput.contains(':path: "../hello/.ios/.symlinks/plugins/google_sign_in/ios"')
|
||||
@ -315,13 +285,9 @@ end
|
||||
throw TaskResult.failure('Building host app Podfile.lock does not contain expected pods');
|
||||
}
|
||||
|
||||
// Just running "pod install" should create a fake App.framework so CocoaPods recognizes
|
||||
// it as a framework that needs to be embedded, before Flutter actually creates it.
|
||||
checkFileExists(dummyAppFramework.path);
|
||||
final String? version = await minPhoneOSVersion(dummyAppFramework.path);
|
||||
if (version != '11.0') {
|
||||
throw TaskResult.failure('Minimum version set to $version, expected 11.0');
|
||||
}
|
||||
// Check the tool is no longer copying to the legacy App.framework location.
|
||||
final File dummyAppFramework = File(path.join(projectDir.path, '.ios', 'Flutter', 'App.framework', 'App'));
|
||||
checkFileNotExists(dummyAppFramework.path);
|
||||
|
||||
section('Build iOS Objective-C host app');
|
||||
|
||||
|
@ -161,7 +161,8 @@ def flutter_install_ios_engine_pod(ios_application_path = nil)
|
||||
ios_application_path ||= File.dirname(defined_in_file.realpath) if self.respond_to?(:defined_in_file)
|
||||
raise 'Could not find iOS application path' unless ios_application_path
|
||||
|
||||
copied_podspec_path = File.expand_path('Flutter.podspec', File.join(ios_application_path, 'Flutter'))
|
||||
podspec_directory = File.join(ios_application_path, 'Flutter')
|
||||
copied_podspec_path = File.expand_path('Flutter.podspec', podspec_directory)
|
||||
|
||||
# Generate a fake podspec to represent the Flutter framework.
|
||||
# This is only necessary because plugin podspecs contain `s.dependency 'Flutter'`, and if this Podfile
|
||||
@ -190,7 +191,7 @@ def flutter_install_ios_engine_pod(ios_application_path = nil)
|
||||
}
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
pod 'Flutter', :path => 'Flutter'
|
||||
pod 'Flutter', :path => flutter_relative_path_from_podfile(podspec_directory)
|
||||
end
|
||||
|
||||
# Same as flutter_install_ios_engine_pod for macOS.
|
||||
@ -260,7 +261,9 @@ def flutter_install_plugin_pods(application_path = nil, relative_symlink_dir, pl
|
||||
File.symlink(plugin_path, symlink)
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
pod plugin_name, :path => File.join(relative_symlink_dir, 'plugins', plugin_name, platform)
|
||||
relative = flutter_relative_path_from_podfile(symlink)
|
||||
|
||||
pod plugin_name, :path => File.join(relative, platform)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -279,3 +282,12 @@ def flutter_parse_plugins_file(file, platform)
|
||||
return [] unless dependencies_hash['plugins'].has_key?('ios')
|
||||
dependencies_hash['plugins'][platform] || []
|
||||
end
|
||||
|
||||
def flutter_relative_path_from_podfile(path)
|
||||
# defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
|
||||
project_directory_pathname = defined_in_file.dirname
|
||||
|
||||
pathname = Pathname.new File.expand_path(path)
|
||||
relative = pathname.relative_path_from project_directory_pathname
|
||||
relative.to_s
|
||||
end
|
||||
|
@ -321,28 +321,7 @@ class Context {
|
||||
targetPath = environment['FLUTTER_TARGET']!;
|
||||
}
|
||||
|
||||
String derivedDir = '$sourceRoot/Flutter}';
|
||||
if (existsDir('$projectPath/.ios')) {
|
||||
derivedDir = '$projectPath/.ios/Flutter';
|
||||
}
|
||||
|
||||
// Use FLUTTER_BUILD_MODE if it's set, otherwise use the Xcode build configuration name
|
||||
// This means that if someone wants to use an Xcode build config other than Debug/Profile/Release,
|
||||
// they _must_ set FLUTTER_BUILD_MODE so we know what type of artifact to build.
|
||||
|
||||
final String buildMode = parseFlutterBuildMode();
|
||||
String artifactVariant = 'unknown';
|
||||
switch (buildMode) {
|
||||
case 'release':
|
||||
artifactVariant = 'ios-release';
|
||||
break;
|
||||
case 'profile':
|
||||
artifactVariant = 'ios-profile';
|
||||
break;
|
||||
case 'debug':
|
||||
artifactVariant = 'ios';
|
||||
break;
|
||||
}
|
||||
|
||||
// Warn the user if not archiving (ACTION=install) in release mode.
|
||||
final String? action = environment['ACTION'];
|
||||
@ -353,47 +332,12 @@ class Context {
|
||||
'--release", then re-run Archive from Xcode.',
|
||||
);
|
||||
}
|
||||
final String frameworkPath = '${environmentEnsure('FLUTTER_ROOT')}/bin/cache/artifacts/engine/$artifactVariant';
|
||||
|
||||
String flutterFramework = '$frameworkPath/Flutter.xcframework';
|
||||
|
||||
final String? localEngine = environment['LOCAL_ENGINE'];
|
||||
if (localEngine != null) {
|
||||
if (!localEngine.toLowerCase().contains(buildMode)) {
|
||||
echoError('========================================================================');
|
||||
echoError("ERROR: Requested build with Flutter local engine at '$localEngine'");
|
||||
echoError("This engine is not compatible with FLUTTER_BUILD_MODE: '$buildMode'.");
|
||||
echoError('You can fix this by updating the LOCAL_ENGINE environment variable, or');
|
||||
echoError('by running:');
|
||||
echoError(' flutter build ios --local-engine=ios_$buildMode');
|
||||
echoError('or');
|
||||
echoError(' flutter build ios --local-engine=ios_${buildMode}_unopt');
|
||||
echoError('========================================================================');
|
||||
exitApp(-1);
|
||||
}
|
||||
flutterFramework = '${environmentEnsure('FLUTTER_ENGINE')}/out/$localEngine/Flutter.xcframework';
|
||||
}
|
||||
String bitcodeFlag = '';
|
||||
if (environment['ENABLE_BITCODE'] == 'YES' && environment['ACTION'] == 'install') {
|
||||
bitcodeFlag = 'true';
|
||||
}
|
||||
|
||||
// TODO(jmagman): use assemble copied engine in add-to-app.
|
||||
if (existsDir('$projectPath/.ios')) {
|
||||
runSync(
|
||||
'rsync',
|
||||
<String>[
|
||||
'-av',
|
||||
'--delete',
|
||||
'--filter',
|
||||
'- .DS_Store',
|
||||
flutterFramework,
|
||||
'$derivedDir/engine',
|
||||
],
|
||||
verbose: verbose,
|
||||
);
|
||||
}
|
||||
|
||||
final List<String> flutterArgs = <String>[];
|
||||
|
||||
if (verbose) {
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'artifacts.dart';
|
||||
import 'base/error_handling_io.dart';
|
||||
import 'base/file_system.dart';
|
||||
import 'base/utils.dart';
|
||||
@ -399,29 +398,6 @@ class IosProject extends XcodeBasedProject {
|
||||
ephemeralModuleDirectory,
|
||||
);
|
||||
}
|
||||
// Use release mode so host project can link on bitcode variant.
|
||||
_copyEngineArtifactToProject(BuildMode.release, EnvironmentType.physical);
|
||||
}
|
||||
}
|
||||
|
||||
void _copyEngineArtifactToProject(BuildMode mode, EnvironmentType environmentType) {
|
||||
// Copy framework from engine cache. The actual build mode
|
||||
// doesn't actually matter as it will be overwritten by xcode_backend.sh.
|
||||
// However, cocoapods will run before that script and requires something
|
||||
// to be in this location.
|
||||
final Directory framework = globals.fs.directory(
|
||||
globals.artifacts?.getArtifactPath(
|
||||
Artifact.flutterXcframework,
|
||||
platform: TargetPlatform.ios,
|
||||
mode: mode,
|
||||
environmentType: environmentType,
|
||||
)
|
||||
);
|
||||
if (framework.existsSync()) {
|
||||
copyDirectory(
|
||||
framework,
|
||||
engineCopyDirectory.childDirectory('Flutter.xcframework'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,12 +443,6 @@ class IosProject extends XcodeBasedProject {
|
||||
return registryDirectory.childFile('GeneratedPluginRegistrant.m');
|
||||
}
|
||||
|
||||
Directory get engineCopyDirectory {
|
||||
return isModule
|
||||
? ephemeralModuleDirectory.childDirectory('Flutter').childDirectory('engine')
|
||||
: hostAppRoot.childDirectory('Flutter');
|
||||
}
|
||||
|
||||
Future<void> _overwriteFromTemplate(String path, Directory target) async {
|
||||
final Template template = await Template.fromName(
|
||||
path,
|
||||
|
@ -1,20 +0,0 @@
|
||||
#
|
||||
# NOTE: This podspec is NOT to be published. It is only used as a local source!
|
||||
#
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'Flutter'
|
||||
s.version = '1.0.0'
|
||||
s.summary = 'A UI toolkit for beautiful and fast apps.'
|
||||
s.description = <<-DESC
|
||||
Flutter is Google's UI toolkit for building beautiful, fast apps for mobile, web, desktop, and embedded devices from a single codebase.
|
||||
This pod vends the iOS Flutter engine framework. It is compatible with application frameworks created with this version of the engine and tools.
|
||||
DESC
|
||||
s.homepage = 'https://flutter.dev'
|
||||
s.license = 'BSD'
|
||||
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
|
||||
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
|
||||
s.documentation_url = 'https://flutter.dev/docs'
|
||||
s.ios.deployment_target = '11.0'
|
||||
s.vendored_frameworks = 'Flutter.xcframework'
|
||||
end
|
@ -31,7 +31,7 @@ POSTINSTALL
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_application_path ||= File.join('..', '..')
|
||||
install_flutter_engine_pod
|
||||
install_flutter_engine_pod(flutter_application_path)
|
||||
install_flutter_plugin_pods(flutter_application_path)
|
||||
install_flutter_application_pod(flutter_application_path)
|
||||
end
|
||||
@ -42,30 +42,12 @@ end
|
||||
# target 'MyApp' do
|
||||
# install_flutter_engine_pod
|
||||
# end
|
||||
def install_flutter_engine_pod
|
||||
current_directory = File.expand_path('..', __FILE__)
|
||||
engine_dir = File.expand_path('engine', current_directory)
|
||||
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.
|
||||
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
|
||||
release_framework_dir = File.join(flutter_root, 'bin', 'cache', 'artifacts', 'engine', 'ios-release')
|
||||
unless Dir.exist?(release_framework_dir)
|
||||
# iOS artifacts have not been downloaded.
|
||||
raise "#{release_framework_dir} must exist. Make sure \"flutter precache --ios\" has been run at least once"
|
||||
end
|
||||
FileUtils.cp_r(File.join(release_framework_dir, framework_name), engine_dir)
|
||||
end
|
||||
def install_flutter_engine_pod(flutter_application_path = nil)
|
||||
flutter_application_path ||= File.join('..', '..')
|
||||
ios_application_path = File.join(flutter_application_path, '.ios')
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
# Process will be run from project directory.
|
||||
engine_pathname = Pathname.new engine_dir
|
||||
# defined_in_file is a Pathname to the Podfile set by CocoaPods.
|
||||
project_directory_pathname = defined_in_file.dirname
|
||||
relative = engine_pathname.relative_path_from project_directory_pathname
|
||||
|
||||
pod 'Flutter', :path => relative.to_s, :inhibit_warnings => true
|
||||
# flutter_install_ios_engine_pod is in Flutter root podhelper.rb
|
||||
flutter_install_ios_engine_pod(ios_application_path)
|
||||
end
|
||||
|
||||
# Install Flutter plugin pods.
|
||||
@ -79,33 +61,13 @@ end
|
||||
# MyApp/my_flutter/.ios/Flutter/../..
|
||||
def install_flutter_plugin_pods(flutter_application_path)
|
||||
flutter_application_path ||= File.join('..', '..')
|
||||
ios_application_path = File.join(flutter_application_path, '.ios')
|
||||
# flutter_install_plugin_pods is in Flutter root podhelper.rb
|
||||
flutter_install_plugin_pods(ios_application_path, '.symlinks', 'ios')
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
# Process will be run from project directory.
|
||||
ios_project_directory_pathname = Pathname.new File.expand_path(File.join('..', '..'), __FILE__)
|
||||
# defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
|
||||
project_directory_pathname = defined_in_file.dirname
|
||||
relative = ios_project_directory_pathname.relative_path_from project_directory_pathname
|
||||
relative = flutter_relative_path_from_podfile(ios_application_path)
|
||||
pod 'FlutterPluginRegistrant', :path => File.join(relative, 'Flutter', 'FlutterPluginRegistrant'), :inhibit_warnings => true
|
||||
|
||||
symlinks_dir = File.join(relative, '.symlinks', 'plugins')
|
||||
FileUtils.mkdir_p(symlinks_dir)
|
||||
|
||||
plugins_file = File.expand_path('.flutter-plugins-dependencies', flutter_application_path)
|
||||
|
||||
# flutter_parse_plugins_file is in Flutter root podhelper.rb
|
||||
plugin_pods = flutter_parse_plugins_file(plugins_file, 'ios')
|
||||
plugin_pods.each do |plugin_hash|
|
||||
plugin_name = plugin_hash['name']
|
||||
plugin_path = plugin_hash['path']
|
||||
has_native_build = plugin_hash.fetch('native_build', true)
|
||||
if (plugin_name && plugin_path && has_native_build)
|
||||
symlink = File.join(symlinks_dir, plugin_name)
|
||||
FileUtils.rm_f(symlink)
|
||||
File.symlink(plugin_path, symlink)
|
||||
pod plugin_name, :path => File.join(symlink, 'ios'), :inhibit_warnings => true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Install Flutter application pod.
|
||||
@ -118,30 +80,24 @@ end
|
||||
# Optional, defaults to two levels up from the directory of this script.
|
||||
# MyApp/my_flutter/.ios/Flutter/../..
|
||||
def install_flutter_application_pod(flutter_application_path)
|
||||
current_directory_pathname = Pathname.new File.expand_path('..', __FILE__)
|
||||
app_framework_dir = File.expand_path('App.framework', current_directory_pathname.to_path)
|
||||
app_framework_dylib = File.join(app_framework_dir, 'App')
|
||||
if !File.exist?(app_framework_dylib)
|
||||
# Fake an App.framework to have something to link against if the xcode backend script has not run yet.
|
||||
# CocoaPods will not embed the framework on pod install (before any build phases can run) if the dylib does not exist.
|
||||
# Create a dummy dylib.
|
||||
FileUtils.mkdir_p(app_framework_dir)
|
||||
sdk_path = `xcrun --sdk iphoneos --show-sdk-path`.strip
|
||||
`echo "static const int Moo = 88;" | xcrun clang -x c -arch arm64 -dynamiclib -miphoneos-version-min=11.0 -isysroot "#{sdk_path}" -o "#{app_framework_dylib}" -`
|
||||
end
|
||||
flutter_application_path ||= File.join('..', '..')
|
||||
|
||||
# Keep pod and script phase paths relative so they can be checked into source control.
|
||||
# Process will be run from project directory.
|
||||
export_script_directory = File.join(flutter_application_path, '.ios', 'Flutter')
|
||||
|
||||
# defined_in_file is set by CocoaPods and is a Pathname to the Podfile.
|
||||
project_directory_pathname = defined_in_file.dirname
|
||||
relative = current_directory_pathname.relative_path_from project_directory_pathname
|
||||
pod '{{projectName}}', :path => relative.to_s, :inhibit_warnings => true
|
||||
# Keep script phase paths relative so they can be checked into source control.
|
||||
relative = flutter_relative_path_from_podfile(export_script_directory)
|
||||
|
||||
flutter_export_environment_path = File.join('${SRCROOT}', relative, 'flutter_export_environment.sh');
|
||||
|
||||
# Compile App.framework and move it and Flutter.framework to "BUILT_PRODUCTS_DIR"
|
||||
script_phase :name => 'Run Flutter Build {{projectName}} Script',
|
||||
:script => "set -e\nset -u\nsource \"#{flutter_export_environment_path}\"\nexport VERBOSE_SCRIPT_LOGGING=1 && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh build",
|
||||
:execution_position => :before_compile
|
||||
|
||||
# Embed App.framework AND Flutter.framework.
|
||||
script_phase :name => 'Embed Flutter Build {{projectName}} Script',
|
||||
:script => "set -e\nset -u\nsource \"#{flutter_export_environment_path}\"\nexport VERBOSE_SCRIPT_LOGGING=1 && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh embed_and_thin",
|
||||
:execution_position => :after_compile
|
||||
end
|
||||
|
||||
def flutter_root
|
||||
|
@ -1,13 +0,0 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = '{{projectName}}'
|
||||
s.version = '0.0.1'
|
||||
s.summary = 'Flutter module'
|
||||
s.description = 'Flutter module - {{projectName}}'
|
||||
s.homepage = 'https://flutter.dev'
|
||||
s.license = { :type => 'BSD' }
|
||||
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
|
||||
s.source = { :path => '.' }
|
||||
s.ios.deployment_target = '11.0'
|
||||
s.vendored_frameworks = 'App.framework'
|
||||
s.dependency 'Flutter'
|
||||
end
|
@ -186,7 +186,6 @@
|
||||
"templates/module/ios/host_app_ephemeral/Config.tmpl/Debug.xcconfig",
|
||||
"templates/module/ios/host_app_ephemeral/Config.tmpl/Flutter.xcconfig",
|
||||
"templates/module/ios/host_app_ephemeral/Config.tmpl/Release.xcconfig",
|
||||
"templates/module/ios/host_app_ephemeral/Flutter/engine/Flutter.podspec.tmpl",
|
||||
"templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.h",
|
||||
"templates/module/ios/host_app_ephemeral/Runner.tmpl/AppDelegate.m",
|
||||
"templates/module/ios/host_app_ephemeral/Runner.tmpl/Assets.xcassets/AppIcon.appiconset/Contents.json",
|
||||
@ -228,7 +227,6 @@
|
||||
"templates/module/ios/host_app_ephemeral_cocoapods/Runner.tmpl/AppDelegate.m",
|
||||
"templates/module/ios/library/Flutter.tmpl/AppFrameworkInfo.plist",
|
||||
"templates/module/ios/library/Flutter.tmpl/podhelper.rb.tmpl",
|
||||
"templates/module/ios/library/Flutter.tmpl/projectName.podspec.tmpl",
|
||||
"templates/module/ios/library/Flutter.tmpl/README.md",
|
||||
"templates/module/README.md",
|
||||
|
||||
|
@ -222,8 +222,6 @@ void main() {
|
||||
'.android/app/',
|
||||
'.gitignore',
|
||||
'.ios/Flutter',
|
||||
'.ios/Flutter/flutter_project.podspec',
|
||||
'.ios/Flutter/engine/Flutter.podspec',
|
||||
'.metadata',
|
||||
'analysis_options.yaml',
|
||||
'lib/main.dart',
|
||||
@ -1163,13 +1161,6 @@ void main() {
|
||||
// Do not override host app build settings.
|
||||
expect(buildPhaseScript, isNot(contains('SYMROOT')));
|
||||
|
||||
// Generated podspec
|
||||
final String podspecPath = globals.fs.path.join('.ios', 'Flutter', 'flutter_project.podspec');
|
||||
expectExists(podspecPath);
|
||||
final File podspecFile = globals.fs.file(globals.fs.path.join(projectDir.path, podspecPath));
|
||||
final String podspec = podspecFile.readAsStringSync();
|
||||
expect(podspec, contains('Flutter module - flutter_project'));
|
||||
|
||||
// App identification
|
||||
final String xcodeProjectPath = globals.fs.path.join('.ios', 'Runner.xcodeproj', 'project.pbxproj');
|
||||
expectExists(xcodeProjectPath);
|
||||
|
@ -318,7 +318,6 @@ void main() {
|
||||
final Directory flutter = project.ios.hostAppRoot.childDirectory('Flutter');
|
||||
expectExists(flutter.childFile('podhelper.rb'));
|
||||
expectExists(flutter.childFile('flutter_export_environment.sh'));
|
||||
expectExists(flutter.childFile('${project.manifest.appName}.podspec'));
|
||||
expectExists(flutter.childFile('Generated.xcconfig'));
|
||||
final Directory pluginRegistrantClasses = flutter
|
||||
.childDirectory('FlutterPluginRegistrant')
|
||||
|
@ -26,23 +26,6 @@ const Map<String, String> unknownFlutterBuildMode = <String, String>{
|
||||
'CONFIGURATION': 'Debug',
|
||||
};
|
||||
|
||||
// Can't use a debug engine build with a release build.
|
||||
const Map<String, String> localEngineDebugBuildModeRelease = <String, String>{
|
||||
'SOURCE_ROOT': '../examples/hello_world',
|
||||
'FLUTTER_ROOT': '../..',
|
||||
'LOCAL_ENGINE': '/engine/src/out/ios_debug_unopt',
|
||||
'CONFIGURATION': 'Release',
|
||||
};
|
||||
|
||||
// Can't use a debug build with a profile engine.
|
||||
const Map<String, String> localEngineProfileBuildModeRelease = <String, String>{
|
||||
'SOURCE_ROOT': '../examples/hello_world',
|
||||
'FLUTTER_ROOT': '../..',
|
||||
'LOCAL_ENGINE': '/engine/src/out/ios_profile',
|
||||
'CONFIGURATION': 'Debug',
|
||||
'FLUTTER_BUILD_MODE': 'Debug',
|
||||
};
|
||||
|
||||
void main() {
|
||||
Future<void> expectXcodeBackendFails(Map<String, String> environment) async {
|
||||
final ProcessResult result = await Process.run(
|
||||
@ -70,8 +53,6 @@ void main() {
|
||||
test('Xcode backend fails for on unsupported configuration combinations', () async {
|
||||
await expectXcodeBackendFails(unknownConfiguration);
|
||||
await expectXcodeBackendFails(unknownFlutterBuildMode);
|
||||
await expectXcodeBackendFails(localEngineDebugBuildModeRelease);
|
||||
await expectXcodeBackendFails(localEngineProfileBuildModeRelease);
|
||||
}, skip: !io.Platform.isMacOS); // [intended] requires macos toolchain.
|
||||
|
||||
test('Xcode backend warns archiving a non-release build.', () async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user