如何分发带有依赖库的 Mac OS X?
Posted
技术标签:
【中文标题】如何分发带有依赖库的 Mac OS X?【英文标题】:How to distribute a Mac OS X with dependent libraries? 【发布时间】:2010-12-01 17:54:46 【问题描述】:我有一个程序(特别是我的 SO DevDays Countdown app challenge 条目),它依赖于几个动态库,即 libSDL、libSDL_ttf 等。我通过 MacPorts 在/opt/local/lib
下安装了这些库,许多人不会安装这些库(有些人可能安装了它们,但不是在那个位置)。
如何分发我的程序,以便没有安装这些库的人可以开箱即用地运行它?显然我必须分发各种.dylib
文件,但这样做是不够的。动态加载程序仍会查找安装在我安装它们的位置的库。有没有办法告诉动态加载器查看可执行文件的当前目录,就像 Windows 对 DLL 所做的那样?人们不应该修改任何环境变量(例如DYLD_LIBRARY_PATH
),因为我希望它能够开箱即用。
【问题讨论】:
【参考方案1】:对此的基本方法是将它们放在 .app 包中。然后,您将修改链接器查找共享库的位置以包含此内容。
步骤如下:
为您的目标创建一个新的复制文件构建阶段,将这些文件复制到 .app 包的 Frameworks 目录中。
编辑构建配置设置“运行路径搜索路径”以包含@executable_path/../Frameworks
如果您使用这些更改构建可执行文件,然后查看,您应该会发现 dylib 存在于 Foo.app/Contents/Framework
目录中,并且运行 otool -L Foo.app/Contents/MacOS/Foo
应该为这些 dylib 生成并以 @rpath 为前缀的条目。
来自Cocoabuilder post:
一般来说,@loader_path
比 @executable_path
更受欢迎,因为它
允许嵌入式框架在可执行文件和捆绑包中工作,
插件或子框架。唯一的缺点是@loader_path
需要 10.4 或更高版本。如果您使用的是 10.5 或更高版本,@rpath
甚至是
比@loader_path
好。
【讨论】:
我没有使用 Xcode(没有 .app 包),只是普通的旧 gcc 和 make。我也在使用 OS X 10.4;根据 developer.apple.com/mac/library/documentation/DeveloperTools/… ,运行路径搜索路径仅支持 10.5 及更高版本。 我相信 @executable_path 甚至可以在 10.4 上工作(@loader_path 和 @rpath 不会)。您可能还会阅读:blog.onesadcookie.com/2008/01/installname-magic.html 如果您不使用 Xcode,最好的选择可能是使用 Autotools 和朋友。 有谁知道如何使用 CMake 将@executable_path/../Frameworks
添加到运行时搜索路径?我找不到明确的解释。【参考方案2】:
正如您提到的,您没有使用 Xcode,所以这有点困难。以下是按我的偏好顺序排列的选项:
切换到 Xcode。使用框架。 SDL 库已经作为框架提供,而且我见过不止几个商业游戏在应用程序包中包含 libsdl.framework。
使用框架,但保留您的 Makefile。下载您的 SDL 库的框架版本(或自己构建它们),并使用 -framework 链接器标志与它们链接。将框架与您的应用一起分发或不分发,并告诉您的用户将它们放在 ~/Library/Frameworks 或 /Library/Frameworks 中。我不会为此烦恼安装程序。
针对 SDL 进行静态链接。在 Makefile 中,您必须列出静态库的路径,而不是使用 -l 标志,例如,您运行“ld blah blah /opt/local/lib/libsdl.a”。我没有办法告诉 -l 更喜欢静态而不是共享库,相信我,我已经看过了。
【讨论】:
想了想,还是打算用静态链接来分发吧。如果我无论如何都要分发动态库,那会破坏使用它们的几个目的,所以我不妨避免处理动态加载器的痛苦。 4.使用上面的选项 2.,将框架放在您的 .app 包(.dmg 文件)中,并使用 install_name_tool 更改可执行文件所需的路径。以下是一些如何使用 install_name_tool 的示例:qt-project.org/doc/qt-4.8/deployment-mac.html。迪特里希,你能把这个加入你的答案吗? @MilanBabuškov:看起来这已经包含在下面的答案中了。我认为没有必要重复信息。 @DietrichEpp,是的,但它没有解释如何做到这一点,即确切的命令是什么。况且,这只是一个评论,没必要吹毛求疵。 这不是吹毛求疵。你让我做某事,我说不,我解释了原因。【参考方案3】:静态链接库。
【讨论】:
静态链接库算作“代码重用”,因为无论有多少应用程序最终使用它,库代码仍然只需要编写/测试/调试一次。虽然编译后的代码的多个副本确实可能最终会出现在用户的磁盘上,但这已经不像以前那样大,因为现在硬盘驱动器太大了。以上是关于如何分发带有依赖库的 Mac OS X?的主要内容,如果未能解决你的问题,请参考以下文章