Xcode 安装\u name\u工具-change和-id之间的差异

Xcode 安装\u name\u工具-change和-id之间的差异,xcode,macos,otool,install-name-tool,Xcode,Macos,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

我已经为这个概念挣扎了一段时间,我无法真正理解
-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.
到目前为止,我已经尝试了
-change
。假设我有以下结构

Test.App
|_Contents
    |_MacOS
    |   |_test -----> item A
    |_Library
        |_test_library.dylib     --->item B
        |_another_library.dylib  --->item C
现在假设我在itemB上运行以下命令

$ otool -L test_library.dylib
   test_library.dylib
   /some/path/another_library.dylib  -->item D
上面的结果表明,
test_library.dylib
依赖于另一个_library.dylib现在如果我需要更改另一个_library.dylib的位置,我会这样做

install_name_tool -change /some/path/another_library.dylib some/new/path/another_library.dylib  test_library.dylib 
这将更改项目D的位置。我的问题是
install-name\u tool-id
做什么?我什么时候使用它?

install-name 术语install name指的是最终用户系统中
.dylib
文件的确切路径,因此运行时链接器可以查找并加载动态库

名称可以是:

  • 绝对值,这是系统库的情况。它们在最终用户和开发人员的系统上都位于同一位置
  • 相对的,这是与应用程序捆绑在一起的库的情况。在最终用户的系统上,
    .dylib
    将嵌入到应用程序包中,而在开发人员系统上,它们将预构建在
    /usr/local
    /opt/local
    或其他地方,或者作为应用程序构建的一部分从源代码构建
后者是主要的问题,因为当构建
.dylib
时,链接器会将其安装名称压印到
.dylib
中,而这正是在运行时查找和加载它的地方。显然,这在最终用户系统上不起作用,因为该路径只存在于开发人员的系统上,因此解决方案是在将应用程序捆绑包放在一起时,使用
install\u name\u tool
修改库的安装名称以及引用这些库的可执行文件

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

  • @executable\u path
    :主可执行文件的完整路径
  • @loader\u path
    :引用可执行文件或
    .dylib
    的完整路径
  • @rpath
    :在主可执行文件中设置的rpath。也可以使用
    install\u name\u tool
    更改此设置
例如,在macOS应用程序包中,可执行文件位于app.app/Contents/macOS/TheApp中,库位于app.app/Contents/Frameworks中,因此您希望使用路径
@executable\u path/./Frameworks/Library.dylib
引用库

但是,最好将主可执行文件的RPATH设置为
@executable\u path/./Frameworks
,并使用
@RPATH/Library.dylib
引用库

安装\u name\u工具
install\u name\u工具
有两个主要选项:

-id
:这将设置
.dylib
文件本身的安装名称,并将在与
.dylib
链接时从该点起用作原型安装名称。在构建
.dylib
之后,您可以立即“更正”安装名称,但是这是一个不同寻常的工作流,因为库如何知道使用它的环境

-change
:这将更改引用可执行文件(或dylib)中
.dylib
的安装名称

-id
名称与
-change
名称不匹配时会发生什么情况?没有什么。
-change
选项非常重要,因为一旦运行时链接器找到了
.dylib
,任务就完成了

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

install\u name\u工具-id
用于更改
dylib
安装名称
,您可以使用
otool-D
查看终端中的dylib
安装名称
,它将为您显示默认值,
/some/path/other_library.dylib
other_library.dylib
的默认
安装名称
,当然,您可以在终端中使用
install_name_tool-id
对其进行更改,只需在终端中这样使用即可

install_name_tool -id /some/path/another_library_newname.dylib /some/path/another_library.dylib
现在,您使用
otool-D/some/path/other_library.dylib
,您会发现
安装名称是
/some/path/other_library\u newname.dylib


下面是我在

中的示例,id
在链接时使用,而
安装名称
在运行时使用。它们都是为链接器提供的信息,以定位动态库。我遵循了这一点

我举个例子,

$cat a.cc
#包括

作废{std::cout你是说当我们在/Contents/MacOS/?@MistyD内的主可执行文件上更改内容时使用-id吗?不,你会使用
-change
。所以我仍然不知道什么时候使用-change?你有什么文章可以解释吗this@MistyD“不,对不起,我没有。”米斯蒂德晚了一点,但我决定重做我的answ呃。