15

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

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

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

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

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

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

4

2 回答 2

14

通常,在我的 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 一起工作之前,请单独检查每个。构建它,然后otool -L在构建的 dylib 上。每个架构的第一行应该LD_DYLIB_INSTALL_NAME是向您展示的内容。

组织好之后,尝试让 dylib 相互链接。它应该更简单。

于 2012-03-21T05:21:49.920 回答
2

install_name_tool对于设置名称和路径非常有用。如果程序在构建目录中运行自测,然后在make install. 在这种情况下,您install_name_tool无需单独构建即可使用。

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

这是它的手册页。之所以完整包含它,是因为它讨论了其他选项,例如-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)
于 2015-12-21T02:01:16.837 回答