Rpath madness on OS X

Hi,

I am attempting to build a software framework that uses ROOT and Geant4 on OS X, which is already working
fine on Linux. I think I am almost there but I am running into some confusing issues involving rpath and linking/loading.

Everything seems to compile and link fine, but then when I run my sim executable I get this error message…

dyld: Library not loaded: @rpath/libCore.so

I suspect that the ROOT libs can’t be found at runtime, so I turn on DYLD_PRINT_LIBRARIES to debug.

But the loader seems to be finding the library just fine!

dyld: loaded: /work/ldmx/dev/root-6.08.00-build/lib/libCore.so
etc.

Investigating further by using otool -l sim-app | grep LC_RPATH -A2 it seems that the directories of the other libraries have rpath entries in the executable but the ROOT dir is not in there.

The ROOT lib dir is set in DYLD_LIBRARY_PATH but it doesn’t seem to be picked up from there.

From what I can tell, Geant4 is setting the rpath explicitly in the binary, which allows its libraries to be found, but this is not what ROOT is doing.

This is probably not a ROOT problem or bug, but I’m wondering if anyone can help me figure out what is going on here…why would it be that the loader finds the ROOT libraries initially but then there is a runtime error indicating the libraries were not found?

If needed I can paste in the full (ugly!) compilation and linking commands should they be useful.

Thanks.

–Jeremy

Sorry for the delay in responding.

This behavior of ignoring DYLD_LIBRARY_PATH is common from MacOS >= 10.10. Any executable coming from /usr/bin will clean the variable DYLD_LIBRARY_PATH. If your executable is run from, lets say, a bash script the command /usr/bin/bash will take care of cleaning DYLD_LIBRARY_PATH, so will miss the ROOT lib dir.

The solution is to build your shared libraries/executables using the -rpath link option. Something like this:

-Wl,-rpath,<root-installation-prefix>/lib

If you use CMake to build your application then all this is somehow the default for MacOS. Typically something like this should work.

find_package(ROOT REQUIRED)
include(${ROOT_USE_FILE})

find_package(Geant4 REQUIRED)
include(${Geant4_USE_FILE})


include_directories(${CMAKE_SOURCE_DIR}  ${ROOT_INCLUDE_DIRS} ${Geant4_INCLUDE_DIRS})

#---Create a shared library
add_library(myLib SHARED MyLib.cxx)
target_link_libraries(Event ${ROOT_LIBRARIES} ${Geant4_LIBRARIES})

#---Create  a main program using the library
add_executable(Main Main.cxx)
target_link_libraries(Main myLib)
1 Like

I had the same problem. I successfully compiled/installed root, Madgraph, Delphes, Pythia and everything worked. Then I compiled CheckMate and the compilation was successful but it crashed at runtime with:
dyld: Library not loaded: @rpath/libGui.so

The reason is that MacOS now comes by default with certain security settings which, among other things, unset the DYLIB_LIBRARY_PATH. If your executable look for libraries in non-standard locations they won’t run.

One trivial solution is to disable this feature:

  1. boot while holding command+R to boot in recovery mode
  2. Start terminal from one of the menus
  3. csrutil disable; reboot

After this CheckMate just run no problems.

Hope it helps.
Enrico