Why do I get iOS linker errors with my static libraries?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
iOS linker errors with static libraries usually mean one of three things: the app cannot find a symbol, the library was built for the wrong architecture or platform, or the build settings do not pull in all the object files the app actually needs. The error text is often noisy, but the root cause is usually precise once you classify it correctly.
Read the Error by Category
The linker stage happens after compilation. Your source code may compile cleanly and still fail later because the final executable cannot be assembled from the objects and libraries you provided.
Three error families cover most cases:
- '
Undefined symbols for architecture arm64' - '
duplicate symbol' - '
building for iOS Simulator, but linking in object file built for iOS'
Those messages point to very different problems, so treat them differently.
Undefined Symbols Usually Mean a Missing Dependency
An undefined symbol error means some code was referenced but the linker could not find its implementation in the linked objects or libraries.
Common causes include:
- The static library itself was not added to the target
- A dependent system framework was not linked
- The symbol exists in the library, but the object file was not loaded
- The symbol name differs because of C, Objective-C, or C++ linkage rules
Useful inspection commands:
lipo shows which architectures the library contains. nm shows which symbols are exported. If the symbol is absent, the issue is inside the library build. If the symbol exists, the issue is usually target linkage or build settings.
Architecture and Platform Mismatches
This is the classic case where a device archive is linked into a simulator build, or the library contains only one architecture slice.
For example, a library built only for iphoneos cannot satisfy a simulator target. Modern distribution usually solves this with an .xcframework, which keeps device and simulator variants separate.
You can inspect a library bundle like this:
If you are packaging your own binaries, creating an .xcframework is the safer route:
That avoids many old "fat library" problems.
Objective-C Categories and -ObjC
One subtle issue is that static libraries containing Objective-C categories are not always fully loaded by the linker. The library is present, yet methods from a category appear missing at runtime or even during linking.
In that situation, Other Linker Flags often needs -ObjC:
This tells the linker to load Objective-C classes and categories from static libraries more aggressively. It is a common fix when a library adds methods in categories rather than in primary class implementations.
Do not add random linker flags without understanding them, though. -all_load or -force_load can fix some cases but also pull in unwanted objects and create duplicate symbol errors.
Duplicate Symbol Errors
A duplicate symbol error means the linker found more than one definition for the same symbol. Typical causes are:
- The same
.mor.ofile is included twice - Two static libraries contain the same third-party code
- A file was added both directly to the target and also through a library
When that happens, identify which libraries or objects define the same name:
The fix is usually to remove one copy, not to hide the warning.
Build Settings Matter More Than People Expect
Many linker errors are really configuration errors. Check these settings first:
- '
Library Search Paths' - '
Framework Search Paths' - '
Other Linker Flags' - target membership for source files
- whether the correct target is linking the correct binary
You can inspect resolved build settings from the command line:
This is often faster than clicking through Xcode when you are comparing multiple configurations.
Transitive Dependencies Are Still Your Problem
A static library can depend on other frameworks or system libraries. Even if libA.a links successfully in its own project, your application may still need to link Security.framework, libz, or another dependency explicitly.
That is why vendor integration guides matter. The library file alone may not be the whole dependency graph.
Common Pitfalls
The most common pitfall is assuming headers prove the library is linked correctly. Headers only help compilation; the linker still needs the compiled implementation.
Another is debugging the wrong architecture. A library can work on device and fail on simulator because the simulator slice is missing.
Teams also overuse linker flags. -ObjC is targeted and common. -all_load and -force_load should be used deliberately because they can create new conflicts.
Finally, duplicate symbols are often self-inflicted by mixing package managers, manual linking, and copied source files in the same target.
Summary
- Undefined symbols usually mean a missing implementation, missing dependency, or unloaded object file.
- Platform and architecture mismatches are common when a static library was not packaged for both device and simulator.
- Objective-C categories inside static libraries often require
-ObjC. - Duplicate symbol errors mean the same implementation was linked more than once.
- Use
lipo,nm, andxcodebuild -showBuildSettingsbefore changing random Xcode settings.

