弱链接静态库通过-weak_library

题:

弱链接静态库(Obj-C)有可能吗?

短细节

我希望我的自定义静态框架( MyFramework.framework )弱链接我的其他自定义静态库( libMyLibrary.a )。

libMyLibrary.a背后的function是可选的,如果没有 libMyLibrary.a被任何使用MyFramework.framework的第三方应用程序链接,可以省略。

我正在使用-weak_library 。 我的testing应用程序抱怨静态连接器无法在MyFrameworkABCTracker.o符号中findMyLibrary的符号MyClass

 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) 

如何正确设置弱链接?

全部细节

build立

  • Xcode项目构build一个静态的Mach-O二进制文件并将其捆绑到一个静态框架中。 结果是MyFramework.framework包。
  • 其他项目生成一个静态Mach-O二进制文件,结果是一个静态lib文件libMyLibrary.a,带有一个头文件MyLib.h
  • libMyLibrary.aMyFramework.framework目标的“ 构build阶段” >“ 链接二进制库”中移除( 如此处所示 )。 只有MyLib.h可以从框架的类中使用库的API
  • NO Bitcode既不用在框架中,也不用在库中
  • MyFramework.frameworklibMyLibrary.a和自定义应用程序都是用Objective-C编写的
  • MyLib.h只定义了一个Objective-C类MyClass
  • MyFramework.framework使用MyClass从它自己的类ABCTracker有条件地检查运行时的符号可用性,例如NSClassFromString(@"MyClass") == NULL
  • MyFramework目标的构build设置我已经设置Other Librarian FlagsOther Linker Flags为相同的值-weak_library MyLibrary

     OTHER_LDFLAGS = ( "-weak_library", MyLibrary, ); OTHER_LIBTOOLFLAGS = "-weak_library MyLibrary"; 

结果

  • MyFramework.framework生成OK
  • 编译后,我已经检查了生成的二进制文件中的符号,输出是emty(静态库中没有符号被构build到静态框架二进制文件中):

     $ otool -L MyFramework.framework/MyFramework | grep MyClass 
  • 尽pipe如此,我的testing应用程序不与MyLibrary链接,build立与ld错误:

     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) 

我在这里做错了什么?

其他观察

MyFramework目标中,我将Other Librarian FlagsOther Linker Flags设置为相同的值:

  • -lMyLibrary 。 结果: otool显示库的符号被构build到框架中(预期)。
  • -weak-lMyLibrary 。 结果与lMyLibrary相同(是否预期?)

我的应用程序目标中,我将Other Linker Flags设置为-force_load MyLibrary 。 结果:链接器错误稍微改变:

 ld: file not found: MyClass clang: error: linker command failed with exit code 1 (use -v to see invocation)