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

时间:2011-01-13 05:21:33

标签: c++ macos build load dylib

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

4 个答案:

答案 0 :(得分:38)

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

  

@executable_path 绝对路径很烦人。有时您希望将框架嵌入到应用程序中而不必安装   框架进入/ Library或类似的位置。

     

Mac的解决方案是@executable_path。这是一个神奇的标记   获取,当放置在库的安装名称的开头时   扩展到正在加载它的可执行文件的路径,减去   最后一个组件例如,假设Bar.app链接   Foo.framework。如果Bar.app安装在/ Applications中,   @executable_path将扩展为/Applications/Bar.app/Contents/MacOS。   如果您打算在内容/框架中嵌入框架,那么您   可以将Foo.framework的安装名称设置为   @executable_path /../框架/ Foo.framework /版本/ A /的Foo。该   动态链接器将扩展到   /Applications/Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Foo   并将在那里找到框架。

     
    

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

获取可执行文件列表dylibs

> 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的安装名称,并通过将@executable_path添加到dylib名称来替换它们。这将使动态链接器在与可执行文件所在目录相同的目录中查找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)
    ...

答案 1 :(得分:14)

您需要设置DYLD_LIBRARY_PATH环境变量。

来自dyld man page

      This  is  a  colon  separated  list  of directories that contain libraries. The dynamic linker
      searches these directories before it searches the default locations for libraries.  It  allows
      you to test new versions of existing libraries.

      For  each  library  that  a program uses, the dynamic linker looks for it in each directory in
      DYLD_LIBRARY_PATH in turn. If it still can't find the library,  it  then  searches  DYLD_FALL-
      BACK_FRAMEWORK_PATH and DYLD_FALLBACK_LIBRARY_PATH in turn.

答案 2 :(得分:6)

答案 3 :(得分:2)

如果dylib位于库的INSTALL_NAME指定的位置,它将正常工作*。

否则,您可以将dylib的位置添加到DYLD_LIBRARY_PATH。您可能需要阅读dyld documentation

*)要完全准确,它需要在DYLD_ROOT_PATH / INSTALL_NAME,但是DYLD_ROOT_PATH非常罕见。