繁体   English   中英

通过-weak_library弱链接静态库

[英]Weakly link static library via -weak_library

题:

是否可以弱链接静态库(Obj-C)?

简短的细节

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

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

我正在使用-weak_library 我的测试应用程序抱怨静态链接器无法在MyFrameworkABCTracker.o符号中找到MyLibrary的符号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)

如何正确设置弱链接?

详细资料

设定

  • Xcode项目构建一个静态的Mach-O二进制文件并将其捆绑到一个静态框架中。 结果是MyFramework.framework捆绑包。
  • 其他项目建立一个静态的Mach-O二进制文件,结果是一个头MyLib.h静态库文件libMyLibrary.a
  • libMyLibrary.a已从MyFramework.framework目标的Build Phases > Link Binary With Libraries如此处建议 )中删除。 只有MyLib.h可以使用框架类中的库API
  • 框架和库中均未使用位码
  • MyFramework.frameworklibMyLibrary.a和自定义应用程序均用Objective-C编写
  • MyLib.h仅定义一个Objective-C类MyClass
  • MyFramework.framework使用其自身类ABCTracker MyClass有条件地在运行时检查符号的可用性,例如NSClassFromString(@"MyClass") == NULL
  • MyFramework目标的Build Settings中,我将Other Librarian FlagsOther Linker Flags为相同的值-weak_library MyLibrary

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

结果

  • MyFramework.framework建立成功
  • 构建之后,我检查了生成的二进制文件中的符号,输出为emty(静态库中没有任何符号内置到静态框架二进制文件中):

     $ otool -L MyFramework.framework/MyFramework | grep MyClass 
  • 尽管如此,我的未与MyLibrary链接的测试应用程序仍会生成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显示库的符号已内置到框架中(预期)。
  • -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)

我也没有成功地使XCode正确弱链接静态库,尽管我遇到了与您相反的问题-对我来说, nm显示了静态库中的所有符号,而不是“ U”(未定义)符号类型当您弱连接框架时,您会看到。

但是,可以使用以下解决方法:

  1. 创建一个名为MyWrapper.framework的新Cocoa Touch Framework项目,并将libMyLibrary.a添加到其中
  2. -ObjC到链接器标志中,以确保所有符号-all_load加载(如果需要非Obj-C符号,则添加-all_load
  3. 构建阶段将库的标头添加到框架的“ 公共标头”部分
  4. 构建此框架(您将需要设置一个聚合目标以针对所有体系结构构建,但这是一个单独的主题)
  5. 打开MyFramework.framework项目,并向其中添加MyWrapper.framework ,使其链接较弱(即,使用切换将其设置为Optional,或者如果您更喜欢从“ 与库链接二进制文件”阶段将其删除,并通过-weak_framework将其添加到Other Linker Flags )。
  6. 现在构建MyFramework.framework
  7. 在您的测试应用中,删除对libMyLibrary.a的任何引用
  8. 你应该能够无碰撞运行测试应用程序,你的代码应该检测的符号从libMyLibrary.a存在
  9. MyWrapper.framework添加到您的测试应用程序中,然后您将看到相反的结果-libMyLibrary.a中的符号将被找到并可用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM