Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a dynamic libray libtest.dylib that is installed in /PATH/lib, and an execution binary, myapp, that uses the dylib installed in /PATH/bin.

I can run myapp to find the dylib as follows (Is it OK to use DYLD_LIBRARY_PATH on Mac OS X? And, what's the dynamic library search algorithm with it?):

DYLD_LIBRARY_PATH="/PATH/lib" myapp  

I think I can use install_name_tool to update the library and executable so that the library can be found with rpath. I used the hints in this post - How can I specify the rpath in a dylib?.

In lib, I executed this command to add rpath.

install_name_tool -id "@rpath/libtest.dylib" libtest.dylib install_name_tool -add_rpath "@executable_path/../lib/" libtest.dylib 

In bin, I executed install_name_tool -add_rpath "@executable_path/../lib/" myapp.

However, when I executed myapp in bin directory, I have the error messages.

dyld: Library not loaded: libtest.dylib   Referenced from: /PATH/bin/./myapp   Reason: image not found Trace/BPT trap: 5 

otool -l myapp shows the rpath is correctly updated in myapp.

Load command 16           cmd LC_RPATH       cmdsize 40          path @executable_path/../lib/ (offset 12) 

The same is true with libtest.dylib

Load command 13           cmd LC_RPATH       cmdsize 40          path @executable_path/../lib/ (offset 12) 

What might be wrong?

ADDED

Of course, I can use cc -install_name when compile and link time, but I wanted to know how to do the same thing my modifying the generatd dylib and execution binary.

From the lib:

cc -install_name "@loader_path/../lib/libtest.dylib" -dynamiclib -o libtest.dylib test.c 

Or, the install_name can use @rpath:

cc -install_name "@rpath/libtest.dylib" -dynamiclib -o libtest.dylib test.c 

From the bin:

cc -I../lib -c main.c cc -o main main.o ../lib/libtest.dylib -Wl,-rpath -Wl,@loader_path/../lib 

Or just one line:

cc -I../lib -L../lib -o main main.c -ltest -Wl,-rpath -Wl,@loader_path/../lib 
like image 957
prosseek Avatar asked Nov 30 '15 04:11

prosseek


People also ask

What is @rpath Mac?

@rpath stands for Runpath Search Path. In the Xcode, it's set with LD_RUNPATH_SEARCH_PATH setting. In ld command tool it's set with -rpath parameter when linking. So it's a search path for the linker. Runtime Search Path instructs the dynamic linker to search a list of paths in order, to locate the dynamic library.


1 Answers

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") 
like image 114
prosseek Avatar answered Oct 05 '22 17:10

prosseek