Privacy of static libs nested inside a dynamic framework

Hi there :slight_smile:

We have a modular app with a complex deps graph.

We heavily depend on multiple Google Maps packages (static, seems very hard to make them dynamic) in multiple modules (dynamic frameworks). Of course, we’re trying to avoid duplicated symbols (as it’s a proven source of crashes).

To achieve this, I created a dynamic framework that depends on all static frameworks/libs, and I’m adding it as a dependency to all modules that depend on Google Maps deps.

Let’s say

  • I have two modules (dynamic frameworks) A and B
  • MapsDependencies dynamic frameworks only embeds C that is static

I would have expected that:

A -> B
B -> MapsDependencies
MapsDependencies -> C

would make C content available to A and B (using implicit deps).

But in fact, there are compilation issues when using C symbols in A in this configuration.

So I tried:

A -> B
A -> MapsDependencies
B -> MapsDependencies
MapsDependencies -> C

Compilation goes through but it results in duplicated symbols at runtime .
According to the console, it seems there are multiple instances of MapsDependencies (even though it’s a dynamic framework).

objc[47444]: Class CADPComplianceRoot is implemented in both /SomePath/MapsDependencies.framework/MapsDependencies (0x116d3d320) and /SomePath/MapsDependencies.framework/MapsDependencies (0x116d49c10). One of the two will be used. Which one is undefined.

I also tried to make GMaps frameworks dynamic but then it seems they won’t find each other properly. On build time, there are some not found symbols.

All of that raises some questions:

  1. For my understanding:
    a. does using C symbols in A and B make it a dependency of each of them, causing the duplication of C in A and B
    b. OR is having C only available from MapsDependency the only source of duplication?
  2. Most importantly on the short term: how can I make GMaps static frameworks available in multiple related dynamic frameworks without duplication issues? Is my only option wrapping and hiding C symbols inside classes that I would make dynamically available from MapsDependencies?

Context

Hi @PierreMardon and welcome to the forum. Would you mind extending the diagram allow to include whether the product is static or dynamically linked for each of the products?

Sure!

A (dynamic) -> B (dynamic)
A (dynamic) -> MapsDependencies (dynamic)
B (dynamic) -> MapsDependencies (dynamic)
MapsDependencies (dynamic) -> C (static)

In fact my original problem is probably caused by something else.

I think there are duplicated symbols inside MapsDependencies, between some C (static) and D (static) .

A (dynamic) -> B (dynamic)
A (dynamic) -> MapsDependencies (dynamic)
B (dynamic) -> MapsDependencies (dynamic)
MapsDependencies (dynamic) -> C (static)
MapsDependencies (dynamic) -> D (static)

One clue is that there are only two symbols that are warned as conflicting at runtime, while the list of collisions would definitely contain dozens of such symbols if static libs were indeed exposed twice.

Plus tuist would have gently warned me as it does usually if I had statically linked libs imported by multiple dynamic frameworks :wink:

Thanks for sharing the graph @PierreMardon. With that setup, I’d expect any conflict to be at MapDependencies, and that really depends on how the graph looks beyond that point. If C and D are the only linked dependencies, I would not expect any issues with conflicting symbols.
If you can make C and D more concrete in the context of your app I might be able to help.

Thanks for the follow up!
In fact all the static libs are shown in the graph image of the first post.

By testing removing some of the MapsDependencies deps, I concluded that GoogleRidesharingDriver, GoogleRidesharingConsumer and GooglePlaces all declared their own implementation of CADPComplianceRoot and CADPComplianceData, hence the duplicate symbols from within my MapsDependencies framework.

No actual full lib duplicated instance, only ObjC conflicts between Google libraries :man_shrugging:

Thank you very much for your attention!

1 Like