First of all, understand that an executable doesn’t contain a single
rpath entry, but an array of one or more entries.
Second, you can use
otool to list an image’s
rpath entries. Using
otool -l, you’ll get output like the following, at the very end of which are the
Load command 34 cmd LC_LOAD_DYLIB cmdsize 88 name /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (offset 24) time stamp 2 Wed Dec 31 19:00:02 1969 current version 1038.32.0 compatibility version 45.0.0 Load command 35 cmd LC_RPATH cmdsize 40 path @loader_path/../Frameworks (offset 12)
Look for the
LC_RPATH commands and note the path under the
EDIT: regarding what
@loader_path is: it’s a generic and dynamic way to refer to the Mach-O object that wants to do the loading of the framework.
While this is a rather contrived example, I think it should get the point across. Let’s say we have an app
MyApp.app that uses a framework
MyFramework.framework. We’ll also say that to function properly, I require that my app is installed in the /Applications and nowhere else. So the structure of said app and framework would be the following:
/Applications/MyApp.app/Contents/Frameworks/MyFramework.framework/MyFramework (Mach-O dylib)
If we were to run
otool -L (note the capital L) on the executable it would show the following regarding MyFramework:
@rpath/MyFramework.framework/Versions/A/MyFramework /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation /usr/lib/libobjc.A.dylib /usr/lib/libSystem.B.dylib ....
Note that because the MyFramework.framework uses an
@rpath install name/path, we’ll need to have runtime search path entries that will be substituted in place of
@rpath at runtime. Now, I could have a single rpath entry of:
That would work, and at runtime the two parts would be put together:
Obviously, hard-coding a path like this is not ideal, as simply moving the app to a different folder or renaming the app itself would cause linking to fail.
@loader_path is simply a dynamic way to refer to the app’s executable wherever it may exist on the filesystem. In this particular case, at runtime it will be filled in with the path to the running executable:
/Applications/MyApp.app/Contents/MacOS/MyApp. Then we can say that to find the MyFramework.framework, you simply go up a directory and over to