分布式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.2
与 3.2.0
)。由于 dylib
已经构建并且您以这种方式将其包含在您的项目中,这表明现有 rpath
或 id
已经存在。
使用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
包含在独立应用程序中,并且应该正确设置它的路径;更新后的 dylib
是 here。更新库后,应用程序可以正常打开。
注意: 在你的问题中你正在导入 libopencv_core3.2.0.dylib
,虽然错误指出 libopencv_imgproc.3.2.dylib
,但我认为它是另一个 dylib
遇到类似的问题,所以这当然可以应用于其他人。您最初在 Xcode 中设置的 rpath
是正确的
虽然因为库允许多个 rpaths
存在并且 /usr/local/bin
已经存在,除了错误的名称之外,它首先使用该位置。
我正在努力寻找 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.2
与 3.2.0
)。由于 dylib
已经构建并且您以这种方式将其包含在您的项目中,这表明现有 rpath
或 id
已经存在。
使用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
包含在独立应用程序中,并且应该正确设置它的路径;更新后的 dylib
是 here。更新库后,应用程序可以正常打开。
注意: 在你的问题中你正在导入 libopencv_core3.2.0.dylib
,虽然错误指出 libopencv_imgproc.3.2.dylib
,但我认为它是另一个 dylib
遇到类似的问题,所以这当然可以应用于其他人。您最初在 Xcode 中设置的 rpath
是正确的
虽然因为库允许多个 rpaths
存在并且 /usr/local/bin
已经存在,除了错误的名称之外,它首先使用该位置。