Search code examples
macosdyldrpath

RPATH failed to expanding


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?


Solution

  • 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.