我制作了一个应用程序(一个可执行文件),成功调用了一些动态链接库(dylib)。但是,这些dylib文件和可执行文件在不同的目录中。我将包含dylib文件的目录添加到$PATH
环境变量中,但它仍然无法加载。当我将所有dylib文件复制到可执行文件所在的目录时,程序终于运行了。这证实了dylib文件没有问题。但是,我该如何告诉操作系统去查找它呢?
在Windows中,我只需要将包含dll文件的目录路径添加到$PATH中。对于Mac OS X,我需要做什么呢?
@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。如果您打算将框架嵌入Contents/Frameworks中,则可以将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
我将举例说明。> mkdir ~/tmp/bin
> cp /opt/local/bin/convert ~/tmp/bin
> 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)
...
> DYLIBS=`otool -L ~/tmp/bin/convert | grep "/opt" | awk -F' ' '{ print $1 }'`
> 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)
...
您需要设置DYLD_LIBRARY_PATH
环境变量。
根据dyld man页面:
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.
export
。详情请参见此处:http://stackoverflow.com/a/8699244/402807 - AlcubierreDrive
otool -L app
检查您的应用程序的依赖项。如果它们是硬编码为绝对路径,则使用命令install_name_tool -change old new file
修改它们以变成相对路径。然后,链接器可能会在您的DYLD_LIBRARY_PATH
环境变量中找到一个库。 - linuxbuild