【问题标题】:Best way to install a custom cocoa framework安装自定义可可框架的最佳方法
【发布时间】:2010-12-13 02:47:54
【问题描述】:

我有一个自定义框架,按照 Apple 框架编程指南中的建议 >> Installing your framework 我安装在 /Library/Frameworks 中。我通过使用以下脚本添加运行脚本构建阶段来做到这一点:

cp -R  build/Debug/MyFramework.framework /Library/Frameworks

然后,在我的项目中,我链接到 /Library/Frameworks/MyFramework 并将其导入我的类中,如下所示:

#import <MyFramework/MyFramework.h>

这很好用,只是我总是在调试器控制台中看到以下消息:

正在将程序加载到调试器中... 共享库应用加载规则全部 警告:无法读取“/Users/elisevanlooij/Library/Frameworks/MyFramework.framework/Versions/A/MyFramework”的符号(未找到文件)。 警告:无法从“MyFramework”中读取符号(尚未映射到内存中)。 程序已加载。

显然,编译器首先在 /Users/elisevanlooij/Library/Frameworks 中查找,找不到 MyFramework,然后在 /Library/Frameworks 中查找,确实找到了 MyFramework 并继续其愉快的方式。到目前为止,这更像是一个烦恼而不是真正的问题,但是在运行单元测试时,gdb 会在(找不到文件)上停止并拒绝继续。我已经通过在运行脚本阶段添加额外的行来解决问题

cp -R  build/Debug/MyFramework.framework ~/Library/Frameworks

但感觉就像是在卖一开始就不应该破坏的东西。我该如何解决这个问题?

【问题讨论】:

    标签: cocoa xcode frameworks xcodebuild


    【解决方案1】:

    在过去的几个月里,我学到了很多关于框架的知识,所以我正在重写这个答案。请注意,我说的是在开发工作流程中安装框架

    安装公共框架(即,将由多个应用程序或捆绑包使用的框架)的首选位置是 /Library/Frameworks[link text],因为“此位置的框架由编译器自动发现在编译时和运行时动态链接器。”[框架编程指南]。最优雅的方法是在构建设置的部署部分。

    在构建框架时,有时您确实想在构建时更新框架,有时又不想。出于这个原因,我只在发布配置中更改部署设置。所以:

    1. 双击框架目标以打开目标信息窗口并切换到构建选项卡。
    2. 在配置选择框中选择发布。
    3. 向下滚动到部署部分并输入以下值:

    部署位置 = YES(单击复选框)

    安装构建产品位置 = /

    安装目录 = /Library/Frameworks

    安装构建产品位置用作安装的根目录。它的默认值是某个 /tmp 目录:如果你不将它更改为系统根目录,你将永远看不到你安装的框架,因为它隐藏在 /tmp 中。

    现在您可以在 Debug 配置中随意处理您的框架,而不会打扰您的其他项目,当您准备好发布时,您需要做的就是切换到 Release 并进行 Build。

    Xcode 4 警告 自从切换到 Xcode 4 后,我的自定义框架遇到了许多问题。大多数情况下,它们链接 GDB 中的警告,这些警告不会真正干扰框架的有用性,除非在运行内置单元测试时。一周前我已经向 Apple 提交了技术支持票,他们仍在调查中。当我得到一个可行的解决方案时,我会更新这个答案,因为这个问题已经证明很受欢迎(1 kViews 和计数)。

    【讨论】:

    • 您应该认为 cdespinosa 提供的有关 Xcode 构建系统的任何回答都是权威的。
    • 好吧,我赞成他的回答,所以我希望我的膝盖骨是安全的。但我确实认为我得到的解决方案更优雅,因为它对默认 Xcode 设置的更改更少,并且不需要命令行。
    【解决方案2】:

    没有太多理由将框架放入 Library/Frameworks 中,而且工作量很大:您需要在安装程序包中为用户完成它,这对于创建和维护来说非常麻烦,或者在您的应用中有安装代码(只能安装到 ~/L/F,除非您花费必要的时间和精力使您的应用能够以 root 权限安装到 /L/F)。

    更常见的是what Apple calls a “private framework”。您将把它捆绑到您的应用程序包中。

    即使是供任何应用程序通用使用的框架(例如 Sparkle、Growl),在实践中也被构建为用作私有框架,仅仅是因为将框架的单个副本安装到 Library/ 的“正确”方式框架太麻烦了。

    【讨论】:

    • 我不怀疑创建安装程序包是一项繁重的工作——我从来没有做过,也不是我期待的事情。但是由于无论如何都需要为应用程序完成它,我认为为框架添加一个新的框架不会有什么大不了的——它可能无论如何都应该捆绑到应用程序安装程序中,除非它被证明是一个不常见的流行框架。总而言之,我不相信保持框架的私有性有那么重要。
    • 我不同意。只需将 .framework 包复制到 /Library/Frameworks 中,然后将其导入其他 Xcode 项目中即可。
    • @RaffiKhatchadourian:但是您的应用程序将无法为其他任何人工作。您必须在每个用户的机器上安装 L/F 中的框架;对于在您拥有框架的同一位置没有框架的任何用户,该应用将不会启动。
    • @PeterHosey /Library/Frameworks 是框架的标准位置,所以这应该不是问题。
    • @RaffiKhatchadourian:使用该框架的多个应用程序并没有使 /L/F 更可取(安装和卸载的麻烦仍然超过它),并且 PackageMaker 看起来比实际更容易并且对用户没有帮助如果他们决定不想要框架,请卸载它。
    【解决方案3】:

    执行此操作的常规方法是让您的框架项目及其客户端共享一个公共构建目录。 Xcode 将在构建文件夹 first 中搜索框架头文件并链接到框架二进制文件,然后再搜索任何其他位置。因此,编译和链接到标头的应用程序项目将选择最近构建的项目,而不是安装的项目。

    然后您可以删除 cp -r 并使用安装位置构建设置将构建产品放置在最终位置,在命令行中使用 xcodebuild install DSTROOT=/。但您只需要在完成后执行此操作,而不是每次重新构建框架时执行此操作。

    【讨论】:

    • 很有趣,但我发现这种方法有两个问题。首先, xcodebuild install DSTROOT=/ 确实解决了“无法读取符号”的问题。但是:1)当框架的构建目录指向公共构建目录(项目文件夹之外)时,xcodebuild 会以某种方式忽略框架中所做的更改。框架头文件的修改日期会改变,但内容不会改变(可能与版本控制有关?)。 2)当我将构建目录更改回默认构建时,xcodebuild 将在框架内安装框架的另一个副本。很奇怪。
    【解决方案4】:

    当然,当您分发框架时,它应该安装在 /Library/Frameworks 中;但是,对我来说,您使用框架的测试/调试版本来做这件事似乎很奇怪。

    我的第一反应是在 ~/Library 下安装测试版本,因为它只是让设置测试和调试环境变得更加简单。如果可能的话,我希望调试/测试框架位于我正在测试的版本的构建树中,在这种情况下,它安装为Private Framework 用于测试目的。当需要处理框架的多个版本时,这将使您的生活变得更加简单。

    最终,只要您的应用程序或测试套件加载正确的版本,框架的位置并不重要。选择最容易进行测试/调试/开发的位置。

    【讨论】:

    • 由于该框架被多个项目使用,因此将其安装为私有框架是不可行的。我在发布版本(cp -R build/Release/MyFramework.framework/Library/Frameworks)上尝试过同样的事情,但结果是一样的。至于框架位于何处,只要...... - 好吧,我说不出话来。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 2011-01-31
    • 1970-01-01
    相关资源
    最近更新 更多