Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple commands produce '/build/ios/Debug-iphonesimulator/Runner.app/Frameworks/Flutter.framework #20685

Closed
sidealice opened this issue Aug 16, 2018 · 47 comments

Comments

@sidealice
Copy link

commented Aug 16, 2018

When I want to debug the application in MacOs environment, it throw such error:

Multiple commands produce '/build/ios/Debug-iphonesimulator/Runner.app/Frameworks/Flutter.framework

  1. Target 'Runner' has copy command from '/ios/Flutter/Flutter.framework' to '/build/ios/Debug-iphonesimulator/Runner.app/Frameworks/Flutter.framework'
  2. That command depends on command in Target 'Runner': script phase “[CP] Embed Pods Frameworks”
    warning: ignoring duplicated output file: '//build/ios/Debug-iphonesimulator/Runner.app/Frameworks/Flutter.framework' (in target 'Runner')
    note: Using new build systemnote: Planning buildnote: Constructing build description

Mac 10.14 Beta
Xcode 10 beta

How to fix it? Thanks a lot

@zoechi

This comment has been minimized.

Copy link
Contributor

commented Aug 16, 2018

Can you please provide exact steps how to reproduce?
How did you create the project?
What files did you change, what changes did you make?

Please add the output of flutter doctor -v.

@gi097

This comment has been minimized.

Copy link

commented Aug 16, 2018

I was able to fix it by opening the Runner workspace project in Xcode 10. Then navigate to File, Workspace Settings and change the build system to Legacy Build System.

schermafbeelding 2018-08-16 om 14 10 10

@sidealice

This comment has been minimized.

Copy link
Author

commented Aug 16, 2018

thanks a lot! it works.

@cbracken

This comment has been minimized.

Copy link
Member

commented Sep 14, 2018

Affected projects

This issue affects all Flutter projects built using Xcode 10 that have a dependency on CocoaPods -- typically this means those that rely on plugins.

Workarounds

There are two workarounds:

  • Option 1: Use the legacy build system . As noted by @gi097, open ios/Runner.xcworkspace, and change the build system to Legacy Build System.
  • Option 2: Use the new Xcode 10 build system.
    1. Open ios/Runner.xcworkspace
    2. Select the Runner project in the project navigator sidebar.
    3. In the main view, select the Runner target, then select the Build Phases tab.
    4. Expand the Embed Frameworks phase and select Flutter.framework from the embedded frameworks list.
    5. Click - to remove Flutter.framework from the list (be sure to keep App.framework).

Root cause

When plugins are in use, there are two competing build actions that copy Flutter.framework into the build application Frameworks directory:

  1. The Embed Frameworks build phase for the Runner project
  2. The [CP] Embed Pods Frameworks build phase that pod install creates in the project.

Item (1) is there to ensure the framework is copied into the built app in the case where there are no plugins (and therefore no CocoaPods integration in the Xcode project). Item (2) is there because Flutter's podspec declares Flutter.framework as a vended_framework, and CocoaPods automatically adds a copy step for each such vended_framework in the transitive closure of CocoaPods dependencies.

Immediate fix

The immediate fix is for us to find a way to automatically opt back in to the legacy build fix until a longer-term better solution is in place. Previous betas supported -useNewBuildSystem=NO or -useModernBuildSystem=NO but looks like this is removed in the GM build. Looks like currently the way to do this is to add a key-value pair (<key>BuildSystemType</key><string>Original</string>) to ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings.

Longer-term fix

The simplest option would be to eliminate Flutter.framework from the Embed Frameworks step above and always rely on pod install, even in the case where there are no plugin dependencies. We'd need to update Flutter tool to automatically edit existing projects to remove Flutter.framework from the Embed Frameworks step.

pro: simpler code. con: makes cocoapods a required install step for Flutter development, first run involves a huge and very slow download of their repo.

A slightly nicer option would be for us to automatically detect whether the project uses plugins or not, and edit the Xcode project to check for and remove Flutter.framework from the Embed Frameworks step automatically if plugins are in use or add it if not.

pro: better user experience. con: more complex code.

Either way, we need some mechanism to automatically edit the project.pbxproj file and remove the framework from the embed frameworks build step. Supporting adding it back in isn't much incremental work and results in a better experience.

/cc @tvolkert @gspencergoog @dnfield

cbracken added a commit to cbracken/flutter that referenced this issue Sep 15, 2018

Use Xcode legacy build system for iOS builds
Xcode 10 introduces a new build system which includes stricter checks on
duplicate build outputs.

When plugins are in use, there are two competing build actions that copy
Flutter.framework into the build application Frameworks directory:

  1. The Embed Frameworks build phase for the Runner project
  2. The [CP] Embed Pods Frameworks build phase that pod install creates
     in the project.

Item (1) is there to ensure the framework is copied into the built app
in the case where there are no plugins (and therefore no CocoaPods
integration in the Xcode project). Item (2) is there because Flutter's
podspec declares Flutter.framework as a vended_framework, and CocoaPods
automatically adds a copy step for each such vended_framework in the
transitive closure of CocoaPods dependencies.

As an immediate fix, we opt back into the build system used by Xcode 9
and earlier. Longer term, we need to update our templates and
flutter_tools to correctly handle this situation.

See: flutter#20685

cbracken added a commit to cbracken/flutter that referenced this issue Sep 15, 2018

Use Xcode legacy build system for iOS builds
Xcode 10 introduces a new build system which includes stricter checks on
duplicate build outputs.

When plugins are in use, there are two competing build actions that copy
Flutter.framework into the build application Frameworks directory:

  1. The Embed Frameworks build phase for the Runner project
  2. The [CP] Embed Pods Frameworks build phase that pod install creates
     in the project.

Item (1) is there to ensure the framework is copied into the built app
in the case where there are no plugins (and therefore no CocoaPods
integration in the Xcode project). Item (2) is there because Flutter's
podspec declares Flutter.framework as a vended_framework, and CocoaPods
automatically adds a copy step for each such vended_framework in the
transitive closure of CocoaPods dependencies.

As an immediate fix, we opt back into the build system used by Xcode 9
and earlier. Longer term, we need to update our templates and
flutter_tools to correctly handle this situation.

See: flutter#20685

cbracken added a commit to cbracken/flutter that referenced this issue Sep 17, 2018

Use Xcode legacy build system for iOS builds
Xcode 10 introduces a new build system which includes stricter checks on
duplicate build outputs.

When plugins are in use, there are two competing build actions that copy
Flutter.framework into the build application Frameworks directory:

  1. The Embed Frameworks build phase for the Runner project
  2. The [CP] Embed Pods Frameworks build phase that pod install creates
     in the project.

Item (1) is there to ensure the framework is copied into the built app
in the case where there are no plugins (and therefore no CocoaPods
integration in the Xcode project). Item (2) is there because Flutter's
podspec declares Flutter.framework as a vended_framework, and CocoaPods
automatically adds a copy step for each such vended_framework in the
transitive closure of CocoaPods dependencies.

As an immediate fix, we opt back into the build system used by Xcode 9
and earlier. Longer term, we need to update our templates and
flutter_tools to correctly handle this situation.

See: flutter#20685

cbracken added a commit to cbracken/flutter that referenced this issue Sep 17, 2018

Use Xcode legacy build system for iOS builds
Xcode 10 introduces a new build system which includes stricter checks on
duplicate build outputs.

When plugins are in use, there are two competing build actions that copy
Flutter.framework into the build application Frameworks directory:

  1. The Embed Frameworks build phase for the Runner project
  2. The [CP] Embed Pods Frameworks build phase that pod install creates
     in the project.

Item (1) is there to ensure the framework is copied into the built app
in the case where there are no plugins (and therefore no CocoaPods
integration in the Xcode project). Item (2) is there because Flutter's
podspec declares Flutter.framework as a vended_framework, and CocoaPods
automatically adds a copy step for each such vended_framework in the
transitive closure of CocoaPods dependencies.

As an immediate fix, we opt back into the build system used by Xcode 9
and earlier. Longer term, we need to update our templates and
flutter_tools to correctly handle this situation.

See: flutter#20685

cbracken added a commit to cbracken/flutter that referenced this issue Sep 17, 2018

Use Xcode legacy build system for iOS builds
Xcode 10 introduces a new build system which includes stricter checks on
duplicate build outputs.

When plugins are in use, there are two competing build actions that copy
Flutter.framework into the build application Frameworks directory:

  1. The Embed Frameworks build phase for the Runner project
  2. The [CP] Embed Pods Frameworks build phase that pod install creates
     in the project.

Item (1) is there to ensure the framework is copied into the built app
in the case where there are no plugins (and therefore no CocoaPods
integration in the Xcode project). Item (2) is there because Flutter's
podspec declares Flutter.framework as a vended_framework, and CocoaPods
automatically adds a copy step for each such vended_framework in the
transitive closure of CocoaPods dependencies.

As an immediate fix, we opt back into the build system used by Xcode 9
and earlier. Longer term, we need to update our templates and
flutter_tools to correctly handle this situation.

See: flutter#20685

cbracken added a commit that referenced this issue Sep 18, 2018

Use Xcode legacy build system for iOS builds (#21901)
Xcode 10 introduces a new build system which includes stricter checks on
duplicate build outputs.

When plugins are in use, there are two competing build actions that copy
Flutter.framework into the build application Frameworks directory:

  1. The Embed Frameworks build phase for the Runner project
  2. The [CP] Embed Pods Frameworks build phase that pod install creates
     in the project.

Item (1) is there to ensure the framework is copied into the built app
in the case where there are no plugins (and therefore no CocoaPods
integration in the Xcode project). Item (2) is there because Flutter's
podspec declares Flutter.framework as a vended_framework, and CocoaPods
automatically adds a copy step for each such vended_framework in the
transitive closure of CocoaPods dependencies.

As an immediate fix, we opt back into the build system used by Xcode 9
and earlier. Longer term, we need to update our templates and
flutter_tools to correctly handle this situation.

See: #20685
@hungrymonkey

This comment was marked as resolved.

Copy link

commented Sep 18, 2018

Sorry, I didn't intent to flood your issue tracker.

@tiagosito

This comment has been minimized.

Copy link

commented Sep 18, 2018

I followed this resolution #20685

but now it results in the following error

captura de tela 2018-09-18 as 10 06 38 am

@tiagosito

This comment has been minimized.

Copy link

commented Sep 18, 2018

Anyone have any idea how to solve this?
@gi097 @cbracken @zoechi @sidealice @hungrymonkey

@cbracken

This comment has been minimized.

Copy link
Member

commented Sep 18, 2018

@tiagosito A patch will be landing momentarily on the master branch. For the time being see the workarounds listed in my comment above.

cbracken added a commit to cbracken/flutter that referenced this issue Sep 18, 2018

Use Xcode legacy build system for iOS builds (flutter#21901)
Xcode 10 introduces a new build system which includes stricter checks on
duplicate build outputs.

When plugins are in use, there are two competing build actions that copy
Flutter.framework into the build application Frameworks directory:

  1. The Embed Frameworks build phase for the Runner project
  2. The [CP] Embed Pods Frameworks build phase that pod install creates
     in the project.

Item (1) is there to ensure the framework is copied into the built app
in the case where there are no plugins (and therefore no CocoaPods
integration in the Xcode project). Item (2) is there because Flutter's
podspec declares Flutter.framework as a vended_framework, and CocoaPods
automatically adds a copy step for each such vended_framework in the
transitive closure of CocoaPods dependencies.

As an immediate fix, we opt back into the build system used by Xcode 9
and earlier. Longer term, we need to update our templates and
flutter_tools to correctly handle this situation.

See: flutter#20685

@Hixie Hixie modified the milestones: Goals, June 2019 May 28, 2019

@tvolkert tvolkert assigned jmagman and unassigned tvolkert May 29, 2019

@jmagman

This comment has been minimized.

Copy link
Member

commented May 30, 2019

We can also leverage the CocoaPods installation option disable_input_output_paths, which removes the input and output files from the [CP] Emded Pods Framework build phase. That installation option was added because the new Xcode build system failed to run the script even when the input files were touched. See https://www.ralfebert.de/ios/blog/cocoapods-clean-input-output-files.

Pros:

  • Xcode projects will use the new build system without compilation errors. Xcode has been threatening to yank legacy build support, so Flutter will be ready when that happens.
  • Simple fix.
  • No additional logic to decide whether to include Flutter.framework in the Embed Frameworks build phase since it will always be included.
  • Will not require CocoaPods to become a dependency if project is vanilla Flutter without packages.

Cons:

  • The Pods-Runner-frameworks.sh script will run on every build, even when Flutter.framework does not change. On my 2018 MacBook Pro this adds ~1 second to the build.
  • If the new Xcode build system bug is addressed, CocoaPods may remove that installation option and the duplicate framework copies issue will reassert itself.
  • Minimum CocoaPods version will need to increase from 1.0.0 to 1.6.0 when the disable_input_output_paths option was introduced.
@cbracken

This comment has been minimized.

Copy link
Member

commented May 30, 2019

@jmagman Awesome! This approach looks good to me. If we get to the point where we're seeing plugin Cocoapods that are really expensive to compile, we can deal with that as an optimisation. This solves the immediate risk in the meantime!

@houqinzhe

This comment has been minimized.

Copy link

commented Jun 25, 2019

thanks!!!!!

@MashirosBaumkuchen

This comment has been minimized.

Copy link

commented Jun 25, 2019

thanks

@jmagman

This comment has been minimized.

Copy link
Member

commented Jul 9, 2019

If you're still seeing this error, you will need to migrate your Xcode project:

  1. File > Workspace Settings... > Build System, change dropdown to New Build System (Default)
  2. In your Podfile, add the line
install! 'cocoapods', :disable_input_output_paths => true

See https://github.com/flutter/flutter/blob/master/examples/platform_view/ios/Podfile for example.
3. In the Runner target "[CP] Embed Pods Framework" Build Phase, remove all Output Files.

@sceee

This comment has been minimized.

Copy link

commented Jul 9, 2019

@jmagman thanks - but could this be related to #18673? Because after migrating (via flutter upgrade, which performed this change on my machine automatically in the Podfile), I can build using flutter build ios but when trying to Archive in Xcode, I run in the error of #18673.

@sceee

This comment has been minimized.

Copy link

commented Jul 9, 2019

@jmagman thanks - but could this be related to #18673? Because after migrating (via flutter upgrade, which performed this change on my machine automatically in the Podfile), I can build using flutter build ios but when trying to Archive in Xcode, I run in the error of #18673.

@jmagman I found the solution, actually this #16246 (comment) solved my issue. Sorry for any inconvenience.

@JaredEzz

This comment has been minimized.

Copy link

commented Jul 10, 2019

@jmagman For those of us less familiar with XCode, could you explain step 3 further? Where is the Runner target "[CP] Embed Pods Framework" Build Phase found to remove all Output Files?

@JaredEzz

This comment has been minimized.

Copy link

commented Jul 10, 2019

Found it. Click “Runner” in the left navigation bar, then the “Build Phases” tab, then scroll down to “Output Files”, select all of them, then click the subtract button to remove them

@gincos

This comment has been minimized.

Copy link

commented Jul 10, 2019

How can I solve this without a Mac? I use a cloud pipeline to build for iOS but need to solve this problem...

@jmagman

This comment has been minimized.

Copy link
Member

commented Jul 10, 2019

If you're still seeing this error, you will need to migrate your Xcode project:

  1. File > Workspace Settings... > Build System, change dropdown to New Build System (Default)
  2. In your Podfile, add the line
install! 'cocoapods', :disable_input_output_paths => true

See https://github.com/flutter/flutter/blob/master/examples/platform_view/ios/Podfile for example.
3. In the Runner target "[CP] Embed Pods Framework" Build Phase, remove all Output Files.

Or you can do #1 and #2, then run pod install from the ios directory, and CocoaPods should remove that Output file in the build phase automatically.

@gincos If you don't have a Mac you can look at PR #33684 for an example of how to tweak the Xcode files manually. If you have a Mac, please follow the above steps instead!

  1. Delete the file ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings. This is what's happening under the covers with File > Workspace Settings... > Build System > New Build System (Default).
    https://github.com/flutter/flutter/pull/33684/files#diff-e7ad834b29956b3cbd9225dc81f2c06a
  2. In your Podfile, add the line
install! 'cocoapods', :disable_input_output_paths => true

https://github.com/flutter/flutter/pull/33684/files#diff-4e7de62cf4dff9802f06b7f3cb120939

Hopefully your cloud pipeline should run pod install and take care of #3 above for you.

If you are still seeing the error, you can edit ios/Runner.xcodeproj/project.pbxproj to remove the output file manually. Please be careful doing this! The Xcode project file does not take kindly to corruption.
https://github.com/flutter/flutter/pull/33684/files#diff-e9e57f7f2e911a135acd8f08e79b20e1

@gincos

This comment has been minimized.

Copy link

commented Jul 11, 2019

@jmagman Thanks! This worked like a charm! Yes, the cloud provider runs pod install and now it's producing a correct artifact for both Android and iOS in the latest Beta.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.