分布式dylib的链接器设置

Linker setting for distributed dylib

我正在努力寻找 XCode 中的正确选项以在我的应用程序中包含 dylib。我在 /usr/local/lib 中确实有一个 dylib,我的应用确实需要它。只要我在Lib Search Paths

中设置这个路径

一切正常。但是我当然想在我的应用程序中分发 dylib,这就是我将它添加到复制阶段的原因:

这确实将 dylib 复制到应用程序的 Frameworks 文件夹中。但是 运行ning 在目标系统上,应用程序没有找到 dylib。它甚至没有在 /usr/local/lib 中找到它。相反,它嘎嘎作响:

Dyld Error Message:

Library not loaded: @rpath/libopencv_imgproc.3.2.dylib

那么,需要设置哪个选项呢?

编辑 我整理了一个示例项目here。它包含 3 个 zip:一个项目,一个 headers 放在 /usr/local/include 中,一个动态库放在 /usr/local/lib 中。编译应用程序后,它应该能够 运行 到任何地方。 dylib 被复制到应用程序中,但是当 运行 在干净的机器上时,它仍然会在 /usr/local/lib 中查找 dylib。

我尝试了(太多)很多方法来让它工作,所以我现在完全搞混了。

在我之前的评论中提到,错误消息中 dylib 的名称与您实际使用的名称不同(3.23.2.0)。由于 dylib 已经构建并且您以这种方式将其包含在您的项目中,这表明现有 rpathid 已经存在。

使用otool:

$ otool -l libopencv_core.3.2.0.dylib
...
 Load command 3
          cmd LC_ID_DYLIB
      cmdsize 56
         name @rpath/libopencv_core.3.2.dylib (offset 24)
   time stamp 1 Wed Dec 31 17:00:01 1969
      current version 3.2.0
compatibility version 3.2.0
...
 Load command 16
          cmd LC_RPATH
      cmdsize 32
         path /usr/local/lib (offset 12)

这里可以观察到两件事;第一个是确认差异的 LC_ID_DYLIB,其次,存在的 LC_RPATH (rpath) 设置为指示库位置是 /usr/local/lib。由于您在应用程序中包含了库,因此应该对其进行更新。

更新库(包含在您的应用程序中的库):

$ install_name_tool -id @rpath/libopencv_core.3.2.0.dylib libopencv_core.3.2.0.dylib

更新 LC_ID_DYLIB

$ install_name_tool -add_rpath "@executable/../Frameworks" libopencv_core.3.2.0.dylib

添加正确的 LC_RPATH.

$ install_name_tool -delete_rpath "/usr/local/lib" libopencv_core.3.2.0.dylib

从库中删除 rpath /usr/local/lib。再次验证运行otool -l

...
 Load command 3
          cmd LC_ID_DYLIB
      cmdsize 64
         name @rpath/libopencv_core.3.2.0.dylib (offset 24)
   time stamp 1 Wed Dec 31 17:00:01 1969
      current version 3.2.0
compatibility version 3.2.0
...
 Load command 17
          cmd LC_RPATH
      cmdsize 40
         path @executable/../Frameworks (offset 12)

现在您应该能够将 dylib 包含在独立应用程序中,并且应该正确设置它的路径;更新后的 dylibhere。更新库后,应用程序可以正常打开。

注意: 在你的问题中你正在导入 libopencv_core3.2.0.dylib,虽然错误指出 libopencv_imgproc.3.2.dylib,但我认为它是另一个 dylib遇到类似的问题,所以这当然可以应用于其他人。您最初在 Xcode 中设置的 rpath 是正确的

虽然因为库允许多个 rpaths 存在并且 /usr/local/bin 已经存在,除了错误的名称之外,它首先使用该位置。