objective-c - Cocoa - 针对框架的弱链接 - 忽略版本?

标签 objective-c xcode macos cocoa

我们有一个使用 R 框架的 Cocoa 应用程序。我们的目的不是随应用程序一起提供 R,因为用户可能会在本地安装自己的版本。我们面临的问题是如何正确地针对具有多个版本的框架进行弱链接。

我们对它的链接很弱:

  • 在链接的二进制文件中将框架设置为可选
  • 在build设置 > 其他链接器标志中添加为 -weak_framework
  • 在尝试使用 R 之前,我们会在代码中进行通常的“类存在”检测。

发生的情况是这样的:

  • 如果安装了我们链接的相同版本的 R,则一切正常。
  • 如果未安装 R,则一切正常。我们检测到不存在并且它优雅地失败。
  • 我们的麻烦是当我们链接到一个版本(假设是 3.1)而用户有不同的版本(假设是 3.2)时。然后我们收到错误无法解析(我的应用程序)中的符号(某些sybmol),因为无法加载依赖的dylib #1

我想这是有道理的,因为我们是针对 3.1 构建的,但它不存在 - 3.2 存在。我只是不清楚如何对这样的外部库进行正确的弱链接并允许它与不同的版本一起使用。或者我完全不知道如何完全弱化链接。这是完全有可能的。

非常感谢任何指导。

谢谢

最佳答案

@eww 和我继续调查此事,以下是我们能够找到的内容。编译框架和应用程序时,它们引用 R.framework 的特定版本。我们可以通过运行看到这一点:

otool -L /Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa 
/Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa:
  @rpath/RCocoa.framework/Versions/A/RCocoa (compatibility version 1.0.0, current version 1.0.0)
  **/Library/Frameworks/R.framework/Versions/3.3/Resources/lib/libR.dylib (compatibility version 3.3.0, current version 3.3.2)**
  /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1252.0.0)
  /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
  /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
  /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1253.0.0)

经过一番搜索,this post提出了如何将 R.framework 引用更改为“当前”而不是特定版本的线索

install_name_tool -change /Library/Frameworks/R.framework/Versions/3.3/Resources/lib/libR.dylib /Library/Frameworks/R.framework/Versions/Current/Resources/lib/libR.dylib /Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa

我们现在可以看到它正在引用当前版本文件夹:

otool -L /Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa 
/Applications/StatTag.app/Contents/Frameworks/RCocoa.framework/RCocoa:
  @rpath/RCocoa.framework/Versions/A/RCocoa (compatibility version 1.0.0, current version 1.0.0)
  /Library/Frameworks/R.framework/Versions/Current/Resources/lib/libR.dylib (compatibility version 3.3.0, current version 3.3.2)
  /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 1252.0.0)
  /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 228.0.0)
  /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1)
  /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1253.0.0)

让我们更困惑的是,当它构建到我们的最终应用程序中时,还有其他本地框架引用 RCocoa 和 R,这意味着我们必须多次运行 install_name_tool 。很高兴地报告现在一切正常。

关于objective-c - Cocoa - 针对框架的弱链接 - 忽略版本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45112115/

相关文章:

iphone - 必须更改语言后刷新导航返回按钮的标题

objective-c - 如何获取CABasicAnimation进度?

xcode - 如何将钥匙串(keychain)从一台开发机器导入另一台开发机器

c - 在 OpenSSL lib 包含文件中找不到 i2c_ASN1_INTEGER 函数

c++ - boost Asio 和 OpenSSL 1.1.0

objective-c - 使用 NSFileManager 访问 mac 共享上的文件

ios - 应用程序在设备上崩溃但在模拟器中没有崩溃 :[UITableViewController loadView] loaded the "XXXViewController" nib but didn't get a UITableView. '

ios - 访问笔记应用程序数据

xcode - 如何修复 Xcode 10.2 中的 "SWIFT_VERSION ' 3. 0' is unsupported, supported versions are: 4.0, 4.2, 5.0"错误?

ios - Xcode UIWebView 不显示 URL 的内容,空白的白色 webview,没有错误