【问题标题】:How to properly set run paths, search paths, and install names?如何正确设置运行路径、搜索路径和安装名称?
【发布时间】:2012-04-05 14:49:45
【问题描述】:

我有一组项目,我正在编译为动态库。这些 .dylib 中的每一个都依赖于我想放置在各种其他目录中的其他各种 .dylib(即,一些在可执行路径,一些在加载器路径,一些在固定路径)。

当我在已编译的库上运行 otool -L 时,我得到了这些依赖项的路径列表,但我知道这些路径是如何设置/确定的。它们几乎看起来是伪随机的。我花了几个小时弄乱 Xcode 中的“构建设置”来尝试更改这些路径(w/@rpath、@executable_path、@loader_path 等),但我似乎无法更改任何内容(通过运行 @ 检查987654322@)。我什至不完全确定在哪里添加这些标志,也不太了解以下内容之间的区别或如何正确使用它们:

链接 - “动态库安装名称”
链接 - “运行路径搜索路径”
链接 - “其他链接标志”
搜索路径 - “库搜索路径”

当我在各种库上运行install_name_tool -change 时,我能够成功更改运行路径搜索路径(再次通过运行otool -L 进行验证以确认)。

我正在运行 Xcode 4.2,我非常接近放弃,只使用运行 install_tool_name 的构建后脚本进行更改。但它是一个 kludge hack 修复,我不想这样做。

在哪里可以看到如何设置 dylib 依赖项的搜索/运行路径?
有人对我可能做错了什么有任何想法吗?

【问题讨论】:

    标签: xcode macos xcode4.2 dylib dyld


    【解决方案1】:

    通常,在我的 dylib 的目标中,我将 INSTALL_PATH 又名“安装目录”设置为我想要的前缀(例如 @executable_path/../Frameworks)。

    我将LD_DYLIB_INSTALL_NAME 又名“动态库安装名称”设置为其默认值,即$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)

    Xcode 会根据您的目标名称对其进行扩展,因此它最终可能是 @executable_path/../Frameworks/MyFramework.framework/Versions/A/MyFramework,例如。

    要意识到的重要一点是,安装路径是内置 dylib,作为其构建过程的一部分。稍后,当您链接指向 A.dylib 的 B.dylib 时,A.dylib 的安装路径会复制到 B.dylib。 (这就是 otool 向您展示的内容——那些复制的安装路径。)所以最好首先将正确的安装路径内置到 dylib 中。

    在尝试让所有 dylib 一起工作之前,请分别检查每一个。构建它,然后在构建的 dylib 上 otool -L。每个架构的第一行应该是 LD_DYLIB_INSTALL_NAME 向您展示的内容。

    一旦你组织好了,试着让 dylib 相互链接。它应该更简单。

    【讨论】:

    • 虽然不是我正在寻找的确切答案,但这有助于我确定我的问题。 otool -L 列出所有安装名称。列出的第一个“安装名称”是库本身的名称。列出的任何其他路径都用于其依赖项。假设您已经从源代码编译了依赖项,在 Xcode 中设置“动态库安装名称”将正确设置这些路径。但是在我的情况下,依赖项来自第 3 方,因此路径已经设置。由于我无法控制第 3 方库的编译,我不得不使用 install_name_tool -change
    • @KurtRevis,假设我正在为软件构建一个插件(基本上是一个 DyLib 本身)。我根据编译器拥有的 libiomp5.dylib 构建它。然而主机程序本身也有它。如何告诉我的插件在主机中搜索它(我可以知道来自@executable_path 的路径)?谢谢。
    • 我在这里写了一个关于它的问题 - stackoverflow.com/questions/40318465/…。谢谢。
    【解决方案2】:

    install_name_tool 对于设置名称和路径非常有用。如果程序在构建目录中运行自检,然后在make install 期间发生变化,则它特别有用。在这种情况下,您可以使用 install_name_tool 而无需单独构建。

    install_name_tool 也很有用,因为 Apple 的 LD 不像 Linux/GCC 那样支持 rpath 链接器选项。也就是说,您需要使用一组不同的命令来设置它们。

    这是它的手册页。之所以完整包含它,是因为它讨论了其他选项,例如 -headerpad_max_install_names

    INSTALL_NAME_TOOL(1)                                      INSTALL_NAME_TOOL(1)
    
    NAME
           install_name_tool - change dynamic shared library install names
    
    SYNOPSIS
           install_name_tool  [-change  old  new  ]  ...  [-rpath  old  new  ] ...
           [-add_rpath new ] ... [-delete_rpath new ] ... [-id name] file
    
    DESCRIPTION
           Install_name_tool changes the dynamic shared library install names  and
           or  adds,  changes  or  deletes the rpaths recorded in a Mach-O binary.
           For this tool to work when the install names or rpaths are  larger  the
           binary  should  be  built  with  the ld(1) -headerpad_max_install_names
           option.
    
           -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.
    
           -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.
    
           -rpath old new
                  Changes the rpath path 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 rpath path name in  a
                  specified -rpath it is an error.
    
           -add_rpath new
                  Adds  the  rpath  path  name new in the specified Mach-O binary.
                  More than one of these options can be specified.  If the  Mach-O
                  binary  already  contains  the  new rpath path name specified in
                  -add_rpath it is an error.
    
           -delete_rpath old
                  deletes the rpath path name old in the specified Mach-O  binary.
                  More  than one of these options can be specified.  If the Mach-O
                  binary does not contains the old rpath path  name  specified  in
                  -delete_rpath it is an error.
    
    SEE ALSO
           ld(1)
    

    【讨论】:

      猜你喜欢
      • 2020-02-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2016-12-05
      • 2012-08-31
      • 1970-01-01
      • 2021-02-24
      相关资源
      最近更新 更多