5

I am developing a reasonably complex iOS Application. To rationalise development, I have begin developing each module as a standalone project, which are then composed together in the top-level Application project, resulting in a tree of dependencies.

I have taken this approach successfully before, but this time around have a shared dependency (C) which causes a problem:

     A
    /|\
   / | \
  B  C  D
 / \     \
C   E     C

Where A is the top-level Application project, and C is a 'Core Library' of functions. This core library is a dependency of A itself, as well as modules B and D. The resulting multiple complilation causes duplicate symbols in the build folder and failed linking.

Now, I can be pragmatic and just remove the reference from A, as this will be compiled into the build folder by B anyway, and if D wasn't involved, this would just work. But how do I go about resolving the duplication of C dependency from B and D? The B and D projects still need a reference to C when I compile them standalone, but there is a clash when compiled twice in the context of A.

I can imagine some convoluted solution using objcopy and giving them unique prefixes, but this would be somewhat inefficient as it's the same code. I could live with this, but is there a better way? Perhaps some compiler or linker flag to reuse an existing symbol in the build folder if one exists, instead of compiling again?

Thanks for any advice.

Chris Hatton
  • 787
  • 9
  • 17
  • Technically, this is the same question as: http://stackoverflow.com/questions/11784917/how-do-i-resolve-avoid-duplicate-symbols-in-common-transitive-xcode-dependencies ...but it has not been adequately answered. – Chris Hatton May 28 '13 at 21:12
  • I cant see the problem, a static library, when being built does not link against other libraries but exposes dependencies which are resolved only when that library is linked against an executable. In your case "A". It appears that B, C, D, E are NOT static libraries, otherwise your question would not make sense. – Till May 28 '13 at 21:26
  • @Till: "a static library, when being built does not link against other libraries". Yes, it does, that was precisely the problem! Anyway, I have since solved this issue by explicitly omitting the linking stage for targets below the top-level, which then does result in the behaviour you describe. – Chris Hatton Oct 04 '15 at 12:31
  • yeah, I know that sometimes this is done resulting into a so called "convenience library" - however not that common and just as you say, usually avoidable. – Till Oct 05 '15 at 12:32

1 Answers1

0

The solution that worked best for me was having two targets in each module project: <TargetName> and one I called <TargetName>-NoLink.

These two targets are identical, except that the linking stage is omitted in -NoLink. As a result, only the intermediate .o files are created, and the build can progress all the way to the root project, which finally is linked to all modules.

The linked target <TargetName> remains, retaining the flexibility to link all dependencies at any point in the tree, producing a standalone .a file for any module.

Chris Hatton
  • 787
  • 9
  • 17