Ako*_* Cz 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.如果您打算在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
我将举例说明.
假设我有以下可执行文件/ opt/local/bin/convert,其dylib位于/ opt/local/lib中.我想将它复制到另一个目录并让它从我复制可执行文件的目录中加载其dylib.
> mkdir ~/tmp/bin
> cp /opt/local/bin/convert ~/tmp/bin
Run Code Online (Sandbox Code Playgroud)
获取可执行文件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)
...
Run Code Online (Sandbox Code Playgroud)
我只关心/ opt/local/lib目录中的dylib,所以我们只在/ opt中提取dylib .我想保持所有其他dylib引用完整,特别是/ usr/lib/libSystem的东西.
> DYLIBS=`otool -L ~/tmp/bin/convert | grep "/opt" | awk -F' ' '{ print $1 }'`
Run Code Online (Sandbox Code Playgroud)
将可执行文件引用的所有dylib复制到已复制可执行文件的同一目录.
> for dylib in $DYLIBS; do cp $dylib ~/tmp/bin/; done;
Run Code Online (Sandbox Code Playgroud)
使用它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;
Run Code Online (Sandbox Code Playgroud)
确认安装名称已更改,并且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)
...
Run Code Online (Sandbox Code Playgroud)
Eme*_*ger 14
您需要设置DYLD_LIBRARY_PATH环境变量.
从dyld手册页:
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.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
71669 次 |
| 最近记录: |