为什么在Mac OS X中,Mach-O库需要使用install_name_tool和otool工具?

42
我正在使用最新版本的 Xcode 4 开发 Cocoa 应用程序,希望将动态库 (dylibs) 链接到我的项目中。
我在某个地方读到,仅将库添加到项目中是不够的,因为我还必须运行 install_name_toolotool,以使我的项目使用打包在项目中的库。
我已阅读了 install_name_tool 的手册页面,但不理解为什么需要这样做。
库如何工作?特别是应用程序和库具有指向机器上特定位置的路径,例如在运行 otool -L 时出现的路径 /usr/local/lib/mylibrary.dylib 的那部分,我特别感兴趣。
2个回答

73

苹果有几种定位共享库的方法:

  1. @executable_path :相对于主可执行文件
  2. @loader_path :相对于引用二进制文件
  3. @rpath :相对于路径列表中的任何一个路径。

@rpath 是最近加入的,自OS X 10.5起引入。

例如,如果您想在 Contents/MacOS 中拥有可执行文件并在 Contents/Libraries 中拥有库,则可以按照以下方式操作:

install_name_tool -id @rpath/Libraries/lib_this.dylib   builddir/lib_this.dylib

在顶级可执行文件中,使用以下命令设置rpath

install_name_tool -add_rpath @loader_path/..  myexecutable

并且:

install_name_tool -change builddir/lib_this.dylib @rpath/Libraries/lib_this.dylib myexecutable

注意:-change 后的第一个路径必须与二进制文件中当前的完全匹配。

如果你迷失了方向,otool -l -v myexecutable 可以告诉你目前可执行文件中确切存在哪些加载命令。

有关更多信息,请参见 man dyldman install_name_tool


otool -L 也很有帮助,可以显示名称和共享库(您可能需要使用 install_name_tool 更改)。 - par
7
注意:install_name_tool 会静默失败;务必使用“otool -L <path_to_dylib>”命令双重检查它是否实际执行了你要求的操作。 - geowar
1
似乎 dylib 中的属性并不重要。它们仅在将可执行文件链接到 dylib 以从 dylib 复制属性时使用。 如果您已经将可执行文件链接到 dylib,但需要更改路径,则只需编辑可执行文件即可设置 LC_LOAD_DYLIB 和(可选)LC_RPATH。如果第一个中有 @rpath,则需要第二个。 - v.shashenko
挽救我的部分是:“注意:-change后的第一个路径必须与二进制文件中当前路径完全匹配。”我没有意识到需要包含在otool -L转储中显示的完整路径。在我的情况下,该路径为/usr/local/lib/libcrypto.1.1.dylib,如果我只使用libcrypto.1.1.dylib作为参数,则无法正常工作。 - M Katz

12

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接