Vend Flutter module App.framework as a local CocoaPod pod to be installed by a host app (#36793)
diff --git a/dev/integration_tests/ios_add2app/Podfile b/dev/integration_tests/ios_add2app/Podfile index 72e1973..8885e60 100644 --- a/dev/integration_tests/ios_add2app/Podfile +++ b/dev/integration_tests/ios_add2app/Podfile
@@ -1,26 +1,15 @@ platform :ios, '12.0' -# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. -install! 'cocoapods', :disable_input_output_paths => true - flutter_application_path = 'flutterapp/' -framework_dir = File.join(flutter_application_path, '.ios', 'Flutter') -engine_dir = File.join(framework_dir, 'engine') -if !File.exist?(engine_dir) - # Copy the debug engine to have something to link against if the xcode backend script has not run yet. - debug_framework_dir = File.join(flutter_root(flutter_application_path), 'bin', 'cache', 'artifacts', 'engine', 'ios') - FileUtils.mkdir_p(engine_dir) - FileUtils.cp_r(File.join(debug_framework_dir, 'Flutter.framework'), engine_dir) - FileUtils.cp(File.join(debug_framework_dir, 'Flutter.podspec'), engine_dir) -end +load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') target 'ios_add2app' do - eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding) + install_all_flutter_pods(flutter_application_path, 'ios_add2app_flutter') end target 'ios_add2appTests' do - pod 'Flutter', :path => engine_dir inherit! :search_paths + install_flutter_engine_pod pod 'EarlGrey' end
diff --git a/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/project.pbxproj b/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/project.pbxproj index 1859736..cc75d34 100644 --- a/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/project.pbxproj +++ b/dev/integration_tests/ios_add2app/ios_add2app.xcodeproj/project.pbxproj
@@ -19,8 +19,8 @@ 24E221E021A28B23008ADF09 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 24E221D721A28B23008ADF09 /* Launch Screen.storyboard */; }; 24E221E221A28B36008ADF09 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 24E221E121A28B36008ADF09 /* Assets.xcassets */; }; 24E7A1FE21A2AF26003A7FAD /* FlutterViewControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E7A1FD21A2AF26003A7FAD /* FlutterViewControllerTests.m */; }; + 4C21FEB4D629B570C74073D1 /* libPods-ios_add2appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F90B141A9A8A680033E97924 /* libPods-ios_add2appTests.a */; }; 8BDD73EC12DFA6CD2AC4EEDA /* EarlGrey.framework in EarlGrey Copy Files */ = {isa = PBXBuildFile; fileRef = DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - AE3B0A0EAE765C1EC16866BF /* libPods-ios_add2appTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 699900B7FF01268E98EC69ED /* libPods-ios_add2appTests.a */; }; DB9A200AFEB7AAE22B4E12E4 /* libPods-ios_add2app.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */; }; /* End PBXBuildFile section */ @@ -73,13 +73,15 @@ 24E7A1FD21A2AF26003A7FAD /* FlutterViewControllerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FlutterViewControllerTests.m; sourceTree = "<group>"; }; 36DA6BEAA5127D74EC6E3E13 /* Pods-ios_add2appUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appUITests/Pods-ios_add2appUITests.debug.xcconfig"; sourceTree = "<group>"; }; 52EA0B290EEBC1D28BF6E803 /* libPods-ios_add2appUITests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2appUITests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 699900B7FF01268E98EC69ED /* libPods-ios_add2appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 74266A4D94FA1C3157B5B560 /* Pods-ios_add2appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.debug.xcconfig"; sourceTree = "<group>"; }; + 762E954C71D922C091619CD4 /* Pods-ios_add2app-ios_add2appTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app-ios_add2appTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app-ios_add2appTests/Pods-ios_add2app-ios_add2appTests.debug.xcconfig"; sourceTree = "<group>"; }; 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2app.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 83017A33946358F55BAE24E1 /* Pods-ios_add2appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2appTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests.release.xcconfig"; sourceTree = "<group>"; }; + 98A4882F55A3E107DFCB67D8 /* Pods-ios_add2app-ios_add2appTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app-ios_add2appTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app-ios_add2appTests/Pods-ios_add2app-ios_add2appTests.release.xcconfig"; sourceTree = "<group>"; }; A18D4CDABD6795975FD6B49F /* Pods-ios_add2app.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.release.xcconfig"; sourceTree = "<group>"; }; CCFA174387D083C931FB85D0 /* Pods-ios_add2app.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios_add2app.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app.debug.xcconfig"; sourceTree = "<group>"; }; DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EarlGrey.framework; path = Pods/EarlGrey/EarlGrey/EarlGrey.framework; sourceTree = SOURCE_ROOT; }; + F90B141A9A8A680033E97924 /* libPods-ios_add2appTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios_add2appTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -88,7 +90,7 @@ buildActionMask = 2147483647; files = ( 09C65652A2B48A21C94FF831 /* EarlGrey.framework in Frameworks */, - AE3B0A0EAE765C1EC16866BF /* libPods-ios_add2appTests.a in Frameworks */, + 4C21FEB4D629B570C74073D1 /* libPods-ios_add2appTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -162,7 +164,7 @@ 7A318514E0307AE0FF0EFC76 /* libPods-ios_add2app.a */, DE1EF0F5719FBB45225A9EC3 /* EarlGrey.framework */, 52EA0B290EEBC1D28BF6E803 /* libPods-ios_add2appUITests.a */, - 699900B7FF01268E98EC69ED /* libPods-ios_add2appTests.a */, + F90B141A9A8A680033E97924 /* libPods-ios_add2appTests.a */, ); name = Frameworks; sourceTree = "<group>"; @@ -176,6 +178,8 @@ 16D27B9BE77DC8804292A9A9 /* Pods-ios_add2appUITests.release.xcconfig */, 74266A4D94FA1C3157B5B560 /* Pods-ios_add2appTests.debug.xcconfig */, 83017A33946358F55BAE24E1 /* Pods-ios_add2appTests.release.xcconfig */, + 762E954C71D922C091619CD4 /* Pods-ios_add2app-ios_add2appTests.debug.xcconfig */, + 98A4882F55A3E107DFCB67D8 /* Pods-ios_add2app-ios_add2appTests.release.xcconfig */, ); name = Pods; sourceTree = "<group>"; @@ -209,7 +213,7 @@ buildConfigurationList = 24E221CB21A28A0C008ADF09 /* Build configuration list for PBXNativeTarget "ios_add2app" */; buildPhases = ( 4375EE880A727341E9C9A57D /* [CP] Check Pods Manifest.lock */, - 24E221E321A28B53008ADF09 /* ShellScript */, + CE6831C2A33C6C5C84521FDE /* [CP-User] Run Flutter Build Script */, 24E221B121A28A0B008ADF09 /* Sources */, 24E221B221A28A0B008ADF09 /* Frameworks */, 24E221B321A28A0B008ADF09 /* Resources */, @@ -281,23 +285,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 24E221E321A28B53008ADF09 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n"; - }; 4375EE880A727341E9C9A57D /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -326,19 +313,33 @@ files = ( ); inputFileListPaths = ( - ); - inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ios_add2app/Pods-ios_add2app-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + CE6831C2A33C6C5C84521FDE /* [CP-User] Run Flutter Build Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/flutterapp/.metadata", + "${SRCROOT}/flutterapp/.ios/Flutter/App.framework/App", + "${SRCROOT}/flutterapp/.ios/Flutter/engine/Flutter.framework/Flutter", + "${SRCROOT}/flutterapp/.ios/Flutter/flutter_export_environment.sh", + ); + name = "[CP-User] Run Flutter Build Script"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "source \"${SRCROOT}/flutterapp/.ios/Flutter/flutter_export_environment.sh\"\n\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh build"; + }; DE5CDCD8B3565EAB9F38F455 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -367,22 +368,15 @@ files = ( ); inputFileListPaths = ( - ); - inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh", - "${PODS_ROOT}/../flutterapp/.ios/Flutter/engine/Flutter.framework", - "${PODS_ROOT}/EarlGrey/EarlGrey/EarlGrey.framework", + "${PODS_ROOT}/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EarlGrey.framework", + "${PODS_ROOT}/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ios_add2appTests/Pods-ios_add2appTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */
diff --git a/dev/integration_tests/ios_host_app/Config/Debug.xcconfig b/dev/integration_tests/ios_host_app/Config/Debug.xcconfig deleted file mode 100644 index 3f48cde..0000000 --- a/dev/integration_tests/ios_host_app/Config/Debug.xcconfig +++ /dev/null
@@ -1,2 +0,0 @@ -#include "Flutter.xcconfig" -#include "../Pods/Target Support Files/Pods-Host/Pods-Host.debug.xcconfig"
diff --git a/dev/integration_tests/ios_host_app/Config/Flutter.xcconfig b/dev/integration_tests/ios_host_app/Config/Flutter.xcconfig deleted file mode 100644 index ccfdd63..0000000 --- a/dev/integration_tests/ios_host_app/Config/Flutter.xcconfig +++ /dev/null
@@ -1,2 +0,0 @@ -#include "../../hello/.ios/Flutter/Generated.xcconfig" -ENABLE_BITCODE=NO
diff --git a/dev/integration_tests/ios_host_app/Config/Release.xcconfig b/dev/integration_tests/ios_host_app/Config/Release.xcconfig deleted file mode 100644 index e9764d1..0000000 --- a/dev/integration_tests/ios_host_app/Config/Release.xcconfig +++ /dev/null
@@ -1,3 +0,0 @@ -#include "Flutter.xcconfig" -#include "../Pods/Target Support Files/Pods-Host/Pods-Host.release.xcconfig" -FLUTTER_BUILD_MODE=release
diff --git a/dev/integration_tests/ios_host_app/Flutter/.gitkeep b/dev/integration_tests/ios_host_app/Flutter/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/dev/integration_tests/ios_host_app/Flutter/.gitkeep +++ /dev/null
diff --git a/dev/integration_tests/ios_host_app/Host.xcodeproj/project.pbxproj b/dev/integration_tests/ios_host_app/Host.xcodeproj/project.pbxproj index b7edca5..ce8eb70 100644 --- a/dev/integration_tests/ios_host_app/Host.xcodeproj/project.pbxproj +++ b/dev/integration_tests/ios_host_app/Host.xcodeproj/project.pbxproj
@@ -13,26 +13,9 @@ 74F9786E215AB9E9005A0F04 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 74F9786D215AB9E9005A0F04 /* Assets.xcassets */; }; 74F97871215AB9E9005A0F04 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74F9786F215AB9E9005A0F04 /* LaunchScreen.storyboard */; }; 74F97874215AB9E9005A0F04 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 74F97873215AB9E9005A0F04 /* main.m */; }; - 74F978AF215AD6F9005A0F04 /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 74F978AC215AD6E8005A0F04 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - DAEA7B95412864C7F3A4AE98 /* libPods-Host.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2499C53F0BD30E24745E2F6B /* libPods-Host.a */; }; /* End PBXBuildFile section */ -/* Begin PBXCopyFilesBuildPhase section */ - 74F978A2215ACF9B005A0F04 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 74F978AF215AD6F9005A0F04 /* App.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ - 2499C53F0BD30E24745E2F6B /* libPods-Host.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Host.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 74F97861215AB9E8005A0F04 /* Host.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Host.app; sourceTree = BUILT_PRODUCTS_DIR; }; 74F97864215AB9E8005A0F04 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 74F97865215AB9E8005A0F04 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; @@ -43,10 +26,6 @@ 74F97870215AB9E9005A0F04 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 74F97872215AB9E9005A0F04 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 74F97873215AB9E9005A0F04 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; - 74F9787B215ABA08005A0F04 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; - 74F9787C215ABA73005A0F04 /* Flutter.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Flutter.xcconfig; sourceTree = "<group>"; }; - 74F9787D215ABA9D005A0F04 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; - 74F978AC215AD6E8005A0F04 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = ../../hello/.ios/Flutter/App.framework; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -54,7 +33,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DAEA7B95412864C7F3A4AE98 /* libPods-Host.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -64,8 +42,6 @@ 74F97858215AB9E8005A0F04 = { isa = PBXGroup; children = ( - 74F978A3215AD111005A0F04 /* Flutter */, - 74F9787A215AB9F3005A0F04 /* Config */, 74F97863215AB9E8005A0F04 /* Host */, 74F97862215AB9E8005A0F04 /* Products */, 74F9788B215AC328005A0F04 /* Frameworks */, @@ -97,32 +73,13 @@ path = Host; sourceTree = "<group>"; }; - 74F9787A215AB9F3005A0F04 /* Config */ = { - isa = PBXGroup; - children = ( - 74F9787C215ABA73005A0F04 /* Flutter.xcconfig */, - 74F9787B215ABA08005A0F04 /* Debug.xcconfig */, - 74F9787D215ABA9D005A0F04 /* Release.xcconfig */, - ); - path = Config; - sourceTree = "<group>"; - }; 74F9788B215AC328005A0F04 /* Frameworks */ = { isa = PBXGroup; children = ( - 2499C53F0BD30E24745E2F6B /* libPods-Host.a */, ); name = Frameworks; sourceTree = "<group>"; }; - 74F978A3215AD111005A0F04 /* Flutter */ = { - isa = PBXGroup; - children = ( - 74F978AC215AD6E8005A0F04 /* App.framework */, - ); - path = Flutter; - sourceTree = "<group>"; - }; A4A9971F50C4EE357B74B6E0 /* Pods */ = { isa = PBXGroup; children = ( @@ -137,13 +94,9 @@ isa = PBXNativeTarget; buildConfigurationList = 74F97877215AB9E9005A0F04 /* Build configuration list for PBXNativeTarget "Host" */; buildPhases = ( - EDACAC7378E52BD5BBDB34D5 /* [CP] Check Pods Manifest.lock */, - 74F9787E215ABB1B005A0F04 /* Run Script */, 74F9785D215AB9E8005A0F04 /* Sources */, 74F9785E215AB9E8005A0F04 /* Frameworks */, 74F9785F215AB9E8005A0F04 /* Resources */, - 53642CAE5328D86A50FDAD59 /* [CP] Embed Pods Frameworks */, - 74F978A2215ACF9B005A0F04 /* Embed Frameworks */, ); buildRules = ( ); @@ -199,56 +152,6 @@ }; /* End PBXResourcesBuildPhase section */ -/* Begin PBXShellScriptBuildPhase section */ - 53642CAE5328D86A50FDAD59 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Host/Pods-Host-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 74F9787E215ABB1B005A0F04 /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n\"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed\n"; - }; - EDACAC7378E52BD5BBDB34D5 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Host-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - /* Begin PBXSourcesBuildPhase section */ 74F9785D215AB9E8005A0F04 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -317,6 +220,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -376,6 +280,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -396,7 +301,6 @@ }; 74F97878215AB9E9005A0F04 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 74F9787B215ABA08005A0F04 /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; @@ -414,7 +318,6 @@ }; 74F97879215AB9E9005A0F04 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 74F9787D215ABA9D005A0F04 /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic;
diff --git a/dev/integration_tests/ios_host_app/Host/ViewController.m b/dev/integration_tests/ios_host_app/Host/ViewController.m index 6101171..3eb47c0 100644 --- a/dev/integration_tests/ios_host_app/Host/ViewController.m +++ b/dev/integration_tests/ios_host_app/Host/ViewController.m
@@ -1,6 +1,6 @@ #import "ViewController.h" -#import "Flutter/Flutter.h" -#import "FlutterPluginRegistrant/GeneratedPluginRegistrant.h" +#import <Flutter/Flutter.h> +#import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h> @implementation ViewController
diff --git a/dev/integration_tests/ios_host_app/Podfile b/dev/integration_tests/ios_host_app/Podfile index 2b94908..a74eec9 100644 --- a/dev/integration_tests/ios_host_app/Podfile +++ b/dev/integration_tests/ios_host_app/Podfile
@@ -1,9 +1,8 @@ platform :ios, '9.0' -# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. -install! 'cocoapods', :disable_input_output_paths => true +flutter_application_path = '../hello' +load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') target 'Host' do - flutter_application_path = '../hello' - eval(File.read("#{flutter_application_path}/.ios/Flutter/podhelper.rb")) + install_all_flutter_pods flutter_application_path end
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart index 7be0ef1..7234890 100644 --- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart +++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -10,6 +10,7 @@ import '../base/context.dart'; import '../base/file_system.dart'; import '../base/io.dart'; +import '../base/os.dart'; import '../base/platform.dart'; import '../base/process.dart'; import '../base/process_manager.dart'; @@ -48,25 +49,96 @@ bool useMacOSConfig = false, bool setSymroot = true, }) async { + final List<String> xcodeBuildSettings = _xcodeBuildSettingsLines( + project: project, + buildInfo: buildInfo, + targetOverride: targetOverride, + useMacOSConfig: useMacOSConfig, + setSymroot: setSymroot + ); + + _updateGeneratedXcodePropertiesFile( + project: project, + xcodeBuildSettings: xcodeBuildSettings, + useMacOSConfig: useMacOSConfig, + ); + + _updateGeneratedEnvironmentVariablesScript( + project: project, + xcodeBuildSettings: xcodeBuildSettings, + useMacOSConfig: useMacOSConfig, + ); +} + +/// Generate a xcconfig file to inherit FLUTTER_ build settings +/// for Xcode targets that need them. +/// See [XcodeBasedProject.generatedXcodePropertiesFile]. +void _updateGeneratedXcodePropertiesFile({ + @required FlutterProject project, + @required List<String> xcodeBuildSettings, + bool useMacOSConfig = false, +}) { final StringBuffer localsBuffer = StringBuffer(); localsBuffer.writeln('// This is a generated file; do not edit or check into version control.'); + xcodeBuildSettings.forEach(localsBuffer.writeln); + final File generatedXcodePropertiesFile = useMacOSConfig + ? project.macos.generatedXcodePropertiesFile + : project.ios.generatedXcodePropertiesFile; + + generatedXcodePropertiesFile.createSync(recursive: true); + generatedXcodePropertiesFile.writeAsStringSync(localsBuffer.toString()); +} + +/// Generate a script to export all the FLUTTER_ environment variables needed +/// as flags for Flutter tools. +/// See [XcodeBasedProject.generatedEnvironmentVariableExportScript]. +void _updateGeneratedEnvironmentVariablesScript({ + @required FlutterProject project, + @required List<String> xcodeBuildSettings, + bool useMacOSConfig = false, +}) { + final StringBuffer localsBuffer = StringBuffer(); + + localsBuffer.writeln('#!/bin/sh'); + localsBuffer.writeln('# This is a generated file; do not edit or check into version control.'); + for (String line in xcodeBuildSettings) { + localsBuffer.writeln('export "$line"'); + } + + final File generatedModuleBuildPhaseScript = useMacOSConfig + ? project.macos.generatedEnvironmentVariableExportScript + : project.ios.generatedEnvironmentVariableExportScript; + generatedModuleBuildPhaseScript.createSync(recursive: true); + generatedModuleBuildPhaseScript.writeAsStringSync(localsBuffer.toString()); + os.chmod(generatedModuleBuildPhaseScript, '755'); +} + +/// List of lines of build settings. Example: 'FLUTTER_BUILD_DIR=build' +List<String> _xcodeBuildSettingsLines({ + @required FlutterProject project, + @required BuildInfo buildInfo, + String targetOverride, + bool useMacOSConfig = false, + bool setSymroot = true, +}) { + final List<String> xcodeBuildSettings = <String>[]; final String flutterRoot = fs.path.normalize(Cache.flutterRoot); - localsBuffer.writeln('FLUTTER_ROOT=$flutterRoot'); + xcodeBuildSettings.add('FLUTTER_ROOT=$flutterRoot'); // This holds because requiresProjectRoot is true for this command - localsBuffer.writeln('FLUTTER_APPLICATION_PATH=${fs.path.normalize(project.directory.path)}'); + xcodeBuildSettings.add('FLUTTER_APPLICATION_PATH=${fs.path.normalize(project.directory.path)}'); // Relative to FLUTTER_APPLICATION_PATH, which is [Directory.current]. if (targetOverride != null) - localsBuffer.writeln('FLUTTER_TARGET=$targetOverride'); + xcodeBuildSettings.add('FLUTTER_TARGET=$targetOverride'); // The build outputs directory, relative to FLUTTER_APPLICATION_PATH. - localsBuffer.writeln('FLUTTER_BUILD_DIR=${getBuildDirectory()}'); + xcodeBuildSettings.add('FLUTTER_BUILD_DIR=${getBuildDirectory()}'); if (setSymroot) { - localsBuffer.writeln('SYMROOT=\${SOURCE_ROOT}/../${getIosBuildDirectory()}'); + xcodeBuildSettings.add('SYMROOT=\${SOURCE_ROOT}/../${getIosBuildDirectory()}'); } if (!project.isModule) { @@ -75,26 +147,26 @@ // logic to derive it from FLUTTER_ROOT and FLUTTER_BUILD_MODE. // However, this is necessary for regular projects using Cocoapods. final String frameworkDir = useMacOSConfig - ? flutterMacOSFrameworkDir(buildInfo.mode) - : flutterFrameworkDir(buildInfo.mode); - localsBuffer.writeln('FLUTTER_FRAMEWORK_DIR=$frameworkDir'); + ? flutterMacOSFrameworkDir(buildInfo.mode) + : flutterFrameworkDir(buildInfo.mode); + xcodeBuildSettings.add('FLUTTER_FRAMEWORK_DIR=$frameworkDir'); } final String buildName = validatedBuildNameForPlatform(TargetPlatform.ios, buildInfo?.buildName ?? project.manifest.buildName); if (buildName != null) { - localsBuffer.writeln('FLUTTER_BUILD_NAME=$buildName'); + xcodeBuildSettings.add('FLUTTER_BUILD_NAME=$buildName'); } final String buildNumber = validatedBuildNumberForPlatform(TargetPlatform.ios, buildInfo?.buildNumber ?? project.manifest.buildNumber); if (buildNumber != null) { - localsBuffer.writeln('FLUTTER_BUILD_NUMBER=$buildNumber'); + xcodeBuildSettings.add('FLUTTER_BUILD_NUMBER=$buildNumber'); } if (artifacts is LocalEngineArtifacts) { final LocalEngineArtifacts localEngineArtifacts = artifacts; final String engineOutPath = localEngineArtifacts.engineOutPath; - localsBuffer.writeln('FLUTTER_ENGINE=${fs.path.dirname(fs.path.dirname(engineOutPath))}'); - localsBuffer.writeln('LOCAL_ENGINE=${fs.path.basename(engineOutPath)}'); + xcodeBuildSettings.add('FLUTTER_ENGINE=${fs.path.dirname(fs.path.dirname(engineOutPath))}'); + xcodeBuildSettings.add('LOCAL_ENGINE=${fs.path.basename(engineOutPath)}'); // Tell Xcode not to build universal binaries for local engines, which are // single-architecture. @@ -106,19 +178,15 @@ // Skip this step for macOS builds. if (!useMacOSConfig) { final String arch = engineOutPath.endsWith('_arm') ? 'armv7' : 'arm64'; - localsBuffer.writeln('ARCHS=$arch'); + xcodeBuildSettings.add('ARCHS=$arch'); } } if (buildInfo.trackWidgetCreation) { - localsBuffer.writeln('TRACK_WIDGET_CREATION=true'); + xcodeBuildSettings.add('TRACK_WIDGET_CREATION=true'); } - final File generatedXcodePropertiesFile = useMacOSConfig - ? project.macos.generatedXcodePropertiesFile - : project.ios.generatedXcodePropertiesFile; - generatedXcodePropertiesFile.createSync(recursive: true); - generatedXcodePropertiesFile.writeAsStringSync(localsBuffer.toString()); + return xcodeBuildSettings; } XcodeProjectInterpreter get xcodeProjectInterpreter => context.get<XcodeProjectInterpreter>();
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index ece0846..d9d7a3e 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart
@@ -260,6 +260,12 @@ /// The Flutter-managed Xcode config file for [mode]. File xcodeConfigFor(String mode); + /// The script that exports environment variables needed for Flutter tools. + /// Can be run first in a Xcode Script build phase to make FLUTTER_ROOT, + /// LOCAL_ENGINE, and other Flutter variables available to any flutter + /// tooling (`flutter build`, etc) to convert into flags. + File get generatedEnvironmentVariableExportScript; + /// The CocoaPods 'Podfile'. File get podfile; @@ -318,6 +324,9 @@ File xcodeConfigFor(String mode) => _flutterLibRoot.childDirectory('Flutter').childFile('$mode.xcconfig'); @override + File get generatedEnvironmentVariableExportScript => _flutterLibRoot.childDirectory('Flutter').childFile('flutter_export_environment.sh'); + + @override File get podfile => hostAppRoot.childFile('Podfile'); @override @@ -662,6 +671,9 @@ File xcodeConfigFor(String mode) => managedDirectory.childFile('Flutter-$mode.xcconfig'); @override + File get generatedEnvironmentVariableExportScript => managedDirectory.childFile('flutter_export_environment.sh'); + + @override File get podfile => _macOSDirectory.childFile('Podfile'); @override
diff --git a/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl index b2b9a40..1e70150 100644 --- a/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl +++ b/packages/flutter_tools/templates/module/ios/host_app_ephemeral_cocoapods/Podfile.copy.tmpl
@@ -1,8 +1,18 @@ platform :ios, '8.0' +flutter_application_path = '../' +load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb') + target 'Runner' do - flutter_application_path = '../' - eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding) + install_flutter_plugin_pods flutter_application_path +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end end # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
diff --git a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb index 3956697..f833b85 100644 --- a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb +++ b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/podhelper.rb
@@ -1,75 +1,137 @@ -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; - end - pods_array = [] - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) { |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - pods_array.push({:name => podname, :path => podpath}); - else - puts "Invalid plugin specification: #{line}" - end - } - return pods_array +# Install pods needed to embed Flutter application, Flutter engine, and plugins +# from the host application Podfile. +# +# @example +# target 'MyApp' do +# install_all_flutter_pods 'my_flutter' +# end +# @param [String] flutter_application_path Path of the root directory of the Flutter module. +# Optional, defaults to two levels up from the directory of this script. +# MyApp/my_flutter/.ios/Flutter/../.. +# @param [String] flutter_application_name Name of the Flutter module. Optional, defaults to module directory name. +def install_all_flutter_pods(flutter_application_path = nil, flutter_application_name = nil) + flutter_application_name ||= File.basename(File.expand_path(flutter_application_path)) + flutter_application_path ||= File.join('..', '..') + install_flutter_engine_pod + install_flutter_plugin_pods(flutter_application_path) + install_flutter_application_pod(flutter_application_path, flutter_application_name) end -def flutter_root(f) - generated_xcode_build_settings = parse_KV_file(File.join(f, File.join('.ios', 'Flutter', 'Generated.xcconfig'))) - if generated_xcode_build_settings.empty? - puts "Generated.xcconfig must exist. Make sure `flutter pub get` is executed in #{f}." - exit - end - generated_xcode_build_settings.map { |p| - if p[:name] == 'FLUTTER_ROOT' - return p[:path] - end - } -end - -# If this wasn't specified, assume it's two levels up from the directory of this script. -flutter_application_path ||= File.join(__dir__, '..', '..') -framework_dir = File.join(flutter_application_path, '.ios', 'Flutter') - -engine_dir = File.join(framework_dir, 'engine') -if !File.exist?(engine_dir) +# Install Flutter engine pod. +# +# @example +# target 'MyApp' do +# install_flutter_engine_pod +# end +def install_flutter_engine_pod + engine_dir = File.join(__dir__, 'engine') + if !File.exist?(engine_dir) # Copy the debug engine to have something to link against if the xcode backend script has not run yet. - debug_framework_dir = File.join(flutter_root(flutter_application_path), 'bin', 'cache', 'artifacts', 'engine', 'ios') + # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. + debug_framework_dir = File.join(flutter_root, 'bin', 'cache', 'artifacts', 'engine', 'ios') FileUtils.mkdir_p(engine_dir) FileUtils.cp_r(File.join(debug_framework_dir, 'Flutter.framework'), engine_dir) FileUtils.cp(File.join(debug_framework_dir, 'Flutter.podspec'), engine_dir) + end + + pod 'Flutter', :path => engine_dir, :inhibit_warnings => true end -pod 'Flutter', :path => engine_dir -pod 'FlutterPluginRegistrant', :path => File.join(framework_dir, 'FlutterPluginRegistrant') +# Install Flutter plugin pods. +# +# @example +# target 'MyApp' do +# install_flutter_plugin_pods 'my_flutter' +# end +# @param [String] flutter_application_path Path of the root directory of the Flutter module. +# Optional, defaults to two levels up from the directory of this script. +# MyApp/my_flutter/.ios/Flutter/../.. +def install_flutter_plugin_pods(flutter_application_path) + flutter_application_path ||= File.join('..', '..') + pod 'FlutterPluginRegistrant', :path => File.join(__dir__, 'FlutterPluginRegistrant'), :inhibit_warnings => true -symlinks_dir = File.join(framework_dir, '.symlinks') -FileUtils.mkdir_p(symlinks_dir) -plugin_pods = parse_KV_file(File.join(flutter_application_path, '.flutter-plugins')) -plugin_pods.map { |r| + symlinks_dir = File.join(__dir__, '.symlinks') + FileUtils.mkdir_p(symlinks_dir) + plugin_pods = parse_KV_file(File.join(flutter_application_path, '.flutter-plugins')) + plugin_pods.map do |r| symlink = File.join(symlinks_dir, r[:name]) FileUtils.rm_f(symlink) File.symlink(r[:path], symlink) - pod r[:name], :path => File.join(symlink, 'ios') -} + pod r[:name], :path => File.join(symlink, 'ios'), :inhibit_warnings => true + end +end -# Ensure that ENABLE_BITCODE is set to NO, add a #include to Generated.xcconfig, and -# add a run script to the Build Phases. -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_BITCODE'] = 'NO' - next if config.base_configuration_reference == nil - xcconfig_path = config.base_configuration_reference.real_path - File.open(xcconfig_path, 'a+') do |file| - file.puts "#include \"#{File.realpath(File.join(framework_dir, 'Generated.xcconfig'))}\"" - end - end +# Install Flutter application pod. +# +# @example +# target 'MyApp' do +# install_flutter_application_pod '../flutter_settings_repository', 'settings_module' +# end +# @param [String] flutter_application_path Path of the root directory of the Flutter module. +# 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, flutter_application_name) + app_framework_dir = File.join(__dir__, 'App.framework') + 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) + `echo "static const int Moo = 88;" | xcrun clang -x c -dynamiclib -o "#{app_framework_dylib}" -` + end + + pod flutter_application_name, :path => __dir__, :inhibit_warnings => true + + # Use relative paths for script phase paths since these strings will likely be checked into source controls. + # Process will be run from project directory. + current_directory_pathname = Pathname.new __dir__.to_s + project_directory_pathname = Pathname.new Dir.pwd + relative = current_directory_pathname.relative_path_from project_directory_pathname + + flutter_export_environment_path = File.join('${SRCROOT}', relative, 'flutter_export_environment.sh'); + script_phase :name => 'Run Flutter Build Script', + :script => "source \"#{flutter_export_environment_path}\"\n\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/xcode_backend.sh build", + :input_files => [ + File.join('${SRCROOT}', flutter_application_path, '.metadata'), + File.join('${SRCROOT}', relative, 'App.framework', 'App'), + File.join('${SRCROOT}', relative, 'engine', 'Flutter.framework', 'Flutter'), + flutter_export_environment_path + ], + :execution_position => :before_compile +end + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + pods_array = [] + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) { |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + pods_array.push({:name => podname, :path => podpath}); + else + puts "Invalid plugin specification: #{line}" end + } + return pods_array +end + +def flutter_root + generated_xcode_build_settings = parse_KV_file(File.join(__dir__, 'Generated.xcconfig')) + if generated_xcode_build_settings.empty? + puts "Generated.xcconfig must exist. Make sure `flutter pub get` is executed in the Flutter module." + exit + end + generated_xcode_build_settings.map { |p| + if p[:name] == 'FLUTTER_ROOT' + return p[:path] + end + } end
diff --git a/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/projectName.podspec.tmpl b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/projectName.podspec.tmpl new file mode 100644 index 0000000..2fbe501 --- /dev/null +++ b/packages/flutter_tools/templates/module/ios/library/Flutter.tmpl/projectName.podspec.tmpl
@@ -0,0 +1,13 @@ +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 = '8.0' + s.vendored_frameworks = 'App.framework' + s.dependency 'Flutter' +end
diff --git a/packages/flutter_tools/test/general.shard/commands/create_test.dart b/packages/flutter_tools/test/general.shard/commands/create_test.dart index 7a8c087..98babb7 100644 --- a/packages/flutter_tools/test/general.shard/commands/create_test.dart +++ b/packages/flutter_tools/test/general.shard/commands/create_test.dart
@@ -100,6 +100,7 @@ '.android/app/', '.gitignore', '.ios/Flutter', + '.ios/Flutter/flutter_project.podspec', '.metadata', 'lib/main.dart', 'pubspec.yaml', @@ -545,6 +546,23 @@ expect(xcodeConfig, contains('FLUTTER_ROOT=')); expect(xcodeConfig, contains('FLUTTER_APPLICATION_PATH=')); expect(xcodeConfig, contains('FLUTTER_TARGET=')); + + // Generated export environment variables script + final String buildPhaseScriptPath = fs.path.join('.ios', 'Flutter', 'flutter_export_environment.sh'); + expectExists(buildPhaseScriptPath); + final File buildPhaseScriptFile = fs.file(fs.path.join(projectDir.path, buildPhaseScriptPath)); + final String buildPhaseScript = buildPhaseScriptFile.readAsStringSync(); + expect(buildPhaseScript, contains('FLUTTER_ROOT=')); + expect(buildPhaseScript, contains('FLUTTER_APPLICATION_PATH=')); + expect(buildPhaseScript, contains('FLUTTER_TARGET=')); + + // Generated podspec + final String podspecPath = fs.path.join('.ios', 'Flutter', 'flutter_project.podspec'); + expectExists(podspecPath); + final File podspecFile = fs.file(fs.path.join(projectDir.path, podspecPath)); + final String podspec = podspecFile.readAsStringSync(); + expect(podspec, contains('Flutter module - flutter_project')); + // App identification final String xcodeProjectPath = fs.path.join('.ios', 'Runner.xcodeproj', 'project.pbxproj'); expectExists(xcodeProjectPath);
diff --git a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart index b560538..ec81949 100644 --- a/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/xcodeproj_test.dart
@@ -304,6 +304,12 @@ final String contents = config.readAsStringSync(); expect(contents.contains('ARCHS=armv7'), isTrue); + + final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh'); + expect(buildPhaseScript.existsSync(), isTrue); + + final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync(); + expect(buildPhaseScriptContents.contains('ARCHS=armv7'), isTrue); }); testUsingOsxContext('sets TRACK_WIDGET_CREATION=true when trackWidgetCreation is true', () async { @@ -322,6 +328,12 @@ final String contents = config.readAsStringSync(); expect(contents.contains('TRACK_WIDGET_CREATION=true'), isTrue); + + final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh'); + expect(buildPhaseScript.existsSync(), isTrue); + + final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync(); + expect(buildPhaseScriptContents.contains('TRACK_WIDGET_CREATION=true'), isTrue); }); testUsingOsxContext('does not set TRACK_WIDGET_CREATION when trackWidgetCreation is false', () async { @@ -340,6 +352,12 @@ final String contents = config.readAsStringSync(); expect(contents.contains('TRACK_WIDGET_CREATION=true'), isFalse); + + final File buildPhaseScript = fs.file('path/to/project/ios/Flutter/flutter_export_environment.sh'); + expect(buildPhaseScript.existsSync(), isTrue); + + final String buildPhaseScriptContents = buildPhaseScript.readAsStringSync(); + expect(buildPhaseScriptContents.contains('TRACK_WIDGET_CREATION=true'), isFalse); }); testUsingOsxContext('sets ARCHS=armv7 when armv7 local engine is set', () async {
diff --git a/packages/flutter_tools/test/general.shard/project_test.dart b/packages/flutter_tools/test/general.shard/project_test.dart index dd800b4..f5b26d1 100644 --- a/packages/flutter_tools/test/general.shard/project_test.dart +++ b/packages/flutter_tools/test/general.shard/project_test.dart
@@ -200,6 +200,8 @@ await project.ensureReadyForPlatformSpecificTooling(); 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')