我想使用 install_name_tool 更改可执行文件的 rpath,但我现在不知道 rpath 是什么。 install_name_tool 要求在命令行上同时提供旧的和新的 rpath。我可以使用什么命令在 macOS 下打印可执行文件的 rpath?

最佳答案

首先,要了解可执行文件不包含单个 rpath 条目,而是包含一个或多个条目的数组。
其次,您可以使用 otool 列出图像的 rpath 条目。使用 otool -l ,您将获得如下输出,在其末尾是 rpath 条目:

Load command 34
          cmd LC_LOAD_DYLIB
      cmdsize 88
         name /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1038.32.0
compatibility version 45.0.0

Load command 35
          cmd LC_RPATH
      cmdsize 40
         path @loader_path/../Frameworks (offset 12)
查找 LC_RPATH 命令并记下 path 条目下的路径。
编辑:关于 @loader_path 是什么:它是引用想要加载框架的 Mach-O 对象的通用和动态方式。
虽然这是一个相当人为的例子,但我认为它应该能说明问题。假设我们有一个应用程序 MyApp.app 使用框架 MyFramework.framework 。我们还会说,要正常运行,我需要将我的应用程序安装在/Applications 中而不是其他任何地方。因此,所述应用程序和框架的结构如下:/Applications/MyApp.app/Contents/MacOS/MyApp(可执行)/Applications/MyApp.app/Contents/Frameworks/MyFramework.framework/MyFramework (Mach-O dylib)
如果我们在可执行文件上运行 otool -L(注意大写 L),它将显示以下关于 MyFramework 的信息:
@rpath/MyFramework.framework/Versions/A/MyFramework
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
/usr/lib/libobjc.A.dylib
/usr/lib/libSystem.B.dylib
....
请注意,因为 MyFramework.framework 使用 @rpath 安装名称/路径,我们需要运行时搜索路径条目将在运行时替换 @rpath。现在,我可以有一个 rpath 条目:
/Applications/MyApp.app/Contents/Frameworks
这会起作用,并且在运行时这两部分将放在一起:/Applications/MyApp.app/Contents/Frameworks + /MyFramework.framework/Versions/A/MyFramework ==
/Applications/MyApp.app/Contents/Frameworks/MyFramework.framework/Versions/A/MyFramework
显然,像这样硬编码路径并不理想,因为简单地将应用程序移动到不同的文件夹或重命名应用程序本身会导致链接失败。@loader_path 只是一种动态方式,用于在文件系统上可能存在的任何位置引用应用程序的可执行文件。在这种特殊情况下,在运行时,它将填充到正在运行的可执行文件的路径: /Applications/MyApp.app/Contents/MacOS/MyApp 。然后我们可以说要找到 MyFramework.framework,您只需上一个目录并转到 Frameworks

关于macos - 在 macOS 上打印可执行文件的 rpath,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12521802/

10-13 09:35