diff --git a/sky/build/sdk_xcode_harness/.gitignore b/sky/build/sdk_xcode_harness/.gitignore index 59ed186b0fd96..47db68103a55b 100644 --- a/sky/build/sdk_xcode_harness/.gitignore +++ b/sky/build/sdk_xcode_harness/.gitignore @@ -24,3 +24,9 @@ build/ xcuserdata *.moved-aside + +Flutter/app.flx +Flutter/app.so +Flutter/app.zip +Flutter/Flutter.framework +Flutter/Generated.xcconfig diff --git a/sky/build/sdk_xcode_harness/Flutter.xcconfig.tmpl b/sky/build/sdk_xcode_harness/Flutter.xcconfig.tmpl deleted file mode 100644 index 9d0ae1807c8bf..0000000000000 --- a/sky/build/sdk_xcode_harness/Flutter.xcconfig.tmpl +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "Local.xcconfig" - -DART_EXPERIMENTAL_INTERPRETER={{ interpreter }} diff --git a/sky/build/sdk_xcode_harness/Flutter/Flutter.xcconfig b/sky/build/sdk_xcode_harness/Flutter/Flutter.xcconfig new file mode 100644 index 0000000000000..592ceee85b89b --- /dev/null +++ b/sky/build/sdk_xcode_harness/Flutter/Flutter.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/sky/build/sdk_xcode_harness/FlutterApplication.xcodeproj/project.pbxproj b/sky/build/sdk_xcode_harness/FlutterApplication.xcodeproj/project.pbxproj index 5551f3c6dbbf4..27e521ed8f7a2 100644 --- a/sky/build/sdk_xcode_harness/FlutterApplication.xcodeproj/project.pbxproj +++ b/sky/build/sdk_xcode_harness/FlutterApplication.xcodeproj/project.pbxproj @@ -7,11 +7,11 @@ objects = { /* Begin PBXBuildFile section */ - 9707A0011CF50D0600D0751C /* app.so in Frameworks */ = {isa = PBXBuildFile; fileRef = 9707A0001CF50D0600D0751C /* app.so */; }; - 9707A0021CF50D2B00D0751C /* app.so in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9707A0001CF50D0600D0751C /* app.so */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - 977A86B71CF4CD4700432945 /* app.flx in Resources */ = {isa = PBXBuildFile; fileRef = 977A86B51CF4CD4700432945 /* app.flx */; }; - 97950E411CDC05A500964A31 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97F908AF1CDC02C500D4520F /* Flutter.framework */; }; - 97950E421CDC05A500964A31 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 97F908AF1CDC02C500D4520F /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 976042271CFB91C5006EFB43 /* Flutter.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 976042261CFB91C5006EFB43 /* Flutter.xcconfig */; }; + 9760422B1CFB925B006EFB43 /* app.flx in Resources */ = {isa = PBXBuildFile; fileRef = 976042281CFB925B006EFB43 /* app.flx */; }; + 9760422D1CFB925B006EFB43 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9760422A1CFB925B006EFB43 /* Flutter.framework */; }; + 9760422E1CFB92B0006EFB43 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9760422A1CFB925B006EFB43 /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9766DC6F1CFB93D50041C027 /* app.so in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9766DC6D1CFB93C80041C027 /* app.so */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 9E07CFA91BE8280A00BCD8DE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9E07CFA81BE8280A00BCD8DE /* Assets.xcassets */; }; 9E07CFBA1BE82DFF00BCD8DE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E07CF9D1BE8280A00BCD8DE /* main.m */; }; 9EA2FB801C6D2D6B00670B03 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9EA2FB7F1C6D2D6B00670B03 /* LaunchScreen.storyboard */; }; @@ -24,8 +24,8 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 9707A0021CF50D2B00D0751C /* app.so in Embed Frameworks */, - 97950E421CDC05A500964A31 /* Flutter.framework in Embed Frameworks */, + 9766DC6F1CFB93D50041C027 /* app.so in Embed Frameworks */, + 9760422E1CFB92B0006EFB43 /* Flutter.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -33,16 +33,14 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 9707A0001CF50D0600D0751C /* app.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = app.so; path = FlutterApplication/Generated/app.so; sourceTree = ""; }; - 977A86B11CF4C36100432945 /* BuildFlutterApp */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = BuildFlutterApp; sourceTree = ""; }; - 977A86B51CF4CD4700432945 /* app.flx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = app.flx; path = FlutterApplication/Generated/app.flx; sourceTree = ""; }; - 97F908AF1CDC02C500D4520F /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = ../common/Flutter.framework; sourceTree = ""; }; + 976042261CFB91C5006EFB43 /* Flutter.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Flutter.xcconfig; path = Flutter/Flutter.xcconfig; sourceTree = ""; }; + 976042281CFB925B006EFB43 /* app.flx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = app.flx; path = Flutter/app.flx; sourceTree = ""; }; + 9760422A1CFB925B006EFB43 /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 9766DC6D1CFB93C80041C027 /* app.so */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = app.so; path = Flutter/app.so; sourceTree = ""; }; 9E07CF9A1BE8280A00BCD8DE /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9E07CF9D1BE8280A00BCD8DE /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 9E07CFA81BE8280A00BCD8DE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../Assets.xcassets; sourceTree = SOURCE_ROOT; }; 9E07CFAD1BE8280A00BCD8DE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = ../Info.plist; sourceTree = SOURCE_ROOT; }; - 9E40464B1C1B64B500A4B87C /* Flutter.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Flutter.xcconfig; sourceTree = ""; }; - 9E40465E1C1B6F7900A4B87C /* Local.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Local.xcconfig; sourceTree = ""; }; 9EA2FB7F1C6D2D6B00670B03 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ../LaunchScreen.storyboard; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ @@ -51,39 +49,29 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 97950E411CDC05A500964A31 /* Flutter.framework in Frameworks */, - 9707A0011CF50D0600D0751C /* app.so in Frameworks */, + 9760422D1CFB925B006EFB43 /* Flutter.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 977A86B21CF4CCF700432945 /* FlutterApplication */ = { + 976042251CFB918B006EFB43 /* Flutter */ = { isa = PBXGroup; children = ( - 977A86B31CF4CD0200432945 /* Generated */, + 9766DC6D1CFB93C80041C027 /* app.so */, + 976042281CFB925B006EFB43 /* app.flx */, + 9760422A1CFB925B006EFB43 /* Flutter.framework */, + 976042261CFB91C5006EFB43 /* Flutter.xcconfig */, ); - name = FlutterApplication; - sourceTree = ""; - }; - 977A86B31CF4CD0200432945 /* Generated */ = { - isa = PBXGroup; - children = ( - 9707A0001CF50D0600D0751C /* app.so */, - 977A86B51CF4CD4700432945 /* app.flx */, - ); - name = Generated; + name = Flutter; sourceTree = ""; }; 9E07CF7C1BE7F4D200BCD8DE = { isa = PBXGroup; children = ( - 977A86B21CF4CCF700432945 /* FlutterApplication */, - 9E40465E1C1B6F7900A4B87C /* Local.xcconfig */, - 9E40464B1C1B64B500A4B87C /* Flutter.xcconfig */, + 976042251CFB918B006EFB43 /* Flutter */, 9E07CF9B1BE8280A00BCD8DE /* Runner */, - 9E40462C1C1B617500A4B87C /* Tools */, 9E07CF871BE7F4D200BCD8DE /* Products */, ); sourceTree = ""; @@ -115,23 +103,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 9E40462C1C1B617500A4B87C /* Tools */ = { - isa = PBXGroup; - children = ( - 9E40464F1C1B6A3600A4B87C /* common */, - ); - path = Tools; - sourceTree = ""; - }; - 9E40464F1C1B6A3600A4B87C /* common */ = { - isa = PBXGroup; - children = ( - 97F908AF1CDC02C500D4520F /* Flutter.framework */, - 977A86B11CF4C36100432945 /* BuildFlutterApp */, - ); - path = common; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -193,7 +164,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 977A86B71CF4CD4700432945 /* app.flx in Resources */, + 9760422B1CFB925B006EFB43 /* app.flx in Resources */, + 976042271CFB91C5006EFB43 /* Flutter.xcconfig in Resources */, 9EA2FB801C6D2D6B00670B03 /* LaunchScreen.storyboard in Resources */, 9E07CFA91BE8280A00BCD8DE /* Assets.xcassets in Resources */, ); @@ -213,7 +185,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh ${SOURCE_ROOT}/Tools/common/BuildFlutterApp ${FLUTTER_APPLICATION_PATH}"; + shellScript = "/bin/sh $FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh"; }; 9E046CD71C9CA1AC00A1E391 /* Copy Extra Assets */ = { isa = PBXShellScriptBuildPhase; @@ -261,7 +233,7 @@ /* Begin XCBuildConfiguration section */ 9E07CF8C1BE7F4D200BCD8DE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9E40464B1C1B64B500A4B87C /* Flutter.xcconfig */; + baseConfigurationReference = 976042261CFB91C5006EFB43 /* Flutter.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; @@ -310,7 +282,7 @@ }; 9E07CF8D1BE7F4D200BCD8DE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9E40464B1C1B64B500A4B87C /* Flutter.xcconfig */; + baseConfigurationReference = 976042261CFB91C5006EFB43 /* Flutter.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; @@ -355,11 +327,13 @@ }; 9E07CFAE1BE8280A00BCD8DE /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 976042261CFB91C5006EFB43 /* Flutter.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Tools/common", + "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = ../Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -367,6 +341,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/FlutterApplication/Generated", + "$(PROJECT_DIR)/Flutter", ); PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -374,11 +349,13 @@ }; 9E07CFAF1BE8280A00BCD8DE /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 976042261CFB91C5006EFB43 /* Flutter.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Tools/common", + "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = ../Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.0; @@ -386,6 +363,7 @@ LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/FlutterApplication/Generated", + "$(PROJECT_DIR)/Flutter", ); PRODUCT_NAME = "$(TARGET_NAME)"; }; diff --git a/sky/build/sdk_xcode_harness/FlutterApplication/.gitignore b/sky/build/sdk_xcode_harness/FlutterApplication/.gitignore deleted file mode 100644 index 673b74ec78e06..0000000000000 --- a/sky/build/sdk_xcode_harness/FlutterApplication/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Generated/ diff --git a/sky/build/sdk_xcode_harness/Local.xcconfig.tmpl b/sky/build/sdk_xcode_harness/Local.xcconfig.tmpl deleted file mode 100644 index 28ea34d1ac168..0000000000000 --- a/sky/build/sdk_xcode_harness/Local.xcconfig.tmpl +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This file is overwritten by `flutter tools`. - -LOCAL_ENGINE={{ local_engine }} - -DART_SDK_PATH=/path/to/dart/sdk -FLUTTER_APPLICATION_PATH=path/to/flutter/application -FLUTTER_ROOT=/path/to/flutter/root diff --git a/sky/build/sdk_xcode_harness/Tools/common/BuildFlutterApp b/sky/build/sdk_xcode_harness/Tools/common/BuildFlutterApp deleted file mode 100644 index 29a4fdd9fe7c0..0000000000000 --- a/sky/build/sdk_xcode_harness/Tools/common/BuildFlutterApp +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/sh -# Copyright 2016 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -RunCommand() { - echo "♦ " $@ - $@ - return $? -} - -EchoError() { - echo "$@" 1>&2 -} - -AssertExists() { - RunCommand ls $1 - if [ $? -ne 0 ]; then - EchoError "The path $1 does not exist" - exit -1 - fi - return 0 -} - -BuildApp() { - # Check that the project path was specified - if [[ -z "$1" ]]; then - EchoError "Project path not specified" - exit -1 - fi - - AssertExists $1 - local project_path=$1 - - local derived_dir=${SOURCE_ROOT}/FlutterApplication/Generated - RunCommand mkdir -p $derived_dir - AssertExists $derived_dir - - RunCommand rm -f ${derived_dir}/app.so - RunCommand rm -f ${derived_dir}/app.flx - - RunCommand pushd ${project_path} - - local local_engine_flag="" - if [[ -n "$LOCAL_ENGINE" ]]; then - local_engine_flag="--local-engine=$LOCAL_ENGINE" - fi - - if [[ $CURRENT_ARCH != "x86_64" ]]; then - local interpreter_flag="--interpreter" - if [[ "$DART_EXPERIMENTAL_INTERPRETER" != "1" ]]; then - interpreter_flag="" - fi - - RunCommand ${FLUTTER_ROOT}/bin/flutter --suppress-analytics build aot \ - --target-platform=ios \ - --release \ - --output-dir=${derived_dir} \ - ${interpreter_flag} \ - ${local_engine_flag} - - if [[ $? -ne 0 ]]; then - EchoError "Failed to build $1." - exit -1 - fi - else - RunCommand eval "$(echo \"static const int Moo = 88;\" | xcrun clang -x c --shared -o ${derived_dir}/app.so -)" - fi - - local precompilation_flag="" - if [[ $CURRENT_ARCH != "x86_64" ]] && [[ "$DART_EXPERIMENTAL_INTERPRETER" != "1" ]]; then - precompilation_flag="--precompiled" - fi - - RunCommand ${FLUTTER_ROOT}/bin/flutter --suppress-analytics build flx \ - --output-file=${derived_dir}/app.flx \ - ${precompilation_flag} \ - ${local_engine_flag} \ - - if [[ $? -ne 0 ]]; then - EchoError "Failed to package $1." - exit -1 - fi - - RunCommand popd - - echo "Project $1 built and packaged successfully." - return 0 -} - -BuildApp $1 diff --git a/sky/build/sky_ios_sdk.gni b/sky/build/sky_ios_sdk.gni index 44dd266a47ca1..697bfd11ab281 100644 --- a/sky/build/sky_ios_sdk.gni +++ b/sky/build/sky_ios_sdk.gni @@ -13,40 +13,10 @@ template("sky_ios_sdk") { sdk_name = invoker.sdk_name sdk_dir = "$root_out_dir/$sdk_name" - tools_dir = "Tools/common" - - action("copy_flutter_framework") { - stamp_file = "$root_build_dir/copy_flutter_framework.stamp" - script = "//sky/tools/copy_dir.py" - - inputs = [ "$root_build_dir/Flutter.framework/Flutter" ] - outputs = [ - "$sdk_dir", - "$sdk_dir/$tools_dir/Flutter.framework/Flutter" - ] - - args = [ - "--src", - rebase_path("$root_build_dir/Flutter.framework"), - "--dst", - rebase_path("$sdk_dir/$tools_dir/Flutter.framework"), - "--stamp", - rebase_path(stamp_file), - ] - - deps = [ "//sky/shell:flutter_framework" ] - } - - copy("ios_xcode_scripts") { - sources = [ - "//sky/build/sdk_xcode_harness/$tools_dir/BuildFlutterApp", - ] - outputs = [ "$sdk_dir/$tools_dir/{{source_file_part}}" ] - } copy("copy_sdk_xcode_harness") { sources = [ - "//sky/build/sdk_xcode_harness/FlutterApplication", + "//sky/build/sdk_xcode_harness/Flutter", "//sky/build/sdk_xcode_harness/FlutterApplication.xcodeproj", "//sky/build/sdk_xcode_harness/Runner", ] @@ -54,33 +24,6 @@ template("sky_ios_sdk") { outputs = [ "$sdk_dir/{{source_file_part}}" ] } - render_template("flutter_xcconfig") { - template = "//sky/build/sdk_xcode_harness/Flutter.xcconfig.tmpl" - output = "$sdk_dir/Flutter.xcconfig" - stamp_file = "$root_build_dir/expand_flutter_xcconfig.stamp" - - variables = [ - "interpreter" - ] - - if (dart_experimental_interpreter) { - variables += [ "1" ] - } else { - variables += [ "0" ] - } - } - - render_template("local_xcconfig") { - template = "//sky/build/sdk_xcode_harness/Local.xcconfig.tmpl" - output = "$sdk_dir/Local.xcconfig" - stamp_file = "$root_build_dir/expand_local_xcconfig.stamp" - - variables = [ - "local_engine", - rebase_path(root_build_dir, ""), - ] - } - # All user editable files are copied to the out directory so that developers # tinkering on the engine still have a fully functional project harness copy("copy_user_editable_files") { @@ -92,38 +35,10 @@ template("sky_ios_sdk") { outputs = [ "$root_out_dir/{{source_file_part}}" ] } - # This archive is only for local consumption by the tools. It is not suitable - # for distribution since it only contains artifacts for a single architecture. - # It is the responsibility of the buildbot to construct universal binaries - # to create an SDK archive suitable for distribution. - action("create_sdk_archive") { - script = "//sky/build/zip_directory.py" - - archive_name = "FlutterXcode.zip" - - sources = [ sdk_dir ] - outputs = [ "$root_out_dir/$archive_name" ] - - args = [ - "--input-directory", - rebase_path(sdk_dir, root_build_dir), - "--output-archive", - rebase_path("$root_out_dir/$archive_name", root_build_dir), - ] - + group(target_name) { deps = [ - ":copy_flutter_framework", ":copy_sdk_xcode_harness", ":copy_user_editable_files", - ":flutter_xcconfig", - ":ios_xcode_scripts", - ":local_xcconfig", - ] - } - - group(target_name) { - deps = [ - ":create_sdk_archive", ] } } diff --git a/sky/tools/create_ios_framework.py b/sky/tools/create_ios_framework.py new file mode 100755 index 0000000000000..8651982cc5f7d --- /dev/null +++ b/sky/tools/create_ios_framework.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# Copyright 2016 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import argparse +import subprocess +import shutil +import sys +import os + + +def main(): + parser = argparse.ArgumentParser(description='Creates Flutter.framework') + + parser.add_argument('--dst', type=str, required=True) + parser.add_argument('--device-out-dir', type=str, required=True) + parser.add_argument('--simulator-out-dir', type=str, required=True) + + args = parser.parse_args() + + fat_framework = os.path.join(args.dst, 'Flutter.framework') + device_framework = os.path.join(args.device_out_dir, 'Flutter.framework') + simulator_framework = os.path.join(args.simulator_out_dir, 'Flutter.framework') + + device_dylib = os.path.join(device_framework, 'Flutter') + simulator_dylib = os.path.join(simulator_framework, 'Flutter') + + if not os.path.isdir(device_framework): + print 'Cannot find iOS device Framework at', device_framework + return 1 + + if not os.path.isdir(simulator_framework): + print 'Cannot find iOS simulator Framework at', simulator_framework + return 1 + + if not os.path.isfile(device_dylib): + print 'Cannot find iOS device dylib at', device_dylib + return 1 + + if not os.path.isfile(simulator_dylib): + print 'Cannot find iOS simulator dylib at', simulator_dylib + return 1 + + shutil.rmtree(fat_framework, True) + shutil.copytree(device_framework, fat_framework) + + subprocess.call([ + 'lipo', + device_dylib, + simulator_dylib, + '-create', + '-output', + os.path.join(fat_framework, 'Flutter') + ]) + + +if __name__ == '__main__': + sys.exit(main())