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

问题描述:

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

+4

使用`otool -L app`检查应用程序的依赖关系。如果它们被硬编码为绝对路径,那么使用`install_name_tool -change old new file`修改它们成为相对路径。之后,链接器可能会在您的`DYLD_LIBRARY_PATH`环境变量中找到一个库。 – aponomarenko 2011-01-24 08:57:21

如果dylib是由库的install_name的指定的地方,都可以正常运行*。

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

*)是完全准确的,它需要在DYLD_ROOT_PATH/install_name的,但DYLD_ROOT_PATH大惊小怪是非常罕见的。

+0

对不起,什么是“图书馆的INSTALL_NAME”?我添加DYLD_LIBRARY_PATH,它不起作用,所以很困惑。 – 2011-01-13 06:06:12

+0

您需要导出变量:export DYLD_LIBRARY_PATH =/usr/local/lib` – Michel 2014-11-12 09:14:01

您需要设置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. 
+0

谢谢!我也通过谷歌找到了这个,我确实设置了DYLD_LIBRARY_PATH,但是,它不起作用,问题仍然存在!我很困惑 – 2011-01-13 05:36:08

读取贾斯汀提供的链接后,我能够成功地使用@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 /../ Frameworks/Foo.framework/Versions/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目录/转换及其dylibs是的/ 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目录目录的dylibs,所以我们仅抽出dylibs在/选择 。我想保留所有其他dylib引用,特别是/usr/lib/libSystem的东西。

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

将可执行文件引用的所有dylib复制到可执行文件被复制到的相同dir。

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

使用install_name_tool改变所有我们在上述步骤拉出dylibs的安装名称,并在前面加上@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) 
    ...