I have a project that builds an iOS static library, and I'm trying to fix symbol conflicts when the library is used in apps, by limiting the global symbols in the library to the actual exported public API. In other words, I want to make all the symbols defined in the library private except for the ones declared in the API.
I found that I can use the Xcode build setting Linker > Exported Symbol File, just as in a dynamic library, and it will make all symbols private except for the ones listed in my .exp file. (I also had to turn on Single-Object Prelink to make this work.)
It's working fine for ARM builds. But the library for the iOS simulator doesn't work — apps built with it get linker errors saying that the Objective-C classes defined in the library can't be found: Undefined symbols for architecture i386: "_OBJC_CLASS_$_CBLManager", referenced from: objc-class-ref in DemoAppDelegate.o … followed by about a dozen more of these, for each of the other public classes …
Sure enough, the 'nm' tool shows that the symbol is marked private in the library: $ nm -arch i386 libCouchbaseLite.a | grep '_OBJC_CLASS_$_CBLManager' 001d70d8 s _OBJC_CLASS_$_CBLManager
(Note the lowercase 's' denoting that the symbol is private.) But I explicitly list this symbol, "_OBJC_CLASS_$_CBLManager", in my .exp file. Same for the other classes.
Even weirder, this problem doesn't happen with 64-bit builds for the same platform: $ nm -arch x86_64 libCouchbaseLite.a | grep '_OBJC_CLASS_$_CBLManager' 00000000001df298 S _OBJC_CLASS_$_CBLManager
(Note the capital 'S'.)
I'm baffled. But then, I'm not a linker expert. Any ideas?
—Jens
PS: I'm using Xcode 6 DP 5 on Yosemite DP 5. |