Hive Hive
Sign in

When using cached xcframeworks for SPM packages, nested packages don’t respect product type of their parent.

GitHub issue · Open

Metadata
Source
tuist/tuist #6638
Updated
Jun 11, 2026
Domains
Generated projects
Details

What happened?

An external package may have its own dependencies. When these are built, they should be build as the same product type as the parent. For example if my dependency Apollo is built as a dynamic framework, I would expect its dependencies ApolloAPI and ApolloUtils to also be built as dynamic frameworks.

This becomes an issue if my project has two internal libraries, say, FeedFeature and ProfileFeature that both depend on Apollo. In this case, since the nested dependencies are built as static frameworks, I see a warning because they’re being linked twice (i.e. duplicated)

How do we reproduce it?

In a Package.swift, we can specify the product type of a dependency like so:

#if TUIST
import ProjectDescription
let packageSettings = PackageSettings(
productTypes: [
"Apollo": .framework
]
)
#endif
let package = Package(
name: "MyProj",
dependencies: [
.package(url: "https://github.com/apollographql/apollo-ios", exact: "0.51.0")
]
)

In the Project.swift:

let project = Project(
...,
target: [
.target(name: "FeedFeature", product: .framework, dependencies: [.external(name: "Apollo")]),
.target(name: "ProfileFeature", product: .framework, dependencies: [.external(name: "Apollo")]),
]
)

When using tuist cache both my targets will have Apollo.xcframework ApolloUtils.xcframework and ApolloAPI.xcframework linked as dependencies. This is a problem since the latter two are static and these two feature frameworks will be linked into the same app.

Error log

The following warnings need attention:
· Xcframework 'ApolloUtils.xcframework' has been linked from target 'FeedFeature' and target 'ProfileFeature', it is a static product so may introduce unwanted side effects.
· Xcframework 'ApolloAPI.xcframework' has been linked from target 'FeedFeature' and target 'ProfileFeature', it is a static product so may introduce unwanted side effects.

macOS version

14.5

Tuist version

4.23

Xcode version

15.4

Flights

Investigate, reproduce, or fix this item in an isolated repository. Each Flight preserves its outcome and agent session.

New Flights are paused Configure model inference, GitHub, and a sandbox provider to start another Flight. Existing results remain available below.
No Flights yet

Start a Flight and preserve its objective, outcome, and session here.

Comments
F
fortmarek Aug 19, 2024

I would expect its dependencies ApolloAPI and ApolloUtils to also be built as dynamic frameworks.

You need to specify those as dynamic in productTypes as well.

That being said, I think I agree and it makes sense to specify to change the product type for the downstream targets, too.

Curious to get thoughts on this from @pepicrft and @danieleformichelli 👀

PD
pm-dev Aug 28, 2024

Any thoughts @pepicrft @danieleformichelli?

N
Narsail May 22, 2025

I recently updated some of my libraries and then ran into this issue again, as some of the libraries included new dependencies that I had to add to my “dynamic frameworks” list. I think that is unnecessary cumbersome and the expected behavior should be the outlined inheritance.

M
MartinStrambach Jun 23, 2025

@fortmarek Does this issue have any priority? I believe it should be a standard behaviour since you can break your project just by updating dependencies even if you setup everything correctly (a new transitive dependency is introduced in the external library of your project). Also I found out that if you integrate TCA using Tuist dependencies, mark all necessary libraries as dynamic (Tuist is satisfied, no runtime crashes), then switch to Tuist cache, it generates lots of warning in runtime and crashes. Seems like Tuist cache treats transitive dependencies differently than when compiled together with the application.

M
MartinStrambach Jun 23, 2025

Also when I mark TCA’s Sharing framework as dynamic - "Sharing": .framework. I get tons of errors in unit tests due to some colliding system framework. Therefore it may not be so easy to just mark all child dependencies as dynamic. Or is there already some workaround?

dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureO15senderCancelledyA2EmFWC' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureO17receiverCancelledyA2EmFWC' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureO11streamErroryA2EmFWC' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureO10badRequestyA2EmFWC' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing13SFAirDropSendO7FailureOMn' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureOMn' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_OBJC_CLASS_$_SFCoordinatedAlertRequest' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/IMDPersistence.framework/IMDPersistence is being set to 0xBAD4007.
...
B
bielikb Jun 24, 2025

Also when I mark TCA’s Sharing framework as dynamic - "Sharing": .framework. I get tons of errors in unit tests due to some colliding system framework. Therefore it may not be so easy to just mark all child dependencies as dynamic. Or is there already some workaround?

dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureO15senderCancelledyA2EmFWC' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureO17receiverCancelledyA2EmFWC' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureO11streamErroryA2EmFWC' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureO10badRequestyA2EmFWC' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing13SFAirDropSendO7FailureOMn' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_$s7Sharing16SFAirDropReceiveO7FailureOMn' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/PassKitCore.framework/PassKitCore is being set to 0xBAD4007.
dyld[21532]: symbol '_OBJC_CLASS_$_SFCoordinatedAlertRequest' missing from root that overrides /System/Library/PrivateFrameworks/Sharing.framework/Sharing. Use of that symbol in /Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/System/Library/PrivateFrameworks/IMDPersistence.framework/IMDPersistence is being set to 0xBAD4007.
...

Im hitting this issue as well in our TCA driven project which pulls Sharing framework

"Sharing": .framework,
P
pepicrft Jun 25, 2025

I would expect its dependencies ApolloAPI and ApolloUtils to also be built as dynamic frameworks.

Is this what most people will expect? I’m not 100% sure. I wonder if we should instead have a mode that can be configured in PackageSettings where we take the graph, and set the product type automatically based on the graph. The thing is that depending on the configuration you are building (unknown at generation time), the thing you optimize for varies:

  • Debug: you want more dynamic products
  • Release: you want more static products

So perhaps this is something configurable at generation time:

tuist generate --infer-spm-linking-release
S
SubvertDev Nov 2, 2025

@pepicrft @fortmarek Good day gentlemen, is this issue on someone’s radar? I’m experiencing same problems as listed above

P
pepicrft Nov 5, 2025

@SubvertDev if you share a small example I can look at your specific issue.