Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MAC OS: dynamically linked library not found despite correct rpath

I have a (relatively) big project C++ that compiles and runs fine on ubuntu (using cmake/catkin). It compiles fine on mac os, but when trying to start the executable, I get the error message:

dyld: Library not loaded: <name of library>.dylib
  Referenced from:
  <path to executable>/<executable>
Reason: image not found

When running the command:

otool -l <executable> | grep LC_RPATH -A2

I get the output:

      cmd LC_RPATH
  cmdsize 64
     path <correct absolute path to folder containing library> (offset 12)

      cmd LC_RPATH
  cmdsize 24
     path /sw/lib (offset 12)

      cmd LC_RPATH
  cmdsize 32
     path /usr/X11/lib (offset 12)

      cmd LC_RPATH
  cmdsize 32
     path /opt/local/lib (offset 12)

      cmd LC_RPATH
  cmdsize 32
     path /opt/X11/lib (offset 12)

It is very unclear to me why the library is not found. Running:

otool -L <executable>

prints:

<executable name>:
    <library name>.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libedit.3.dylib (compatibility version 2.0.0, current version 3.0.0)
    /usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
    /opt/X11/lib/libglut.3.dylib (compatibility version 13.0.0, current version 13.0.0)
    /opt/X11/lib/libGL.1.dylib (compatibility version 1.2.0, current version 1.2.0)
    /opt/X11/lib/libGLU.1.dylib (compatibility version 1.3.0, current version 1.3.0)
    /opt/X11/lib/libX11.6.dylib (compatibility version 10.0.0, current version 10.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

which seems to confirm it does not get the right path.

Anything I am missing ?

ps:

not sure it is relevant, here the cmake commands I used: (from here)

# use, i.e. don't skip the full RPATH for the build tree
SET(CMAKE_SKIP_BUILD_RPATH  FALSE)

# when building, don't use the install RPATH already
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)

SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/${MACHTYPE}")

# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)

# the RPATH to be used when installing, but only if it's not a system directory
LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib/${MACHTYPE}" isSystemDir)
IF("${isSystemDir}" STREQUAL "-1")
    SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/${MACHTYPE}")
ENDIF("${isSystemDir}" STREQUAL "-1")
like image 861
Vince Avatar asked Sep 08 '15 14:09

Vince


People also ask

Is “dyld library not loaded” error on macOS?

MacOS developed and distributed by Apple is surely one of the most reliable Operating System out there. It is used mostly by professionals who intend to use their computers for business purposes. However, quite recently a lot of reports have been coming in of a “Dyld: Library Not Loaded” Error on MacOS.

How does @rPath work in dylib?

Dyld maintains a current stack of paths called the run path list. When @rpath is encountered it is substituted with each path in the run path list until a loadable dylib if found. The run path stack is built from the LC_RPATH load commands in the depencency chain that lead to the current dylib load.

How does the @rpath command work?

When @rpath is encountered it is substituted with each path in the run path list until a loadable dylib if found. The run path stack is built from the LC_RPATH load commands in the depencency chain that lead to the current dylib load. You can add an LC_RPATH load command to an image with the -rpath option to ld (1).

How to find the anchor point of a dyld dylib?

Each main executable is linked with -rpath @loader_path/zzz, where zzz is the path from the executable to the anchor point. At runtime dyld sets it run path to be the anchor point, then each dylib is found relative to the anchor point.


1 Answers

Answer came from a comment from here

I need to use @rpath

Actually Mac OS X does have the concept of rpath. Previous to 10.4 there was only @executable_path which pointed to the location of the executable binary (as opposed to any dylibs that it loaded). @loader_path was introduced in 10.4 which allowed dylibs to load dependencies based on their location (and not on the location of the executable - who knows what's using the library).

With 10.5 apple introduced @rpath which is baked into the loading binary - executable or library. So instead of seeing: @loader_path/../../Library/Frameworks/blah.dylib you might see @rpath/Library/Frameworks/blah.dylib

Which means if the rpath is set to . and / it would look at ./Library/Frameworks/blah.dylib and then /Library/Frameworks/blah.dylib for any libraries.

like image 81
Vince Avatar answered Sep 20 '22 00:09

Vince