Question:
Is it possible to weakly link a static library (Obj-C)?
Short Details
I do want my custom static framework (MyFramework.framework) to weakly link my other custom static library (libMyLibrary.a).
The functionality behind libMyLibrary.a is optional and can be omitted if there is NO libMyLibrary.a being linked by any 3rd party application that uses MyFramework.framework.
I am using -weak_library. My test application complains that static linker is unable to find MyLibrary's symbol MyClass within MyFramework's ABCTracker.o symbol:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_MyClass", referenced from:
objc-class-ref in MyFramework(ABCTracker.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
How to correctly setup weak linking?
Full Details
Setup
- The Xcode project builds a static Mach-O binary and bundles it into a static framework. The result is MyFramework.framework bundle.
- Other project builds a static Mach-O binary and the result is a static lib file libMyLibrary.a with a header MyLib.h
- libMyLibrary.a is removed from MyFramework.framework target's Build Phases > Link Binary With Libraries (as suggested here). Only MyLib.h is available to use library's API from the framework's classes
- NO Bitcode is used neither in the framework, nor in the library
- MyFramework.framework, libMyLibrary.a and custom application are all written in Objective-C
- The MyLib.h defines just one Objective-C class
MyClass - MyFramework.framework uses
MyClassfrom its own classABCTrackerconditionally checking for symbol availability during runtime, e.g.NSClassFromString(@"MyClass") == NULL From MyFramework target's Build Settings I have set
Other Librarian FlagsandOther Linker Flagsto same value-weak_library MyLibrary:OTHER_LDFLAGS = ( "-weak_library", MyLibrary, ); OTHER_LIBTOOLFLAGS = "-weak_library MyLibrary";
Result
- MyFramework.framework builds OK
After the build I have checked the symbols in the resulting binary and the output was emty (no symbols from the static library were built into static framework binary):
$ otool -L MyFramework.framework/MyFramework | grep MyClassDespite that, my test application which is not linked with MyLibrary whatsoever, builds with
lderror:Undefined symbols for architecture arm64: "_OBJC_CLASS_$_MyClass", referenced from: objc-class-ref in MyFramework(ABCTracker.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
What am I doing wrong here?
Other Observations
In MyFramework target I set Other Librarian Flags and Other Linker Flags of to same value:
-lMyLibrary. Result:otoolshows the library's symbols are built into the framework (expected).-weak-lMyLibrary. Result is the same as forlMyLibrary(is it expected?)
In my application target I set Other Linker Flags to -force_load MyLibrary. Result: the linker error slightly changes:
ld: file not found: MyClass
clang: error: linker command failed with exit code 1 (use -v to see invocation)