0

I have an iOS project (let's call it mainProj) with a library dependency. The library is used in other projects as well. Let's call this library utilLib.

Now, I want to add another library (let's call it logLib) as dependency in both the mainProj and the utilLib.

The problem is that adding logLib as dependency in both mainProj and utilLib leads to duplicate symbols. The other problem is that both the mainProj and utilLib need to depend on that logLib as they need to work independent one of the other.

Is there a work-around for this problem?

icenac
  • 400
  • 4
  • 11

2 Answers2

1

You should link logLib only to mainProj. There is no reason to link it into utilLib. A static library is just a bunch of unlinked .o files. You never need to link dependencies into a static library, and you should strongly avoid doing so because it leads to duplicate symbols. You just need the logLib headers for utilLib.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • As I specified, the utilLib is used in other projects as well and it needs logging capabilities. I don't want to force the users of the utilLib to also depend upon logLib. – icenac Jun 25 '16 at 16:11
  • That's fine. utilLib will still have access to logLib. The other projects also need to link both utilLib and logLib. You only need the logLib headers at the time you compile utilLib. You don't need to link them together until the final project link (and this is the only time you should link them together). To the next obvious question everyone asks, "how do I let other projects use utilLib without having to link logLib themselves?" The answer is "you don't." They need to link all the dependencies themselves, or you will have collisions eventually. – Rob Napier Jun 25 '16 at 16:15
  • What if utilLib uses 100 other libs just like logLib? Should I force everyone using utilLib to also link all those 100 libs? This doesn't look like a good practice. It should only be one single lib. Also, I don't have access to the other projects that use utilLib. In fact, I don't even know how many projects depend upon it. – icenac Jun 25 '16 at 16:18
  • Yes, if you have that many dependencies, you would have to make everyone link them all. You should not create a library with so many dependencies. Anything you try to do to work around this problem is going to cause collisions eventually. You cannot pre-link for your caller any library that they might ever link from somewhere else. Even when it seems to be working, very small changes will make it explode. It is inconvenient, but not a solvable problem without a package manager (which just automates linking everything at the end; it doesn't avoid it). – Rob Napier Jun 25 '16 at 16:50
  • Note that every platform and shared code system has this problem. Microsoft's attempted to work around it, and that's what caused "DLL Hell." Microsoft finally fixed it by creating a package manager via assemblies. CocoaPods is iOS's most ubiquitous answer to this problem. Eventually there will be a Swift package manager, and we'll move the problem into that. But you can't make the problem go away. You can only try to make it a little more automatic and easier to track. Eventually the link must be at the final target. – Rob Napier Jun 25 '16 at 16:52
  • I see. I was afraid of that. The only work-around that I see is to use some kind of dependency inversion. Thanks for your answers! – icenac Jun 25 '16 at 16:53
  • 2
    +1 for dependency inversion, especially for logging. It is much nicer on the caller to pass their own logger into frameworks than to have the framework do its own logging. This is a very good direction to explore. – Rob Napier Jun 25 '16 at 16:57
0

From my point of view, the best solution would be to add logLib only to utilLib. It will be anyway available from mainProj, because it already has a dependency with utilLib.

  • But then, it couples the utilLib with the mainProj. If utilLib is later removed, the mainProj will not build anymore. – icenac Jun 25 '16 at 16:13