Duplicate symbols when linking ObjectiveC static libraries

转自:http://www.lizhecome.com/post/e59bb0e689b0e68891e4b8a4e5a4a9e79a84e997aee9a298e7bb88e4ba8ee8a7a3e586b3e4ba86efbc81efbc81e8bdace7af87e69687e7aba0.aspx


When you link a static library that’s using ObjectiveC categories, you usually have instructions from the developers to add -ObjC and -all_load linker flags which solve linking problems and prevent crashes. Now, if you happen to have the same categories or other objc symbols in your project that uses this static library you’ll get linker errors for duplicate symbols. The most common example for this is using touch JSON framework. I have this static library that uses it, and I also use it in my own code. I’m running into this linking problem every once in a while so I’m going to explain it here and provide a solution for fixing/avoiding it.

THE PROBLEM

Command /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1

ld: duplicate symbol _OBJC_METACLASS_$_SBJSON in /Users/ivan/Projects/MyApp/sources/Trunk/MyApp/libtest-simulator.a(SBJSON.o) and /Users/ivan/Projects/MyApp/sources/Trunk/MyApp/build/MyApp.build/Debug-iphonesimulator/MyApp.build/Objects-normal/i386/SBJSON.o

WARNING: I’ll be talking about problems with touch JSON library because this is the common problem. Solutions may not apply to other libraries although the principle is more-less the same. Be warned.

SCENARIO #1

“My project uses 1 static library and both this library and my project need JSON framework”.

Simplest solution that might work is to remove -ObjC and -all_load linker flags. When I say ‘might’, I mean that you need to be extra careful with this. If you do this, the static library you link will depend on JSON code from your project so if there’s, for example, a version mismatch you’ll run into serious problems.

 

Linker Flags

SCENARIO #2

“My project uses a static library which depends on JSON framework but this library also links other ObjectiveC static libraries. Both my project and this static library need JSON framework”

OR

“I cannot remove -ObjC and -all_load because I need to properly link categories inside a static library, but I also need to add JSON framework to my own project”

Now this is a specific scenario I ran into earlier. I wanted to use Three20 library which links several different ObjC libraries of its own so I definitely need -ObjC and -all_load flags otherwise my app crashes. On the other hand, I had another static library which uses JSON framework and adding this framework to my project causes duplicate symbols linker error.

The solution is simple again but you also need to be extremely careful. You leave those linker flags to properly link ObjC libraries but you don’t add JSON framework in your project. Instead you depend on JSON library linked with the static library you are using. You will, however, need to add header files in order to avoid compilation errors in your own code. Possible problem here is header files vs. compiled code in the static library mismatch. So you need to make sure that the JSON header files you’re using match the JSON code version linked with the static library. If you already imported JSON framework, just remove .m files in XCode from your target.

 

JSON framework files

 

BOTTOMLINE

Obviously, these are some rare cases of linking problems however, JSON touch framework is a very popular framework and it’s not uncommon that some 3rd party libraries you want to use are built on top of it. My final advice is to understand the problem and why it happens, then you will be able to solve it one way or the other. Good luck!


你可能感兴趣的:(json,header,xcode,library,linker,compilation)