diff --git a/.gitignore b/.gitignore index f92944ad0c5ff3..d46d282df64d98 100644 --- a/.gitignore +++ b/.gitignore @@ -100,6 +100,7 @@ unlinked_spec.ds **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.xcframework **/ios/Flutter/Flutter.podspec **/ios/Flutter/Generated.xcconfig **/ios/Flutter/app.flx diff --git a/shell/platform/darwin/ios/BUILD.gn b/shell/platform/darwin/ios/BUILD.gn index e131ca60433869..897fe374b55787 100644 --- a/shell/platform/darwin/ios/BUILD.gn +++ b/shell/platform/darwin/ios/BUILD.gn @@ -324,7 +324,8 @@ shared_library("copy_and_verify_framework_module") { ] } -group("flutter_framework") { +group("universal_flutter_framework") { + visibility = [ ":*" ] deps = [ ":copy_and_verify_framework_module", ":copy_dylib", @@ -335,3 +336,18 @@ group("flutter_framework") { ":copy_license", ] } + +action("flutter_framework") { + script = "//flutter/sky/tools/create_xcframework.py" + outputs = [ "$root_out_dir/Flutter.xcframework" ] + args = [ + "--frameworks", + rebase_path("$_flutter_framework_dir"), + "--name", + "Flutter", + "--location", + rebase_path("$root_out_dir"), + ] + + deps = [ ":universal_flutter_framework" ] +} diff --git a/sky/tools/create_xcframework.py b/sky/tools/create_xcframework.py new file mode 100755 index 00000000000000..400bce56248789 --- /dev/null +++ b/sky/tools/create_xcframework.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# Copyright 2013 The Flutter Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import argparse +import errno +import os +import shutil +import subprocess +import sys + +def main(): + parser = argparse.ArgumentParser( + description='Creates an XCFramework consisting of the specified universal frameworks') + + parser.add_argument('--frameworks', + nargs='+', help='The framework paths used to create the XCFramework.', required=True) + parser.add_argument('--name', help='Name of the XCFramework', type=str, required=True) + parser.add_argument('--location', help='Output directory', type=str, required=True) + + args = parser.parse_args() + + output_dir = os.path.abspath(args.location) + output_xcframework = os.path.join(output_dir, '%s.xcframework' % args.name) + + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + if os.path.exists(output_xcframework): + # Remove old xcframework. + shutil.rmtree(output_xcframework) + + # xcrun xcodebuild -create-xcframework -framework foo/baz.framework -framework bar/baz.framework -output output/ + command = ['xcrun', + 'xcodebuild', + '-quiet', + '-create-xcframework'] + + for framework in args.frameworks: + command.extend(['-framework', os.path.abspath(framework)]) + + command.extend(['-output', output_xcframework]) + + subprocess.check_call(command, stdout=open(os.devnull, 'w')) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/testing/scenario_app/compile_ios_aot.sh b/testing/scenario_app/compile_ios_aot.sh index 40dad57a4016d4..06b5adc82f1877 100755 --- a/testing/scenario_app/compile_ios_aot.sh +++ b/testing/scenario_app/compile_ios_aot.sh @@ -103,7 +103,7 @@ cp "$SCRIPT_DIR/ios/AppFrameworkInfo.plist" "$OUTDIR/App.framework/Info.plist" echo "Created $OUTDIR/App.framework/App." rm -rf "$SCRIPT_DIR/ios/Scenarios/App.framework" -rm -rf "$SCRIPT_DIR/ios/Scenarios/Flutter.framework" +rm -rf "$SCRIPT_DIR/ios/Scenarios/Flutter.xcframework" cp -R "$OUTDIR/App.framework" "$SCRIPT_DIR/ios/Scenarios" -cp -R "$DEVICE_TOOLS/../Flutter.framework" "$SCRIPT_DIR/ios/Scenarios" +cp -R "$DEVICE_TOOLS/../Flutter.xcframework" "$SCRIPT_DIR/ios/Scenarios" diff --git a/testing/scenario_app/compile_ios_jit.sh b/testing/scenario_app/compile_ios_jit.sh index 7cae11b4466764..9b2eb9a8bddd0f 100755 --- a/testing/scenario_app/compile_ios_jit.sh +++ b/testing/scenario_app/compile_ios_jit.sh @@ -111,6 +111,6 @@ cp "$SCRIPT_DIR/ios/AppFrameworkInfo.plist" "$OUTDIR/App.framework/Info.plist" echo "Created $OUTDIR/App.framework/App." rm -rf "$SCRIPT_DIR/ios/Scenarios/App.framework" -rm -rf "$SCRIPT_DIR/ios/Scenarios/Flutter.framework" +rm -rf "$SCRIPT_DIR/ios/Scenarios/Flutter.xcframework" cp -R "$OUTDIR/App.framework" "$SCRIPT_DIR/ios/Scenarios" -cp -R "$DEVICE_TOOLS/../Flutter.framework" "$SCRIPT_DIR/ios/Scenarios" +cp -R "$DEVICE_TOOLS/../Flutter.xcframework" "$SCRIPT_DIR/ios/Scenarios" diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index 71d8cb57f989db..98565ef094b0d5 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -14,19 +14,19 @@ 0A97D7C024BA937000050525 /* FlutterViewControllerInitialRouteTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A97D7BF24BA937000050525 /* FlutterViewControllerInitialRouteTest.m */; }; 0D14A3FE239743190013D873 /* golden_platform_view_rotate_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 0D14A3FD239743190013D873 /* golden_platform_view_rotate_iPhone SE_simulator.png */; }; 0D8470A4240F0B1F0030B565 /* StatusBarTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0D8470A3240F0B1F0030B565 /* StatusBarTest.m */; }; - 0DB781EF22E931BE00E9B371 /* Flutter.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 0DB781F122E933E800E9B371 /* Flutter.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 0DB781FE22EA2C6D00E9B371 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.framework */; }; - 0DB781FF22EA2C7200E9B371 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.framework */; }; + 0DB781EF22E931BE00E9B371 /* Flutter.xcframework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 0DB781F122E933E800E9B371 /* Flutter.xcframework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 0DB781FE22EA2C6D00E9B371 /* Flutter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.xcframework */; }; + 0DB781FF22EA2C7200E9B371 /* Flutter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.xcframework */; }; 0DB7820022EA2C9D00E9B371 /* App.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4122E3B5F700073EBF /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 0DB7820122EA2CA500E9B371 /* App.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 246B4E4122E3B5F700073EBF /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 0DB7820222EA493B00E9B371 /* FlutterViewControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DB781FC22EA2C0300E9B371 /* FlutterViewControllerTest.m */; }; - 242F37A222E636DE001E83D4 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 242F37A222E636DE001E83D4 /* Flutter.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 242F37A322E636DE001E83D4 /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4122E3B5F700073EBF /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 244EA6D0230DBE8900B2D26E /* golden_platform_view_D21AP.png in Resources */ = {isa = PBXBuildFile; fileRef = 244EA6CF230DBE8900B2D26E /* golden_platform_view_D21AP.png */; }; 246A6611252E693A00EAB0F3 /* RenderingSelectionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 246A6610252E693A00EAB0F3 /* RenderingSelectionTest.m */; }; 246B4E4222E3B5F700073EBF /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4122E3B5F700073EBF /* App.framework */; }; - 246B4E4622E3B61000073EBF /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.framework */; }; + 246B4E4622E3B61000073EBF /* Flutter.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 246B4E4522E3B61000073EBF /* Flutter.xcframework */; }; 248D76CC22E388370012F0C1 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 248D76CB22E388370012F0C1 /* AppDelegate.m */; }; 248D76D422E388380012F0C1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 248D76D322E388380012F0C1 /* Assets.xcassets */; }; 248D76DA22E388380012F0C1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 248D76D922E388380012F0C1 /* main.m */; }; @@ -83,7 +83,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 0DB781EF22E931BE00E9B371 /* Flutter.framework in CopyFiles */, + 0DB781EF22E931BE00E9B371 /* Flutter.xcframework in CopyFiles */, 0DB7820122EA2CA500E9B371 /* App.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; @@ -94,7 +94,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 0DB781F122E933E800E9B371 /* Flutter.framework in CopyFiles */, + 0DB781F122E933E800E9B371 /* Flutter.xcframework in CopyFiles */, 0DB7820022EA2C9D00E9B371 /* App.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; @@ -105,7 +105,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 242F37A222E636DE001E83D4 /* Flutter.framework in Embed Frameworks */, + 242F37A222E636DE001E83D4 /* Flutter.xcframework in Embed Frameworks */, 242F37A322E636DE001E83D4 /* App.framework in Embed Frameworks */, ); name = "Embed Frameworks"; @@ -129,7 +129,7 @@ 244EA6CF230DBE8900B2D26E /* golden_platform_view_D21AP.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = golden_platform_view_D21AP.png; sourceTree = ""; }; 246A6610252E693A00EAB0F3 /* RenderingSelectionTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RenderingSelectionTest.m; sourceTree = ""; }; 246B4E4122E3B5F700073EBF /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = App.framework; sourceTree = ""; }; - 246B4E4522E3B61000073EBF /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Flutter.framework; sourceTree = ""; }; + 246B4E4522E3B61000073EBF /* Flutter.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Flutter.xcframework; sourceTree = ""; }; 248D76C722E388370012F0C1 /* Scenarios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Scenarios.app; sourceTree = BUILT_PRODUCTS_DIR; }; 248D76CA22E388370012F0C1 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 248D76CB22E388370012F0C1 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -180,7 +180,7 @@ buildActionMask = 2147483647; files = ( 246B4E4222E3B5F700073EBF /* App.framework in Frameworks */, - 246B4E4622E3B61000073EBF /* Flutter.framework in Frameworks */, + 246B4E4622E3B61000073EBF /* Flutter.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -188,7 +188,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0DB781FF22EA2C7200E9B371 /* Flutter.framework in Frameworks */, + 0DB781FF22EA2C7200E9B371 /* Flutter.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -196,7 +196,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0DB781FE22EA2C6D00E9B371 /* Flutter.framework in Frameworks */, + 0DB781FE22EA2C6D00E9B371 /* Flutter.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -301,7 +301,7 @@ 248D76FC22E388900012F0C1 /* Frameworks */ = { isa = PBXGroup; children = ( - 246B4E4522E3B61000073EBF /* Flutter.framework */, + 246B4E4522E3B61000073EBF /* Flutter.xcframework */, 246B4E4122E3B5F700073EBF /* App.framework */, ); name = Frameworks;