Linker setting for distributed dylib

别说谁变了你拦得住时间么 提交于 2019-12-10 10:59:15

问题


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

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:

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 Error Message:

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

So, which option needs to be set?

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.


回答1:


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.

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)

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.

Update the library (the one included in your app):

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

Updates the LC_ID_DYLIB.

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

Adds the correct LC_RPATH.

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

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)

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.

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

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.



来源:https://stackoverflow.com/questions/41782274/linker-setting-for-distributed-dylib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!