ios - 通过-weak_library 弱链接静态库

标签 ios objective-c xcode linker static-libraries

问题:

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

详细信息

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

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

I am using -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 二进制文件,结果是静态库文件 libMyLibrary.a, header 为 MyLib.h
  • libMyLibrary.a 已从 MyFramework.framework 目标的Build Phases> Link Binary With Libraries ( as suggested here ).只有 MyLib.h 可用于从框架的类中使用库的 API
  • NO Bitcode既不在框架中也不在库中使用
  • 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 构建正常
  • 在构建之后,我检查了生成的二进制文件中的符号,输出为空(静态库中的符号没有内置到静态框架二进制文件中):

    $ 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 符号)
  3. 将您的库的 header 添加到构建阶段中框架的公共(public) header 部分
  4. 构建此框架(您需要设置一个聚合目标以构建所有架构,但这是一个完全独立的主题)
  5. 打开您的 MyFramework.framework 项目并将 MyWrapper.framework 添加到其中,弱链接(即使用切换将其设置为可选或者,如果您希望将其从Link Binary with Libraries 阶段移除并通过-weak_framework 添加到Other Linker Flags)
  6. 现在构建MyFramework.framework
  7. 在您的测试应用中,删除对 libMyLibrary.a
  8. 的所有引用
  9. 您应该能够在没有崩溃的情况下运行您的测试应用程序,并且您的代码应该检测到来自 libMyLibrary.a
  10. 的符号的存在
  11. MyWrapper.framework 添加到您的测试应用程序,然后您应该会看到相反的结果 - 来自 libMyLibrary.a 的符号将被发现并可用。

关于ios - 通过-weak_library 弱链接静态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47345870/

相关文章:

ios - 给 App 添加隐形标签?

ios - UINavigationViewController - 每个后续 VC 上的右键不同吗?

ios - 远程推送通知在另一个 View Controller 中接收

ios - ViewController 没有取消

iphone - 是否有用于处理 map 上的区域并计算交叉点、面积等的 iOS API?

swift - UIProgressView 在 iOS 13 上没有动画进度

ios - swift 这些协议(protocol)有什么区别

ios - 以编程方式通过内容的摘要高度设置 uiview 高度,并将其添加到容器并调整其大小

iphone - iOS 客户端 : "Caching" Server-side data to persistent storage

iOS:无法在 iCarousel 中设置图像