Adding a package to two targets in one projects results in an error

I upgrade to Xcode 11.4 and now I am getting an error in a project that has one package used by two targets in the same project. The error I get is:

Swift package product 'x' is linked as a static library by 'y' and 'z'. This will result in duplication of library code.

This worked fine in Xcode 11.3. Any ideas?

1 Like

It depends on your concrete scenario, this diagnostic is new in 11.4, that's why you did not see it in 11.3.

If an app and an embedded app extension or helper tool statically link the same package product, this error will incorrectly be emitted. In this case, you can set the DISABLE_DIAMOND_PROBLEM_DIAGNOSTIC build setting to YES in your app target to disable this diagnostic.

When a binary (such as an app or a framework) uses a statically linked package product, the code from the library is copied into the binary. At runtime, there can be only one copy of the code in each process, so if multiple binaries that will loaded into the same process use the same statically linked package product, this diagnostic is correct and should not be disabled. In this case, restructure your project to use the package product in only one binary, or change the type of the library product to dynamic in its package manifest.

2 Likes

I have a similar post about this problem. In short, my two targets are an iOS app and an iMessage extension embedded inside of it. They run as separate processes AFAICT. I initially thought that DISABLE_DIAMOND_PROBLEM_DIAGNOSTIC wasn’t working, but then I realized I had added it to an xcconfig file that wasn't actually getting used; with this (correctly) set to YES, my project builds again.

Where should this be set?

As a custom build setting (or in an enabled xcconfig file).

Here is my solution to the problem:

Just in case someone else finds this and has trouble, the problem is that Xcode 11.4 is checking for duplicate static libraries and sometimes incorrectly assumes using the same library in two independent targets will cause duplicate symbols.

This can be disabled by adding a custom build setting to the project with the build setting of DISABLE_DIAMOND_PROBLEM_DIAGNOSTIC = 1. In Xcode project settings, go to Build Settings, click the +, and add a custom setting of DISABLE_DIAMOND_PROBLEM_DIAGNOSTIC and set the value to 1.

Thank you all for your help.

2 Likes

Why do you think this is "incorrectly"? Two of your packages will embed the code from the static library, and you will indeed have duplicate symbols. I linked a solution I use above which offloads the whole linking resolution completely to SPM. It won't be the perfect solution for everyone due to some missing SPM features such as package resources, etc., but it's a good workaround that avoids DISABLE_DIAMOND_PROBLEM_DIAGNOSTIC, which I consider as wrong solution anyway.

It's incorrect because the package is linked to two separate executables, there's no chance there will be duplicate symbols. This is the project structure, and I do not want to use dynamic libraries.

Target A: A command line program
Target B: A XPC service
Target C: A SwiftUI application using the XPC service

Targets A and B use the same package, a set of "helper" Swift files.

Target A is used by Target B, and Target B is used by Target C. They are all separate processes, all linked independently. There is no reason whatsoever for Xcode to detect these as duplicate linking and fail the build.

1 Like

Yeah I got the same "Problem". It's not a duplicated symbol warning. It's a duplicated code warning and it's fair enough. You could link all this with a dynamic framework and the specific search pathes.

The downside is that you need to be in control of all the packages to make dynamic linking possible :/

Yes. This is BUG behavior and assume Targets in one Project should produce same executable. Try do the same framework without SPM, which does not show any error. Just Xcode team’s issue with SPM integration

DISABLE_DIAMOND_PROBLEM_DIAGNOSTIC = YES

worked for me, and now I can run my iOS app. However my mac catalyst app still won't compile:

multiple configured targets of 'x' are being created for macOS

This might be a known issue, do you have any iOS-only target dependencies by any chance?

If that's the case, I'm afraid there is no good workaround for this issue, the only thing you could do would be temporarily removing that dependency while building for catalyst.

I have an iOS only iMessage app. But both my swift packages are iOS + macOS.

Terms of Service

Privacy Policy

Cookie Policy