阅读 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
获取可执行文件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)
...