A
is a module project. There are some test targets and the relevant reusable code is compiled in a separate (static library) target. A
uses the third party Lumberjack logging library. The Lumberjack code was simply dropped into the project.
B
is a different module project, but otherwise it has the same properties as A
.
C
is the main project. It depends on A
and B
. It links the libraries of A
and B
.
Compiling C
will result in duplicate Lumberjack symbols.
How can I have multiple separate module projects so that...
- they don't know of each other,
- use the same third party code,
- can be compiled and tested on their own,
- included in a main project without duplicate issues?
Since you are targeting OSX, the solution to your issue is building Lumberjack as a framework (as opposed to link the sources code in your A and B modules) and then using that framework wherever it is required (i.e., in any project using A or B modules).
Indeed, Lumberjack already includes a project that will build a Lumberjack.framework, check this:
CocoaLumberjack/Xcode/LumberjackFramework/Desktop/Lumberjack.xcodeproj
.Elaborating more on this, you would define your A and B modules as you are doing now, but without dropping Lumberjack source code in it. What you do instead is, whenever you want to use the A static library in a executable (say, your test target), you add the library to the target and also the lumberjack framework (exactly as you do with OSX SDK frameworks).
Adding the dynamic framework is just a different way to "drop the sources", if you want, but done properly.
When you want to use both A and B in a C project, you add both static libraries and your Lumberjack framework to C.
As you can see, this way of doing will comply with all your four requirements, at the expense of introducing one dependency: you need to make clear in your static libraries documentation that they depend on the Lumberjack framework. This is actually not a big issue, since the latter is available in its own project and any one will be able to build it on his own.
If you want to improve on the handling of this dependencies, cocoapods are the way to go (a cocoapod is a file associated to your library which describes its dependencies, so when you install your library, the cocoapods system will automatically install also the dependencies). But this is highly optional. One single dependency is not a big issue to document or comply with.
Hope this answers your question.
So, to elaborate on sergio's answer, I was able to succesfully build a test setup as follows.
I hate to reference an existing answer but here's one solution that's cumbersome but works: What is the best way to solve an Objective-C namespace collision?
I have this same problem and I'm working on a better solution though. Another idea that might work but I'm not yet sure how to implement it I asked here: Selectively loading classes in Objective-C
A third idea I had because of something someone said on my question was to wrap one of the libraries in a framework and create functions that reference the functions you need. Then load using something like #import
<myFramework/MFMyAliases.h>
I was trying to achieve the same thing before few months and "Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References" article got all what i needed. please check it out if its useful.
Have you tried looking at the libraries with
ar
? If you are very lucky, running for examplegives you a list of files like
where the Lumberjack files are clearly separable from the rest. Then, you can kick them out with
and link
C
against this trimmed library while using the full library when testingA
alone.Try this.
It is sharing libraries/modules between different projects.