我可以在另一个框架中包含一个框架吗?

时间:2010-08-18 20:26:29

标签: objective-c cocoa xcode frameworks

我正在编写一个框架(称为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 / Development / Project / Current /lighthouse / build / Debug / Lighthouse.framework / Version / 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)

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

3 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分:1)

是的,你可以。

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

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

答案 2 :(得分:1)

我发现了解决这个问题的方法。我从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/,一切都很顺利。