Question

I am trying to use a static library in a project. The static library depends on several frameworks... CoreData, CFNetwork, AddressBook, etc.

The static library also uses categories, so I am forced to use the -all_load linker option in the main project's "Other Linker Settings". When I enable this, I get 120 errors all relating to my main project not being linked with the same frameworks as my static library (CoreData, CFNetwork, AddressBook, etc).

It is very inconvenient for a developer to want to use a static library, link to it, but then still be required to link to all of the frameworks that the library links to. Is there any way to automate this process, so that the main project automatically links to all of the frameworks linked to by the static library?

I am using XCode 4.4.

edit: to be more clear, I have the following:

StaticLibrary.xcodeproj
    - AFNetworking
        - files...
    - CoreData
        - categories for NSManagedObjectContext, for convenience
    - AddressBook
        - convenience methods for working with contacts

This project's target is linked to the necessary frameworks under Build Phases > Link Binary With Libraries. This includes CoreData.framework, AddressBook.framework, etc.

Now what I would like to do is add this library to another project of mine. In fact, I would like to add this library to every new project I make from here on out, so I always have easy access to the convenience functions/categories that I've written. So: I add the library to my project, and then add the .a file to Build Phases > Link Binary With Libraries (of my main project). I also do everything else necessary that I know of (see comments).

What I would like to happen: the main project is now linked to the library, so it inherits all of the library's links so that the main project is now also linked to CoreData.framework, AddressBook.framework, etc.

What does happen: the main project gives me errors because it is not linked to anything that the library requires.

Is there a way to automatically add the linked frameworks from the static library to the main project, or should I split the library up into CoreDataStaticLibrary, etc, and then require the developer to add CoreData.framework as well as the static library to the project target everytime?

Was it helpful?

Solution

As I understand, you should only need -all_load if your library contains only categories. Otherwise, you can use -ObjC. That's what I use, at any rate.

Also, when you build a static library, you are just creating an archive of compiled object modules. No external dependencies are resolved in the library. Really, you should just think of it as a single collection of a bunch of object code files.

So, when you finally link your executable, it will link all your compiled code, along with the archive of pre-compiled code in your static libraries. The linker will expect to resolve all symbols, so you must tell it where to find all the libraries (frameworks) that are needed to completely resolve all the symbols.

Should XCode be able to look inside a static-library subproject and pull out the framework dependencies from that project and add them to the linker invocation for the final project? Sure. But, I'm not aware of a way to make that happen automatically.

If you want, you can create a podfile for your library, and use CocoaPods to manage your project dependencies.

OTHER TIPS

The problem is you're including the same symbols several times. I've run into the same issue several times and the solution is basically to understand what the "-all_load" flag does, which is pretty well explained in this SO question: What does the all load linked flag do

Said that, you never reference frameworks from your library in that way. Since these frameworks are dynamically linked they don't really belong to your static library, there are just references pointing to them on it.

The user of such library should be responsible of adding the necessary frameworks to make it work properly. This means, you don't have to link your library to such frameworks (as such thing just doesn't make sense), just add them to project that's gonna use it. (Have a look on Restkit to see how it's done).

Also, I think you could get rid of the "all_load" flag and try to replace it with "force_load /path/to/the/library" all_load is only necessary in case your library only contains categories (no classes at all).

Let us know how it goes and happy coding!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top