If use (or distribute) third party Objective-c frameworks, you might have been faced once or twice with an "Undefined symbols for architecture" error.


This error can mean that you:

  • Are not linking to the library at all
  • The framework is missing that particular symbol for the architecture.

In this article I am going to cover the second case.

Inspecting a missing symbol

Let's start by seeing all the slices that the framework has;

lipo -info TestFramework.framework/TestFramework  

This outputs all the slices that the framework included.

Architectures in the fat file: TestFramework.framework/TestFramework are: armv7 i386 x86_64 arm64  

So, i386 is indeed a slice that this framework contain.

Next, we will check if the framework actually has the symbol it tries to link. From the issue description, we get that the symbol _MyAwesomeClass is not found in i386 architecture. Let's check that.

We can achieve that with either nm or otool. With nm:

nm -arch i386 -g TestFramework.framework/TestFramework  

Which outputs:

00000300 S _TestFrameworkVersionNumber  
000002d0 S _TestFrameworkVersionString  

Calling nm with -g will only show the external symbols, passing -arch i386 tells nm to only show the symbols for an architecture.

From above output, we can see that the symbols are missing for that architecture. That is what causes the linkage error.

Otool can also be used to return the symbols for an arch, using this command.

otool -arch i386 -Sv TestFramework.framework/TestFramework  

This outputs:

size of strings: 56  
object           symbol name  
TestFramework_vers.o _TestFrameworkVersionNumber  
TestFramework_vers.o _TestFrameworkVersionString  

Again, we can see how the symbols is not included in this slice.

By inspecting the symbols exported by the framework, we can make sure that we are not doing something wrong. While we cannot fix this issue, we can point it to the third party vendor and ask them to fix it from their side.