Dylibを正常に呼び出すアプリケーション(実行可能ファイル)を作成しましたが、dylibファイルと実行可能ファイルは別のディレクトリにあります。 dylibファイルを含むディレクトリを$ PATH環境変数に追加しましたが、それでもロードされません。すべてのdylibファイルを実行可能ファイルにコピーすると、プログラムが最終的に実行されます。これにより、dylibファイルに問題がないことが確認されます。ただし、OSにそれを見つけるように指示するにはどうすればよいですか? Windowsでは、dllファイルを含むディレクトリパスを$ PATHに追加するだけです。 Mac OS Xで何をする必要がありますか?どうもありがとう!
Justinが提供したリンクを読んだ後、@executable_path
トークンを使用して、dylib install_nameを実行可能ファイルのある同じディレクトリを指すように変更することに成功しました。
@ executable_path絶対パスは迷惑です。フレームワークを/ Libraryまたは同様の場所にインストールする代わりに、フレームワークをアプリケーションに埋め込む場合があります。
これに対するMacのソリューションは@executable_pathです。これは、ライブラリのインストール名の先頭に配置されると、それをロードする実行可能ファイルのパスから最後のコンポーネントを除いて展開されるマジックトークンです。たとえば、Bar.appがFoo.frameworkにリンクしているとします。 Bar.appが/ Applicationsにインストールされている場合、@ executable_pathは/Applications/Bar.app/Contents/MacOSに展開されます。フレームワークをContents/Frameworksに埋め込む場合は、Foo.frameworkのインストール名を@executable_path /../ Frameworks/Foo.framework/Versions/A/Fooに設定するだけです。動的リンカーはそれを/Applications/Bar.app/Contents/MacOS/../Frameworks/Foo.framework/Versions/A/Fooに展開し、そこでフレームワークを見つけます。
http://www.mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html
例を使って説明します。
次の実行可能ファイル/ opt/local/bin/convertがあり、そのdylibが/ opt/local/libにあるとします。別のディレクトリにコピーして、実行可能ファイルをコピーしたディレクトリと同じディレクトリからdylibをロードするようにします。
> mkdir ~/tmp/bin
> cp /opt/local/bin/convert ~/tmp/bin
実行可能ファイルdylibのリストを取得します
> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
/opt/local/lib/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/opt/local/lib/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
/opt/local/lib/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
/opt/local/lib/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
/opt/local/lib/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
/opt/local/lib/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
/opt/local/lib/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
/opt/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
...
/ opt/local/libディレクトリー内のdylibのみが重要なので、/ opt内のdylibのみを引き出します。特に/ usr/lib/libSystemを参照して、他のすべてのdylib参照をそのまま保持したいと思います。
> DYLIBS=`otool -L ~/tmp/bin/convert | grep "/opt" | awk -F' ' '{ print $1 }'`
実行可能ファイルが参照するすべてのdylibを、実行可能ファイルがコピーされたのと同じディレクトリにコピーします。
> for dylib in $DYLIBS; do cp $dylib ~/tmp/bin/; done;
install_name_tool
を使用して、上記の手順で取り出したすべてのdylibのインストール名を変更し、@executable_path
をdylib名の前に追加して置き換えます。これにより、動的リンカーは、実行可能ファイルが存在するディレクトリと同じディレクトリでdylibを検索します。
> for dylib in $DYLIBS; do install_name_tool -change $dylib @executable_path/`basename $dylib` ~/tmp/bin/convert; done;
インストール名が変更されていること、およびlibSystemがまだ/ usr/lib/libSystemを指していることを確認します。
> otool -L ~/tmp/bin/convert
~/tmp/bin/convert:
@executable_path/libtiff.3.dylib (compatibility version 13.0.0, current version 13.5.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
@executable_path/libjpeg.8.dylib (compatibility version 12.0.0, current version 12.0.0)
@executable_path/libfontconfig.1.dylib (compatibility version 6.0.0, current version 6.4.0)
@executable_path/libiconv.2.dylib (compatibility version 8.0.0, current version 8.1.0)
@executable_path/libfreetype.6.dylib (compatibility version 15.0.0, current version 15.0.0)
@executable_path/libexpat.1.dylib (compatibility version 7.0.0, current version 7.2.0)
@executable_path/libbz2.1.0.dylib (compatibility version 1.0.0, current version 1.0.6)
@executable_path/libz.1.dylib (compatibility version 1.0.0, current version 1.2.6)
...
DYLD_LIBRARY_PATH
環境変数を設定する必要があります。
dyld manページ から:
This is a colon separated list of directories that contain libraries. The dynamic linker
searches these directories before it searches the default locations for libraries. It allows
you to test new versions of existing libraries.
For each library that a program uses, the dynamic linker looks for it in each directory in
DYLD_LIBRARY_PATH in turn. If it still can't find the library, it then searches DYLD_FALL-
BACK_FRAMEWORK_PATH and DYLD_FALLBACK_LIBRARY_PATH in turn.
DylibがライブラリのINSTALL_NAMEで指定された場所にある場合、Just Work *になります。
それ以外の場合は、dylibの場所をDYLD_LIBRARY_PATHに追加できます。 dyld documentation を読みたいかもしれません。
*)完全に正確であるためには、DYLD_ROOT_PATH/INSTALL_NAMEにある必要がありますが、DYLD_ROOT_PATHに煩わされることはほとんどありません。