分布式dylib的链接器设置 [英] Linker setting for distributed dylib
问题描述
我正在为XCode中的正确选项苦苦挣扎,以在我的应用程序中包含一个dylib.我在我的应用程序确实需要/usr/local/lib
中有一个dylib.只要我在库搜索路径"中设置此路径
I'm struggling with the right options in XCode to include a dylib in my app. I do have a dylib in /usr/local/lib
which I do need for my app. As long as I set this path in Lib Search Paths
一切正常.但是我当然想通过我的应用程序分发dylib,这就是为什么我将其添加到复制阶段的原因:
everything works fine. But of course I want to distribute the dylib with my app which is why I added it to a copy phase:
这确实将dylib复制到应用程序的Frameworks
文件夹中.但是在目标系统上运行时,该应用程序找不到dylib.它甚至在/usr/local/lib
中都找不到.而是嘶哑:
This indeed copies the dylib into the Frameworks
folder in the app. But running on the target system, the app does not find the dylib. It even does not find it in /usr/local/lib
. Rather it croaks:
Dyld错误消息:
Dyld Error Message:
库未加载:@ rpath/libopencv_imgproc.3.2.dylib
Library not loaded: @rpath/libopencv_imgproc.3.2.dylib
那么,需要设置哪个选项?
So, which option needs to be set?
编辑:我在此处整理了一个示例项目.它包含3个zip:一个项目,一个项目的头文件放置在/usr/local/include
中,另一个项目的dylib文件放置在/usr/local/lib
中.编译应用后,它应该可以在任何地方运行. dylib已复制到应用程序中,但是在干净的计算机上运行时,它仍在/usr/local/lib
中查找dylib.
Edit I put together a sample project here. It contains 3 zips: one project, one with the headers to be placed in /usr/local/include
and one with the dylibs to be placed in /usr/local/lib
. Once the app is compiled it should be able to run anywhere. The dylib is copied into the app, but when run on a clean machine it still looks in /usr/local/lib
for the dylib.
我尝试了太多方法来使其正常工作,所以我目前完全感到困惑.
I tried (too) many ways to get this to work, so I'm currently completely mixed up.
推荐答案
在我之前提到的错误消息中,dylib
的名称与错误消息中的3.2
与3.2.0
有所不同.您实际上正在使用.由于dylib
已经构建,并且您是通过这种方式将其包括在指示符中的项目中,因此现有的rpath
或id
已经存在.
In my earlier comment as mentioned the name of the dylib
in the error message differs (3.2
vs. 3.2.0
) from that of the one you are actually using. Since the dylib
is already built and you are including it this way in your project that's an indicator an existing rpath
or id
already exists.
使用otool
:
Using 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
.由于您将lib包含在您的应用程序中,因此应该对其进行更新.
Two things can be observed here; the first being the LC_ID_DYLIB
which confirms the discrepancy, and secondly, the LC_RPATH
(rpath) which is present is set to indicate the library location is /usr/local/lib
. Since you are including the lib with your app it should be updated.
更新库(应用程序中包含的库):
$ 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
:
Removes the rpath
/usr/local/lib
from the library. To verify run otool -l
again:
...
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
是此处.更新库后,该应用程序将打开,没有任何问题.
Now you should be able to include the dylib
in a standalone app and it's path should be set correctly; the updated dylib
is here. After updating the library the app opens without issue.
注意事项:在您的问题中,您正在导入libopencv_core3.2.0.dylib
,尽管错误提示libopencv_imgproc.3.2.dylib
,但我认为这是另一个dylib
,它也遇到了类似的问题,因此可以肯定地适用给别人.您最初在Xcode中设置的rpath
是正确的
Notes: In your question you are importing libopencv_core3.2.0.dylib
, although the error states libopencv_imgproc.3.2.dylib
, but I assume it's another dylib
which suffers a similar issue, so this can certainly be applied to others. The rpath
you had originally set in Xcode was correct
尽管由于库允许存在多个rpaths
并且/usr/local/bin
已经存在,所以除了错误的名称外,它还会首先使用该位置.
although since libraries allow multiple rpaths
to exist and /usr/local/bin
already is present it's using that location first, in addition to the wrong name.
这篇关于分布式dylib的链接器设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!