Search code examples
macoslinkerdynamic-linkingrpath

Recursive RPATH in macOS


The directory structure of a framework is like this:

   fw.framework
      Versions
         A
            fw
            Libraries
               a.dylib
               b.dylib
         Current -> A
      Libraries -> Versions/Current/Libraries
      fw -> Versions/Current/fw

Dependencies:

  • fw links to a.dylib
  • a.dylib links to b.dylib

a.dylib and b.dylib have the install name @rpath/a.dylib and @rpath/b.dylib.

The RPATH of fw is set to @loader_path/Libraries, so that it can find a.dylib.

But the RPATH of a.dylib is set to @loader_path, because its dependency b.dylib is in the same directory.

Will this work? Will the linker use the RPATH of a.dylib (and not the one of fw, when recursively linking b.dylib)

And will @loader_path in the RPATH of a.dylib refer to the directory of a.dylib, and not that of fw?


Solution

  • Yes, you are right.

    If you use otool -l <dylib>, you will find (in my case):

    Load command 22
              cmd LC_RPATH
          cmdsize 32
             path @loader_path/../lib (offset 12)
    

    @loader_path will be resolved to path to folder which contains <dylib>, so each dylib will have itself @loader_path.

    As above, LC_RPATH means @rpath_path will have different path in different dylib, it won't be inherited from another.

    So, when you load fw, @loader_path of fw is its dirname, load a.dylib, @loader_path of a.dylib is its dirname.