Abhishek
Abhishek

Reputation: 21

dyld not able to load dylibs

I have a bunch of dylibs which i need to load at runtime from application bundle. I have noticed that if i put my dylibs in /usr/lib folder, then application is able to load it. I have gone thru install_name_tool manual but haven't got a clue on how can i make my application load these dylibs from .app/contents/Frameworks folder.

Could please someone help me out with this??

Upvotes: 2

Views: 3519

Answers (1)

Richard Kettering
Richard Kettering

Reputation: 331

I just dealt with this same problem yesterday.

What's unintuitive is that you would expect, since you drag your dylibs into XCode's file browser, and since you add a build phase to copy them into your bundled executable, the linker would "write into" the app to tell it where to find those dylibs. Unfortunately, it doesn't.

For whatever historical-or-who-knows-why reason, instead of deriving this info from what you do in XCode, it derives this from a string inside the dylibs themselves. One which XCode doesn't touch, and which you need to set manually with a commandline tool.

Inside each of the dylibs is a string called the "id", which is the path that the program will look for the dylibs at. I think this gets copied into the executable at link time. To find out what this string is, you can run the following:

otool -L pathToMyDylib

The first line that command outputs is the string the exec will expect it to be at, when the program is run, which is called the "id". I built some boost libraries, and the output for their id was simply the filename. The later lines that the command outputs are "dependencies"; these are other libraries that your dylib may depend on to run. Often, as was the case with mine, these are libraries which are guaranteed to be in any mac distro, so you have no worries about having to correct these. If they weren't such; if they were libraries you had built yourself and were going to include in your app, you would have to correct these as well. So, the output for my otool -L libboost_regex.dylib was:

libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.0.0)

The first line, is the one that needs to be corrected to look inside my executable. You're correct that install_name_tool is the right thing to fix this. What I used to fix this was (with my terminal in the same directory as my boost dylib):

install_name_tool -id "@executable_path/../Frameworks/libboost_regex.dylib" libboost_regex.dylib

Respectively, the first parameter there (after the -id flag) is the new path, and the second parameter is the dylib file to be modified.

If you needed to do a similar modification to one of the dependencies, you'd use:

install_name_tool -change oldpath newpath currentfile

And this would have to be reapplied for each separate dependency.

I hope this helps!

Upvotes: 9

Related Questions