【问题标题】:Can I include a framework in another framework?我可以在另一个框架中包含一个框架吗?
【发布时间】:2011-03-31 18:58:30
【问题描述】:

我正在编写一个框架(称为 Lighthouse.framework),该框架又使用来自另一个框架(准确地说是 RegexKit.framework)的代码。我已将 RegexKit.framework 复制到我自己的框架中,使其具有如下结构:

Lighthouse.framework/
  Versions/
    A/
      Frameworks/
        RegexKit.framework
      Lighthouse

但是,当我尝试运行使用 Lighthouse.framework(我的框架)的应用程序时,我收到以下错误:

dyld:库未加载:@executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit

引用自:/Users/mdippery/Developer/Projects/Current/lighthouse/build/Debug/Lighthouse.framework/Versions/A/Lighthouse

原因:图片未找到

显然,加载程序没有找到 RegexKit。

这里是加载器期望加载的路径,礼貌otool

build/Debug/Lighthouse.framework/Versions/A/Lighthouse:
    /Users/mdippery/Library/Frameworks/Lighthouse.framework/Versions/A/Lighthouse (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 12.0.0)
    @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit (compatibility version 0.4.0, current version 0.6.0)
    /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.1.4)
    /usr/lib/libobjc.A.dylib (compatibility version 1.0.0, current version 227.0.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 476.19.0)
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility version 300.0.0, current version 677.26.0)

我可以在另一个框架中包含一个框架吗?这是正确的方法吗?如何解决我的错误?

【问题讨论】:

标签: objective-c cocoa xcode frameworks


【解决方案1】:

是的,你可以。

但是,您需要包含的框架“知道”它在构建时的安装位置;否则,dyld 将无法在运行时找到它,如您所见。

如果我没记错的话,XCode 中的相关设置是“安装目录”和“框架安装名称”。后者可能对您的使用无关紧要,但您将需要前者成为以下内容:@executable_path/../Frameworks/Lighthouse.framework/Versions/A/Frameworks/RegexKit.framework/Versions/A/

【讨论】:

  • 在构建Lighthouse.framework(用于Lighthouse.framework)时是否设置安装目录?我试了一下,但没有成功(虽然也许我做错了什么)。
  • @mipadi:如果您不构建 RegExKit.framework,您将无法执行此操作。为什么要将 RegExKit 包含在其他框架中?没有它,你正在做的事情会很好。
  • 如果我的框架的消费者只需要包含我的框架,而不是包含我的框架的依赖项,那就太好了。
【解决方案2】:

最简单的方法是使用@rpath。您的配置应如下所示:

  1. 将 RegExKit.framework 的安装目录设置为 @rpath
  2. 将 Lighthouse.frameworks 的安装目录设置为 @rpath
  3. 将 Lighthouse.framework 的运行路径搜索路径设置为 @loader_path/Frameworks
  4. 确保将 RegExKit.framework 复制到 Lighthouse.framework 的 Framework 子文件夹中(为此使用自定义构建阶段)

最后,任何链接到 Lighthouse.framework 的应用程序都应该将 Runpath Search Paths 设置为 @loader_path/../Frameworks

【讨论】:

  • 我没有构建 RegexKit.framework(我使用的是预编译的二进制文件)。我还可以为它设置安装目录吗(我没有看到这样做的方法)?
  • 您可以为此使用 install_name_tool - 类似 install_name_tool -change @executable_path/../Frameworks @rpath/Frameworks
【解决方案3】:

我找到了解决此问题的方法。我从 sbooth 的回答中吸收了一些想法,但修复更简单。我运行了这个脚本:

install_name_tool -change @executable_path/../Frameworks/RegexKit.framework/Versions/A/RegexKit @loader_path/Frameworks/RegexKit.framework/Versions/A/RegexKit "${TARGET_BUILD_DIR}/${PRODUCT_NAME}.framework/Versions/A/${PRODUCT_NAME}"

作为运行构建脚本阶段。

请注意,对于一般情况,您必须将@executable_path/../ 更改为@loader_path/,一切正常。

【讨论】:

  • 你在哪里设置了这个构建脚本?在框架产品还是在聚合产品?
猜你喜欢
  • 1970-01-01
  • 2016-05-04
  • 2010-09-24
  • 2013-03-28
  • 2016-02-09
  • 1970-01-01
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多