【问题标题】:How to distribute a Mac OS X with dependent libraries?如何分发带有依赖库的 Mac OS X?
【发布时间】:2010-12-01 17:54:46
【问题描述】:

我有一个程序(特别是我的 SO DevDays Countdown app challenge 条目),它依赖于几个动态库,即 libSDL、libSDL_ttf 等。我通过 MacPorts 在/opt/local/lib 下安装了这些库,许多人不会安装这些库(有些人可能安装了它们,但不是在那个位置)。

如何分发我的程序,以便没有安装这些库的人可以开箱即用地运行它?显然我必须分发各种.dylib 文件,但这样做是不够的。动态加载程序仍会查找安装在我安装它们的位置的库。有没有办法告诉动态加载器查看可执行文件的当前目录,就像 Windows 对 DLL 所做的那样?人们不应该修改任何环境变量(例如DYLD_LIBRARY_PATH),因为我希望它能够开箱即用。

【问题讨论】:

    标签: macos software-distribution dynamic-linking dyld


    【解决方案1】:

    对此的基本方法是将它们放在 .app 包中。然后,您将修改链接器查找共享库的位置以包含此内容。

    步骤如下:

    1. 为您的目标创建一个新的复制文件构建阶段,将这些文件复制到 .app 包的 Frameworks 目录中。

    2. 编辑构建配置设置“运行路径搜索路径”以包含@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,所以这有点困难。以下是按我的偏好顺序排列的选项:

    1. 切换到 Xcode。使用框架。 SDL 库已经作为框架提供,而且我见过不止几个商业游戏在应用程序包中包含 libsdl.framework。

    2. 使用框架,但保留您的 Makefile。下载您的 SDL 库的框架版本(或自己构建它们),并使用 -framework 链接器标志与它们链接。将框架与您的应用一起分发或不分发,并告诉您的用户将它们放在 ~/Library/Frameworks 或 /Library/Frameworks 中。我不会为此烦恼安装程序。

    3. 针对 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】:

    静态链接库。

    【讨论】:

    • 静态链接库算作“代码重用”,因为无论有多少应用程序最终使用它,库代码仍然只需要编写/测试/调试一次。虽然编译后的代码的多个副本确实可能最终会出现在用户的磁盘上,但这已经不像以前那样大,因为现在硬盘驱动器太大了。
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2012-02-23
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 2017-12-25
    • 2013-02-07
    • 1970-01-01
    相关资源
    最近更新 更多