Swift package with resources in iOS project won't compile test targets

I'm cross posting this here (I originally posted this in the Apple Developer forums a few days ago), in the hopes of finding someone else who knows more than I, and can either confirm my suspicions, or help find a workaround.

I've been trying to convert a set of app and library projects to use swift packages for dependencies (previously used Carthage), and I've run into an issue where Xcode is throwing me a diagnostic for "Unexpected duplicate tasks".

The setup:

  • A dynamic library package which includes some file resources (not any special resources like asset catalogs or CoreData models). Let's call this LibA.
  • A second dynamic library, containing test utilities, which depends on LibA. Let's call this one LibB.
  • An iOS app project, where the app target depends on LibA, and the unit test target depends on LibB, and transitively through LibB, depends on LibA.

The result is Xcode will compile the app target, but when compiling the unit test target, fails with the diagnostic:

Unexpected duplicate tasks:

1) Target 'TestPMAppTests' (project 'TestPMApp') has copy command from '/Users/someone/Library/Developer/Xcode/DerivedData/TestPMApp-bsobwbvrasoqbtejzhodakcdkqqu/Build/Products/Debug-iphonesimulator/liba_liba.bundle' to '/Users/someone/Library/Developer/Xcode/DerivedData/TestPMApp-bsobwbvrasoqbtejzhodakcdkqqu/Build/Products/Debug-iphonesimulator/TestPMApp.app/PlugIns/TestPMAppTests.xctest/liba_liba.bundle'

2) Target 'TestPMAppTests' (project 'TestPMApp') has copy command from '/Users/someone/Library/Developer/Xcode/DerivedData/TestPMApp-bsobwbvrasoqbtejzhodakcdkqqu/Build/Products/Debug-iphonesimulator/liba_liba.bundle' to '/Users/someone/Library/Developer/Xcode/DerivedData/TestPMApp-bsobwbvrasoqbtejzhodakcdkqqu/Build/Products/Debug-iphonesimulator/TestPMApp.app/PlugIns/TestPMAppTests.xctest/liba_liba.bundle'

The same diagnostic appears when compiling from the command line using xcodebuild.

Is this something that is expected behaviour here, or is this a bug in the implementation of Swift Packages within Xcode/xcodebuild?

Bump. We're seeing the same issues.

I've filed this as [SR-13739] 'Unexpected duplicate tasks' error when using Swift Package with bundle resources linked from a Unit Test Target · Issue #4486 · apple/swift-package-manager · GitHub and rdar://8802612

I also opened a feedback item (FB8751233) back on September 28th for the issue

I ended up opening a DTS incident for this issue, as ~6 weeks have passed since I filed the feedback assistant bug. During that time there have been a few beta releases of Xcode, and no progress has been made, and there have been no responses to my bug report.

The response I received on the DTS indicated that this was a bug, and suggested that I open a bug in the feedback assistant, and leave a comment on the feedback item requesting updates to the bug's status.

For anyone else who stumbles across this post while researching this issue, I'd encourage you to also file a bug via feedback assistant to help this issue gain visibility at Apple. Feel free to reference the issue I've filed to help link them together (FB8751233), along with the bug and radar that @clausjoergensen opened: https://bugs.swift.org/browse/SR-13739 and rdar://8802612.

1 Like

Still an issue with Xcode 12.3 RC. Hopefully this gets resolved sooner rather than later.

I forgot to post that I also filed a feedback - FB8893830 - for this.

Still an issue in Xcode 12.4 RC. I'm beginning to think we may not see a fix for this until Xcode 13 :disappointed:

Still an issue with Xcode 12.5 Beta 1.

Now I'm getting this bug when just trying to build a project in Xcode 12.5 beta that was building perfectly fine in Xcode 12.4. If we try to link one local Swift package, which is also linked by another local package, then it breaks with this "Unexpected duplicate tasks" error:

  1. Target 'REDACTED' (project 'REDACTED') has copy command from '/Users/REDACTED/code/ios/DerivedData/REDACTED/Build/Products/Debug_Testing-iphonesimulator/PackageFrameworks/Session.framework' to '/Users/REDACTED/code/ios/DerivedData/REDACTED/Build/Products/Debug_Testing-iphonesimulator/REDACTED.app/Frameworks/Session.framework'

  2. Target 'REDACTED' (project 'REDACTED') has copy command from '/Users/REDACTED/code/ios/DerivedData/REDACTED/Build/Products/Debug_Testing-iphonesimulator/PackageFrameworks/Session.framework' to '/Users/REDACTED/code/ios/DerivedData/REDACTED/Build/Products/Debug_Testing-iphonesimulator/REDACTED.app/Frameworks/Session.framework'

Target and project are identical for both cases.

I've just started to observe similar issue in our codebase with a REGULAR (non-test) target using Xcode 12.5 Beta 1:

error: Unexpected duplicate tasks:

  1. Target 'App' (project 'App') has copy command from 'DerivedData/APP/Build/Products/Debug-iphonesimulator/PackageFrameworks/Places.framework' to 'DerivedData/APP/Build/Products/Debug-iphonesimulator/APP.app/Frameworks/Places.framework'
  2. Target 'App' (project 'App') has copy command from 'DerivedData/APP/Build/Products/Debug-iphonesimulator/PackageFrameworks/Places.framework' to 'DerivedData/APP/Build/Products/Debug-iphonesimulator/APP.app/Frameworks/Places.framework'

Places is an explicitly dynamic SPM package, requested as a dependency by other SPM package and other (mostly static) internal frameworks, all of them being embed only in the APP target.

Unit tests also link this framework, but even dropping these references from Test targets keeps the issue present – that points to an issue in app dependency tree resolution or so.

Xcode 12.4 works completely fine, it's just Xcode 12.5 Beta 1 where this immediately fails to compile our project, right after hitting the Build action & Build preparation complete logged in the console.

EDIT: Probably same issue as @1oo7 posted right above.

Update: I've also made a

Minimalistic example project triggering the Xcode 12.5 issue

It's geniunely caused by one SPM package linking the other one when both are later linked & embed by the target app – my guess is the depending one (PlacesProviding) also creates a duplicate build plan task to copy the resulting Places.framework (which would be logical in case you target PlacesProviding, but there's no way how to further specify embedding options in the Package.swift file) as much as the target app does.

Besides the mentioned issue, I'm also getting some nice warnings, probably related:

missing creator for mutated node: ('DerivedData/depsissue/Build/Products/Debug/depsissue.app/Contents/Frameworks/Places.framework/Versions/A')

I can confirm this is indeed what's happening.

I've submitted a bug report to Apple with a sample project demonstrating this. (FB9005461)

We also get the following warning:

missing creator for mutated node: ('/Users/REDACTED/code/debug/DuplicationBug/DerivedData/DuplicationBug/Build/Products/Release-iphonesimulator/Debug.app/Frameworks/MyLibrary.framework/MyLibrary')

Frankly, the poor integration between SPM and Xcode has been a constant source of issues for my organization.

Here are the current (as of Xcode 12.4) bugs with SPM and Xcode:

  1. Xcode forces you to embed any dynamic library target from a local Swift package that you link into a framework. Setting it to "do not embed" unlinks it entirely. There are two workarounds—edit the project file in a text editor or delete the entire "embed frameworks" step in Xcode.
  2. Given a Swift package that declares multiple dynamic library targets A and B, where B depends on A, Xcode links them statically instead of dynamically, resulting in build errors when your app tries to link to both targets. While this can be worked around by only linking B to the app, there is no workaround if the Swift package declares dynamic library targets A, B, and C, where B and C both depend on A, and the app needs to link to B and C (because both B and C will now contain a copy of A due to the bug).
  3. Swift Packages that have several remote dependencies often fail to open in Xcode if DerivedData was deleted (i.e. we're on a fresh clone, as would happen on CI). The "package resolution step" fails because evidently SPM does not do a shallow clone of remote dependencies—it does a deep clone, which can take a hell of a long time, causing package resolution to fail. In this case Xcode opens the project but it cannot be built until being closed and reopened. This can also cause xcodebuild to fail, as when running a Carthage bootstrap operation in a project that contains the Nuke dependency (which tries to build its sample app, which uses SPM and has some very large remote package dependency repos; Carthage bootstrap times out because of how long the deep clone takes).
  4. The bug mentioned in this thread now with Xcode 12.5 beta, which makes it seem like SPM integration with Xcode is getting worse instead of better, making it into a liability.

Given the fact that Xcode 12.5 beta STILL doesn't have fixes for issues 1 thru 3, and now we're seeing an even worse issue, it seems to me that Apple is not prioritizing fixing any of these bugs related to using SPM with Xcode. Based on that, it is starting to really seem like a liability for any organization to use Swift Packages for local dependencies (as opposed to using frameworks or libraries declared in Xcode projects).

That really sucks because Xcode projects suck. We're super excited to switch to Swift Packages because Xcode project files are such a constant source of merge conflicts and corruption.

5 Likes

Given this thread has gone without any reaction from the maintainers, I hope you can forgive the ping, @NeoNacho - can we expect these issues to be fixed some time soon, at least the regression from 12.4?

I'd also like to bring up my pet issue of SPM/Xcode of code coverage generation for package targets as described here: RFC: Deprecating generate-xcodeproj - #16 by sjavora (that bug goes back to Xcode 11, by the way).

2 Likes

@username0x0a @1oo7 Xcode 12.5 beta 3 has a new issue for me, but may be related / the same to what you pointed out. (in Xcode 12.4, all works fine)

A dynamic swiftPM package A with a remote dependency B that uses a binary target called C (XCFramework) will give this error.

Unexpected duplicate tasks:
1) Command: ProcessXCFramework A_PATH_TO/SourcePackages/checkouts/PACKAGE_B/C.xcframework ios simulator
2) Command: ProcessXCFramework ProcessXCFramework A_PATH_TO/SourcePackages/checkouts/PACKAGE_B/C.xcframeworkios simulator

Any idea if this is the same issue or a new one? I just filed a bug report.

1 Like

I also ran into this on Xcode 12.5 beta 3. It's definitely a new problem.

I found a workaround (see my post here), but this workaround only works if B is a local package dependency. So you might try making a local copy of B, and instead of using ".binaryTarget", use the suggestion in my post. Alternatively, if B is merely a wrapper for C.xcframework (i.e. B has no source code of its own), then you could put C.xcframework somewhere in the same repo as A, and link to it using the methods mentioned in my post. (If you do the latter, you'll have to make a wrapper around A if you want to link to this from any .xcproj-defined targets).

Let me know if you run into any issues with the workaround.

That being said, I did report some of these concerns to Apple as well, so, hopefully they're able to get it working before 12.5 releases, in which case ideally this workaround won't be necessary.

BTW—I really don't understand why there are so many problems with SPM. Why doesn't xcodebuild treat it just like an xcproj file? It's as if they are handling SPM targets completely differently from how .xcproj targets are handled. They should handle them using the exact same code.

Thank you @1oo7 ! For the folks intrigued, here is my issue with Xcode 12.5 beta 3 GitHub - simonpierreroy/DemoIssue. It will compile in Xcode 12.4, but not 12.5.

Same here for our app that compiles just fine in Xcode 12.4, but fails in 12.5 beta 3 with:

error: Unexpected duplicate tasks:

1) Command: ProcessXCFramework /Users/xxxx/Library/Developer/Xcode/DerivedData/MyApp-aogvoaisydtekoeuqgeskjnliidt/SourcePackages/artifacts/Setapp/Setapp.xcframework ios simulator

2) Command: ProcessXCFramework /Users/xxxx/Library/Developer/Xcode/DerivedData/MyApp-aogvoaisydtekoeuqgeskjnliidt/SourcePackages/artifacts/Setapp/Setapp.xcframework ios simulator

Unfortunately, we cannot talk about unreleased products here which includes whether a known issue will be fixed in the future and when.

Thanks to everyone for their detailed bug reports and example projects on this thread, though.

1 Like

As an update to this, a workaround was identified this morning in the Swift Jira bug, for cases where the duplicate task error is caused by having the SPM dependency with resources linked to both an app target and a unit testing target that depends on the app target.