如何分发带有依赖库的 Mac OS X?

发布于 2024-08-06 02:57:03 字数 477 浏览 5 评论 0原文

我有一个计划(特别是我的 SO DevDays Countdown 应用挑战) 它依赖于几个动态库,即 libSDL、libSDL_ttf 等。我通过 MacPorts 将这些库安装在 /opt/local/lib 下,许多人不会安装这些库(有些人可能安装了它们,但没有安装在该位置)。

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

I have a program (specifically my entry for the SO DevDays Countdown app challenge) which relies on several dynamic libraries, namely libSDL, libSDL_ttf, and others. I have these libraries installed under /opt/local/lib via MacPorts, and many people won't have these installed (and some might have them installed, but not at that location).

How do I distribute my program so that people without these libraries installed can run it out-of-the-box? Obviously I'll have to distribute the various .dylib files, but doing this is insufficient. The dynamic loader still looks for the libraries installed at the locations I have them installed at. Is there a way to tell the dynamic loader to look in the current directory of the executable, like what Windows does with DLLs? People shouldn't have to modify any environment variables (e.g. DYLD_LIBRARY_PATH), since again I want this to work out-of-the-box.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凡间太子 2024-08-13 02:57:03

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

步骤如下:

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

  2. 编辑构建配置设置“运行路径搜索路径”以包含 @executable_path/../Frameworks

如果您使用这些更改构建可执行文件,然后查看,您应该发现 dylib 存在于 Foo.app/Contents/Framework 目录中并正在运行 otool -L Foo.app/Contents/MacOS/Foo 应该为这些 dylib 生成并以 @rpath 为前缀的条目。

从这个 Cocoabuilder 帖子

一般来说,@loader_path 优于 @executable_path,因为它
允许嵌入式框架在可执行文件和捆绑包中工作,
插件或子框架。唯一的缺点是 @loader_path
需要 10.4 或更高版本。如果您使用的是 10.5 或更高版本,@rpath 是偶数
@loader_path 更好。

The basic approach to this is to ship them in the .app bundle. You'll then modify the location the linker looks for shared libraries to include this.

The steps are:

  1. Create a new copy files build phase to your target that copies those files into the Frameworks directory of the .app bundle.

  2. Edit the build configuration setting "Runpath Search Paths" to include @executable_path/../Frameworks

If you build your executable with these changes and then look, you should find that the dylibs exist in the Foo.app/Contents/Framework directory and running otool -L Foo.app/Contents/MacOS/Foo should yield and entry prefixed by @rpath for those dylibs.

From this Cocoabuilder post:

In general, @loader_path is preferred over @executable_path, as it
allows embedded frameworks to work in both an executable and a bundle,
plugin, or sub-framework. The only downside is that @loader_path
requires 10.4 or newer. If you're on 10.5 or newer, @rpath is even
better than @loader_path.

情定在深秋 2024-08-13 02:57:03

正如您提到的,您没有使用 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 更喜欢静态而不是共享库,相信我,我已经看过了。

As you mentioned you're not using Xcode, so it's a bit difficult. Here are options in my order of preference:

  1. Switch to Xcode. Use frameworks. The SDL libraries are available as frameworks already, and I've seen more than a couple commercial games with a libsdl.framework inside the app bundle.

  2. Use frameworks, but keep your Makefiles. Download the framework versions of your SDL libraries (or build them yourself), and link with them with the -framework linker flag. Distribute the frameworks with your app or don't, and tell your users to put them in either ~/Library/Frameworks or in /Library/Frameworks. I wouldn't bother with an installer for this.

  3. Statically link against SDL. In the Makefile, you'll have to list the path of the static libraries rather than use the -l flag, e.g., you run "ld blah blah /opt/local/lib/libsdl.a". There is no way that I know to tell -l to prefer static over shared libraries, and believe me, I've looked.

救赎№ 2024-08-13 02:57:03

静态链接库。

Statically link the libraries.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文