I have built an executable (named demux) on OS X that always fails to load and I cannot find why:
$ ./demux
RPATH failed to expanding @rpath/sfeMovie.framework/Versions/2.0/sfeMovie to: @executable_path/sfeMovie.framework/Versions/2.0/sfeMovie
dyld: Library not loaded: @rpath/sfeMovie.framework/Versions/2.0/sfeMovie
Referenced from: …current_dir/./demux
The framework is next to the executable. Otool shows the following :
$ otool -L sfeMovie.framework/Versions/2.0/sfeMovie
sfeMovie.framework/Versions/2.0/sfeMovie:
@rpath/sfeMovie.framework/Versions/2.0/sfeMovie (compatibility version 2.0.0, current version 2.0.0)
And:
$ otool -L demux
demux:
@rpath/sfeMovie.framework/Versions/2.0/sfeMovie (compatibility version 2.0.0, current version 2.0.0)
Given that, I thought that adding @executable_path to the runtime search path of the executable would allow it to look at any framework and library whose relative install name is simply prefixed with @rpath (like in @rpath/sfeMovie.framework/…) and which is next to the executable. To make sure that this runtime search path is correct:
$ otool -l demux | grep LC_RPATH -A 2
cmd LC_RPATH
cmdsize 32
path @executable_path (offset 12)
But this fails and I don't know why. To me @executable_path/sfeMovie.framework/Versions/2.0/sfeMovie looks like the correct path but it still fails… is there any misuse of @rpath or @executable_path?
I was able to reproduce your issue with a quick test project. It was fixed when I appended a trailing slash to the LD_RUNPATH_SEARCH_PATH
build setting.
Instead of:
@executable_path
you should try
@executable_path/
The output from otool -l
now looks like this:
cmd LC_RPATH
cmdsize 32
path @executable_path/ (offset 12)
In general, you can check your toplevel executable (in this case "demux") with my dyld analyzer script at https://github.com/liyanage/macosx-shell-scripts/blob/master/checklibs.py
./checklibs.py demux
This tool attempts to faithfully reproduce dyld
's resolution logic. It can usually provide a hint about which references don't work, but in this case it doesn't catch the issue with the missing trailing slash. I will update it accordingly to match dyld
's behavior.