/PATH/lib
にインストールされている動的ライブラリーlibtest.dylibと、/PATH/bin
にインストールされているdylibを使用する実行バイナリmyappがあります。
次のようにmyapp
を実行してdylibを見つけることができます( Mac OS XでDYLD_LIBRARY_PATHを使用しても大丈夫ですか?また、動的ライブラリ検索アルゴリズムは何ですか? ):
DYLD_LIBRARY_PATH="/PATH/lib" myapp
ライブラリがrpathで見つかるように、install_name_tool
を使用してライブラリと実行可能ファイルを更新できると思います。この投稿でヒントを使用しました- dylibでrpathを指定するにはどうすればよいですか? 。
Libでは、このコマンドを実行してrpathを追加しました。
install_name_tool -id "@rpath/libtest.dylib" libtest.dylib
install_name_tool -add_rpath "@executable_path/../lib/" libtest.dylib
ビンで、install_name_tool -add_rpath "@executable_path/../lib/" myapp
を実行しました。
ただし、myapp
ディレクトリでbin
を実行すると、エラーメッセージが表示されます。
dyld: Library not loaded: libtest.dylib
Referenced from: /PATH/bin/./myapp
Reason: image not found
Trace/BPT trap: 5
otool -l myapp
は、myappでrpathが正しく更新されたことを示します。
Load command 16
cmd LC_RPATH
cmdsize 40
path @executable_path/../lib/ (offset 12)
Libtest.dylibでも同様です
Load command 13
cmd LC_RPATH
cmdsize 40
path @executable_path/../lib/ (offset 12)
何が悪いのでしょうか?
もちろん、コンパイル時とリンク時にcc -install_name
を使用できますが、generatd dylibと実行バイナリを変更して同じことを行う方法を知りたいと思いました。
ライブラリから:
cc -install_name "@loader_path/../lib/libtest.dylib" -dynamiclib -o libtest.dylib test.c
または、install_nameは@rpathを使用できます。
cc -install_name "@rpath/libtest.dylib" -dynamiclib -o libtest.dylib test.c
ビンから:
cc -I../lib -c main.c
cc -o main main.o ../lib/libtest.dylib -Wl,-rpath -Wl,@loader_path/../lib
または1行だけ:
cc -I../lib -L../lib -o main main.c -ltest -Wl,-rpath -Wl,@loader_path/../lib
otool -l
から、元のライブラリとバイナリに追加または変更する必要があるものを分析しました。
変更は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)
これは、変更を行うためのコマンドです。
install_name_tool -id "@loader_path/../lib/libtest.dylib" libtest.dylib
または、rpathを使用します。
install_name_tool -id "@rpath/libtest.dylib" libtest.dylib
2つの変更点があります:rpathと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)
これは、変更を達成するためのコマンドです
install_name_tool -change libtest.dylib @loader_path/../lib/libtest.dylib myapp
また、rpathを追加する必要がありました
Load command 14
cmd LC_RPATH
cmdsize 32
path @loader_path/../lib (offset 12)
これは、追加を実行するコマンドです。
install_name_tool -add_rpath "@loader_path/../lib" myapp
バイナリはライブラリを見つけようとし、install_name_tool -add_rpath "@loader_path/../lib" myapp
からどこにあるかを認識します。ライブラリをロードし、ライブラリのIDは@rpath/libtest.dylib
です。@rpath
は、実行可能バイナリで@loader_path/../lib
に設定され、一致します。
CMakeを使用する場合、CMakeLists.txtファイルに以下を追加することでプロセスを自動化できます。
IDを追加する必要があります。
# https://cmake.org/pipermail/cmake/2006-October/011530.html
SET_TARGET_PROPERTIES (test
PROPERTIES BUILD_WITH_INSTALL_RPATH 1
INSTALL_NAME_DIR "@rpath"
)
Rpathを指定する必要があります。
SET(CMAKE_INSTALL_RPATH "@loader_path/../lib/libtest.dylib")