如何使用独立的库分发Mac OS X ?

时间:2023-01-13 00:02:06

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).

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

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.

我如何分发我的程序,以便没有安装这些库的人能够开箱即用地运行它?显然,我将不得不分发各种.dylib文件,但是这样做是不够的。动态加载程序仍然在我安装它们的位置查找已安装的库。是否有一种方法可以告诉动态加载程序在可执行文件的当前目录中查找,比如Windows对dll做什么?人们不需要修改任何环境变量(例如DYLD_LIBRARY_PATH),因为我同样希望它能在开箱即用的情况下工作。

3 个解决方案

#1


5  

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

正如您提到的,您没有使用Xcode,所以这有点困难。以下是我的选择顺序:

  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.

    切换到Xcode。使用框架。SDL库已经可以作为框架使用了,我已经看到了一些在应用包中包含libsdl.framework的商业游戏。

  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.

    使用框架,但保留makefile。下载您的SDL库的框架版本(或者您自己构建它们),并使用-framework链接器标记与它们链接。用你的应用发布框架,或者不发布,告诉你的用户把它们放在~/Library/ framework中,或者放在/Library/ framework中。我不会为此而麻烦安装程序。

  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.

    对SDL静态链接。在Makefile中,您必须列出静态库的路径,而不是使用-l标志,例如,您运行“ld blah /opt/local/lib/libsdl.a”。我不知道要告诉-l喜欢静态而不是共享库,相信我,我已经看过了。

#2


13  

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.

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

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.

    为目标创建一个新的复制文件构建阶段,将这些文件复制到.app bundle的框架目录中。

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

    编辑构建配置设置“Runpath搜索路径”以包含@executable_path/. /框架

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.

如果您使用这些更改构建可执行文件,然后查看,您应该会发现dylibs存在于Foo中。app/内容/框架目录,运行otool -L Foo。应用/内容/MacOS/Foo应该为那些dylibs提供以@rpath为前缀的输出和输入。

From this Cocoabuilder post:

从这个Cocoabuilder帖子:

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.

一般来说,与@executable_path相比,@loader_path更可取,因为它允许嵌入框架在可执行文件和包、插件或子框架中工作。唯一的缺点是@loader_path需要10.4或更新。如果您使用的是10.5或更新版本,@rpath甚至比@loader_path还要好。

#3


3  

Statically link the libraries.

静态链接库。

#1


5  

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

正如您提到的,您没有使用Xcode,所以这有点困难。以下是我的选择顺序:

  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.

    切换到Xcode。使用框架。SDL库已经可以作为框架使用了,我已经看到了一些在应用包中包含libsdl.framework的商业游戏。

  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.

    使用框架,但保留makefile。下载您的SDL库的框架版本(或者您自己构建它们),并使用-framework链接器标记与它们链接。用你的应用发布框架,或者不发布,告诉你的用户把它们放在~/Library/ framework中,或者放在/Library/ framework中。我不会为此而麻烦安装程序。

  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.

    对SDL静态链接。在Makefile中,您必须列出静态库的路径,而不是使用-l标志,例如,您运行“ld blah /opt/local/lib/libsdl.a”。我不知道要告诉-l喜欢静态而不是共享库,相信我,我已经看过了。

#2


13  

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.

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

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.

    为目标创建一个新的复制文件构建阶段,将这些文件复制到.app bundle的框架目录中。

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

    编辑构建配置设置“Runpath搜索路径”以包含@executable_path/. /框架

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.

如果您使用这些更改构建可执行文件,然后查看,您应该会发现dylibs存在于Foo中。app/内容/框架目录,运行otool -L Foo。应用/内容/MacOS/Foo应该为那些dylibs提供以@rpath为前缀的输出和输入。

From this Cocoabuilder post:

从这个Cocoabuilder帖子:

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.

一般来说,与@executable_path相比,@loader_path更可取,因为它允许嵌入框架在可执行文件和包、插件或子框架中工作。唯一的缺点是@loader_path需要10.4或更新。如果您使用的是10.5或更新版本,@rpath甚至比@loader_path还要好。

#3


3  

Statically link the libraries.

静态链接库。