install_name_tool to update a executable to search for dylib in Mac OS X

From otool -l, I analyzed what should be added or modified from the original library and binary.

Dylib

The change is in id:

Load command 2 <-- OLD
          cmd LC_ID_DYLIB
      cmdsize 40
         name libtest.dylib (offset 24)
   time stamp 1 Wed Dec 31 18:00:01 1969

Load command 2 <-- NEW
          cmd LC_ID_DYLIB
      cmdsize 64
         name @loader_path/../lib/libtest.dylib (offset 24)

This is the command to accomplish the change:

install_name_tool -id "@loader_path/../lib/libtest.dylib" libtest.dylib 

Or use rpath:

install_name_tool -id "@rpath/libtest.dylib" libtest.dylib

The executable

There are two changes: rpath and load_dylib

Load command 12 <-- OLD
          cmd LC_LOAD_DYLIB
      cmdsize 40
         name libtest.dylib (offset 24)

Load command 12 <-- NEW
          cmd LC_LOAD_DYLIB
      cmdsize 64
         name @loader_path/../lib/libtest.dylib (offset 24)

This is the command to accomplish the change

install_name_tool -change libtest.dylib @loader_path/../lib/libtest.dylib myapp 

Also I needed to add the rpath

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

This is the command to accomplish the addition:

 install_name_tool -add_rpath "@loader_path/../lib" myapp

The idea

The binary tries to find the library, it knows where it is located from install_name_tool -add_rpath "@loader_path/../lib" myapp. It loads the library, and the library’s id is @rpath/libtest.dylib where @rpath is set to @loader_path/../lib in the executable binary to make the match.

Reference

  • Can you please help me understand how Mach-O libraries work in Mac Os X?

Cmake

When using CMake, we can automatize the process with the following addition in CMakeLists.txt file.

Library

The id should be added.

# https://cmake.org/pipermail/cmake/2006-October/011530.html
SET_TARGET_PROPERTIES (test
  PROPERTIES BUILD_WITH_INSTALL_RPATH 1
             INSTALL_NAME_DIR "@rpath"
  )

Executable

The rpath should be specified:

SET(CMAKE_INSTALL_RPATH "@loader_path/../lib/libtest.dylib")

Leave a Comment