Question

I've build a Framework for an Objective-C App. I've tested it on minimalistic Programs where it worked. I was trying to use it in a real App now. Unfortunately the linker can't find the definition of my classes. =(

When I try to run it, I get the following Error Message:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_ClassInMyFramework", referenced from:
    objc-class-ref in libMyLib.a(MyLib.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The Dependency:
App -> libMyLib.a -> MyFramework.framework

The usual suggestion for this error message is to add the framework into the "Link Binary with Library" Build Phase... I can assure you that this has happened ;)

My first thought is that something might be wrong with the Build Settings which results in this linking error. On second thought It may have to do with the Project-Setup. Is it possible to statically link a framework into an '.a' library file?

Update:
I've linked the Framework into the App and now it's working. But I don't consider this a clean solution. Help still appriciated. =)

Was it helpful?

Solution

The short answer is no, you can't link the framework statically into your .a file. See this discussion.

The reason is, the static library doesn't include the object code (the definition) of classes from the dynamic framework. The static library links to object code in the framework the same way the app links to the framework code: at run-time.

From Apple's Framework Programming Guide: "Dynamic shared libraries have characteristics that set them apart from static linked shared libraries. For static linked shared libraries, the symbols in the library are checked at link time to make sure they exist. If they don’t exist, link errors occur. With dynamic shared libraries, the binding of undefined symbols is delayed until the execution of the program."

It depends on what you want to be able to do with your code. You could add a static "target" for your framework project, so your framework project outputs both a framework and a static library. You could include this static library into apps.

But, one benefit of frameworks is that you can include nibs, images, headers, etc. So, linking your framework into your apps directly is not a bad way to go. Otherwise, you need to include these assets directly into your project. If you want this framework to be distributed with your app, you'll need to package it inside the app wrapper.

It looks like some people create a "static framework" for inclusion into an iOS project, but this looks a bit hacky to me.

As an interesting exercise, you can explore the symbols in your object code. Let's say you are using a ClassInMyFramework (from your framework) somewhere in your static library, like:

ClassInMyFramework *myFramework = [[ClassInMyFramework alloc] init]; 

The static library will then include the _OBJC_CLASS_$_ClassInMyFramework symbol. You can see the list of symbols in your static library file at the command line:

$ nm /path/to/libMyLib.a

This will output a list of symbols, which will show that _OBJC_CLASS_$_ClassInMyFramework is undefined (note, the "U" designates that the class is undefined):

                 U _OBJC_CLASS_$_ClassInMyFramework

Whereas, if you were do to the nm command on your framework:

$ nm /path/to/MyFramework.framework/Versions/A/MyFramework

Your output would show that the symbol is defined in your framework (though the definition will still only linked at run-time), which would look something like this, showing an address of the definition:

0000000000001100 S _OBJC_CLASS_$_ClassInMyFramework
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top