I'm writing a static library that has dependencies on other libraries (in my case SBJSON and ASIHTTPRequest).
If I compile these external dependencies into my library then I can't link against other libraries that have these classes compiled in. As my goal is to create a set of static libraries for my company that can be imported into any new app, compiling these dependencies into the library is obviously not an option.
Does anyone have any advice / best practices for creating a suite of shared static libraries with common dependencies?
If a static library's code contains references to some shared library items, these references will become dependencies in the resulting executable. The same holds if you link a library instead of executable.
Static Library Chains This is because static libraries don't link to other static libraries: All of the executable code only gets embedded in the executable. Technically, then, no static library depends on any other static library.
Static libraries belong next to their corresponding dynamic libraries, and in accordance with the FHS. Keep in mind that static libraries are usually only needed to build software, not run it.
Static Linking and Static Libraries is the result of the linker making copy of all used library functions to the executable file. Static Linking creates larger binary files, and need more space on disk and main memory.
A static library is just a collection of object files. In your case you don't want the object files for SBJSON and ASIHTTPRequest to be included in your static library—you want to leave that job to the final application. The only thing your static lib needs is the header files for SBJSON and ASIHTTPRequest.
Since these projects are both distributed as source files (.h and .m files) you just need to tell Xcode not to build the SBJSON/ASIHTTPRequest .m files for your static library target.
The easiest way to do this is to only import the .h header files for these projects into your Xcode project. Alternatively you can import both the .h and .m files but make sure the .m files are not included in the "Compile Sources" build phase of your static library target
Some other relevant SO topics:
How can I avoid "duplicate symbol" errors in xcode with shared static libraries?
Duplicate symbol: Include static lib A in static lib B, also include lib A and B in XCode Project
You could use a dependency manager like CocoaPods or VendorKit to pull in the required library, as well as all it's transitive dependencies - libraries that the library depends on.
It's the job of the dependency manager to manage any conflicts in transitive dependencies - eg if two libraries both use different versions of SBJSON, it will work out what to do. All you have to do is declare the top level library you want in a config file and it will work out what sub-libraries are needed and pull them into your Xcode Project.
CocoaPods has a nice way of managing this by pulling in the all of the libraries as source, and then compiling them all into a single static library - in a separate project. This is then linked into your project via a workspace.
VendorKit takes a similar approach, but uses a single project file.
Both CocoaPods and VendorKit allow you to easily publish your library to a central repository. CocoaPods allows you to maintain your own private or public fork of the central repo, if you wish - ie as an enterprise repository.
Most of the time this will get you out of trouble. In rare cases your library might depend on a very specific, older version of another common library. In this case you could use a tool to rename all of the header/impl files in that library to avoid collisions.
[Edit]: As of January, 2013 there is also a new contender - Maven Xcode plugin.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With