c++ - 如何在 Mac OS X (C++) 中使用 dylib

标签 c++ macos build load dylib

我创建了一个应用程序(一个可执行文件),成功调用了一些 dylib。但是,dylib 文件和可执行文件位于不同的目录中。我将包含 dylib 文件的目录添加到 $PATH 环境变量中。但是,它仍然无法加载。我将所有dylib文件复制到可执行文件中,程序终于运行了。这确认 dylib 文件没有问题。但是,我怎样才能告诉操作系统找到它呢?
在 Windows 中,我只需要将包含 dll 文件的目录路径添加到 $PATH。对于 Mac OS X,我需要做什么?

最佳答案

阅读 Justin 提供的链接后,我成功地使用 @executable_path token 将我的 dylib install_name 更改为指向我的可执行文件所在的同一目录。

@executable_path Absolute paths are annoying. Sometimes you want to embed a framework into an application instead of having to install the framework into /Library or a similar location.

The Mac's solution to this is @executable_path. This is a magic token that, when placed at the beginning of a library's install name, gets expanded to the path of the executable that's loading it, minus the last component. For example, let's say that Bar.app links against Foo.framework. If Bar.app is installed in /Applications, @executable_path will expand to /Applications/Bar.app/Contents/MacOS. If you intend to embed the framework in Contents/Frameworks, then you can just set Foo.framework's install name to @executable_path/../Frameworks/Foo.framework/Versions/A/Foo. The dynamic linker will expand that to /Applications/Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Foo and will find the framework there.

http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html

我会用一个例子来演示。

假设我有以下可执行文件 /opt/local/bin/convert,它的 dylib 位于 /opt/local/lib 中。 我想将它复制到另一个目录,并让它从与我复制可执行文件的目录相同的目录中加载它的 dylib。

> mkdir ~/tmp/bin
> cp /opt/local/bin/convert ~/tmp/bin

获取可执行文件dylib的列表

> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
    /opt/local/lib/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
    /opt/local/lib/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
    /opt/local/lib/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
    /opt/local/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
    /opt/local/lib/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
    /opt/local/lib/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
    /opt/local/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
    /opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
    ...

我只关心 /opt/local/lib 目录中的 dylib,所以我们只提取 /opt 中的 dylib。我想保持所有其他 dylib 引用完整,尤其是对 /usr/lib/libSystem 的东西。

> DYLIBS=`otool -L ~/tmp/bin/convert | grep "/opt" | awk -F' ' '{ print $1 }'`

将可执行文件引用的所有 dylib 复制到可执行文件已复制到的同一目录。

> for dylib in $DYLIBS; do cp $dylib ~/tmp/bin/; done;

使用 install_name_tool 更改我们在上述步骤中提取的所有 dylib 的安装名称,并通过在 dylib 名称前添加 @executable_path 来替换它们。这将使动态链接器在与可执行文件所在的目录相同的目录中查找 dylib。

> for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` ~/tmp/bin/convert; done;

确认安装名称已更改,并且 libSystem 仍指向 /usr/lib/libSystem

> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
    @executable_path/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
    @executable_path/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
    @executable_path/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
    @executable_path/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
    @executable_path/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
    @executable_path/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
    @executable_path/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
    @executable_path/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
    ...

关于c++ - 如何在 Mac OS X (C++) 中使用 dylib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4677044/

相关文章:

xcode - 当 NSMenu 在 Swift 中打开时,NSTimer 不会触发

swift - 如何防止Mac菜单栏应用失去焦点?

visual-studio-2008 - 在 Visual Studio 2008 中将 Fxcop 错误显示为编译错误

facebook - React-tools JSX 编译嵌套文件夹错误

c++ - 依赖于编译器的OpenMP最小/最大减少编译指示

c++ - 无法在 Microsoft Visual Studio 中打开 Windows.h

macos - Homebrew 把二进制文件放在哪里?

css - 在构建 VITE 应用程序时如何分配自定义 CSS 文件名?

c++ - 将值从一个类传递到另一个类。单独的 cpp 文件。 C++

c++ - 为什么我的迭代次数少于预期?