install_name_tool -change 和 -id 之间的区别

Mis*_*tyD 10 macos xcode otool install-name-tool

我已经在这个概念上挣扎了一段时间,我无法真正理解-change和之间的区别-id。手册页指出

 -id name
              Changes  the  shared  library identification name of a dynamic shared library to name.  If the Mach-O binary is not a dynamic
              shared library and the -id option is specified it is ignored.

-change old new
              Changes  the dependent shared library install name old to new in the specified Mach-O binary.  More than one of these options
              can be specified.  If the Mach-O binary does not contain the old install name in a specified -change  option  the  option  is
              ignored.
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经尝试过-change. 假设我有以下结构

Test.App
|_Contents
    |_MacOS
    |   |_test -----> item A
    |_Library
        |_test_library.dylib     --->item B
        |_another_library.dylib  --->item C
Run Code Online (Sandbox Code Playgroud)

现在假设我在 itemB 上运行了以下内容

$ otool -L test_library.dylib
   test_library.dylib
   /some/path/another_library.dylib  -->item D
Run Code Online (Sandbox Code Playgroud)

上面的结果表明,现在test_library.dylib取决于another_library.dylib我是否需要改变another_library.dylib我会这样做的位置

install_name_tool -change /some/path/another_library.dylib some/new/path/another_library.dylib  test_library.dylib 
Run Code Online (Sandbox Code Playgroud)

这会改变项目 D 的位置。我的问题是做什么,我什么install-name_tool -id时候使用它?

tro*_*foe 11

安装名称

术语安装名称指的是.dylib最终用户系统中文件的确切路径,以便运行时链接程序可以找到并加载动态库。

名称可以是:

  • 绝对,系统库就是这种情况。这些在最终用户和开发人员的系统上都位于同一位置。
  • 相对,这是与应用程序捆绑在一起的库的情况。在最终用户的系统.dylib将被嵌入到应用程序包和开发系统,他们将两种预建在/usr/local/opt/local或其他地方,或者他们会从源代码被编译为应用程序构建的一部分。

后者是主要问题,因为当它.dylib被构建时,它的安装名称.dylib链接器标记到其中,这就是预期在运行时被发现和加载的地方。显然这不适用于最终用户系统,因为该路径仅存在于开发人员的系统上,因此解决方案是在将应用程序包放在一起时install_name_tool修改库的安装名称以及引用这些库的可执行文件.

占位符

由于可执行文件/应用程序包可以安装在最终用户系统的不同位置,您可以使用占位符系统来抽象安装名称位置:

  • @executable_path: 主可执行文件的完整路径。
  • @loader_path: 引用可执行文件的完整路径或.dylib.
  • @rpath: 在主可执行文件中设置的 RPATH。这也可以使用install_name_tool.

因此,例如在 macOS 应用程序包中,可执行文件将在其中TheApp.app/Contents/MacOS/TheApp,库将在其中,TheApp.app/Contents/Frameworks因此您可能希望使用 path 引用库@executable_path/../Frameworks/Library.dylib

最好将主可执行文件的 RPATH 设置为@executable_path/../Frameworks然而,并使用@rpath/Library.dylib.

install_name_tool

install_name_tool 有两个主要选项:

-id:这台安装名字的的.dylib文件本身,将被用于为原型安装的名字从该点向前的时候事情链接.dylib。您可以在构建后立即“更正”安装名称.dylib,但这是一个不寻常的工作流程,因为库如何了解正在使用它的环境?

-change:这改变了安装名称.dylib一个参考可执行文件(或dylib)内。

-id名称与名称不匹配时会发生什么-change?没有。-change一旦运行时链接器发现.dylib任务完成,该选项就很重要。

xcodedevtools

您显然会使用脚本编写所有修复程序,但这有点乏味,因此我开发了copy_dylibs.py脚本来为您完成所有工作。您将其配置为在链接您的应用程序可执行文件后运行,它会查看您的可执行文件以递归查找.dylib要复制到应用程序包中的文件。然后修复它们的安装名称,保留原始.dylib文件。


Pri*_*kin 5

install_name_tool -id用于更改 的install name,您可以在终端中dylib使用otool -Dsee a dylib ,它会为您显示默认值,是默认的,当然,您可以更改它在终端中的使用,只需像这样使用终端install name/some/path/another_library.dylibinstall nameanother_library.dylibinstall_name_tool -id

install_name_tool -id /some/path/another_library_newname.dylib /some/path/another_library.dylib
Run Code Online (Sandbox Code Playgroud)

现在,你使用otool -D /some/path/another_library.dylib,你会发现install name/some/path/another_library_newname.dylib

这是我的图片示例