ショートバージョン
問題は、ビルド時SBJSON.framework
に、インストール名がを使用するように構成されていないこと@rpath
です。その結果、アプリがダイナミックライブラリをロードしようと/Library/Frameworks
すると、アプリの実行パスが検索するように指示する場所ではなく、検索します。
SBJSON.framework
これを修正するには、ターゲットのビルド設定を変更する必要があります。ダイナミックライブラリのインストール名の設定をに変更し@rpath/${EXECUTABLE_PATH}
ます。次に、新しく構築されたフレームワークに対してリンクして、再度構築するだけで、準備は完了です。
ロングバージョン
フレームワークは、基本的には単なるダイナミックライブラリです。これは、ライブラリに含まれているコードがアプリに埋め込まれているのではなく、実行時SBJSON.framework
にバンドルから取得されることを意味します。これを行うには、アプリがダイナミックライブラリを探す場所を知る必要があります。
これが機能する方法は、フレームワークに対してリンクする場合、リンカーが実際にライブラリ全体をアプリに埋め込むことはないということです。代わりに、実行時にライブラリを見つける場所をアプリに指示する小さなセクションを追加するだけです。もちろん、これは、コンパイラが実行時にライブラリがどこにあるかを知る必要があることを意味します。ダイナミックライブラリの「インストール名」を調べることで、その情報を見つけます。
ダイナミックライブラリの「インストール名」は、基本的に、ライブラリが存在すると予想されるパスにすぎません。歴史的に、ほとんどのダイナミックライブラリとフレームワークはシステム全体で共有されてきました。たとえば、のようなものはに住んでFoundation.framework
おり、すべてのアプリはそこにそれらを見つけることを合理的に期待できます。したがって、がビルドされると、そのインストール名はに設定されます。XcodeがアプリをCoreDataにリンクすると、フレームワークのインストール名が確認され、アプリの起動時にそのパスでフレームワークに読み込まれるように指示されます。CoreData.framework
/System/Library/Frameworks
CoreData.framework
/System/Library/Frameworks/...
それはすべて問題ありませんが、アプリ内にフレームワークを埋め込む必要がある場合は役に立ちません。実行時にアプリがシステムのどこに配置されるかはわかりません。ユーザーはから実行できますが、から実行する/Applications
こともできます~/Downloads
。実行時にフレームワークを常に正しく指すインストール名として指定できる単一のパスはありません。
これに対処するために、フレームワークのインストール名をに設定できます@loader_path/../Frameworks
。ダイナミックローダーが@loader_path
を検出すると、現在ロードしているアプリのパスに置き換えられます。このインストール名を使用すると、フレームワークをFrameworks
任意のアプリのフォルダー内にインストールできます。
しかし、物事はまだ完璧ではありません。フレームワークはまだそれがどこに置かれるべきかを指示しています。たとえば、別のアプリがLibraries
代わりにフレームワークをフォルダー内に配置したい場合、それは運が悪いです。フレームワークは、アプリではなく、配置できる場所を担当します。これは依存関係ツリーの反転であり、理想的ではありません。アプリは、他のフレームワークが何をするかに関係なく、フレームワークを隠したい場所からフレームワークをロードできる必要があります。
そのため、OSX10.5では@rpath
が導入されました。dylibまたはフレームワークのインストール名がで始まる@rpath
場合、ローダーは向きを変えてアプリに「Runpath検索パス」とは何かを尋ね、それらを置き換えます。これにより、アプリはフレームワークが存在する場所を指定できます。を使用することにより@rpath
、フレームワークは決定をアプリに委任します。アプリは必要に応じて使用でき@loader_path
、必要に応じて絶対パスを指定できます。アプリスイート全体が使用する共有フォルダーを指定することもできます。
あなたの問題
だから、あなたの問題に移ります。アプリの実行パス検索パスをに正しく設定しています@loader_path/../Frameworks
。ただし、フレームワークのインストール名は@rpath
;を使用していません。実際、それはまだへのハードコードされたパスを使用してい/Library/Frameworks/...
ます。フレームワークのインストール名はを使用しないため@rpath
、アプリの実行パスは参照されません。フォルダからSBJSONにリンクしようとしているだけ/Library
です。そこにないため、アプリが起動する前にクラッシュします。
を使用するには、SBJSONフレームワークのインストール名を変更する必要があります@rpath
。ダイナミックライブラリのインストール名の設定をに設定し@rpath/${EXECUTABLE_PATH}
ます。(${EXECUTABLE_PATH}
フレームワークを含むフォルダーからの内部ダイナミックライブラリへの相対パスです。)
新しいインストール名でフレームワークを構築すると、新しいフレームワークにリンクできるようになり、アプリバンドルのFrameworks/
フォルダーにコピーされていることを確認できます。これで準備完了です。
PSこれがすべて明確ではない場合、マイクアッシュは@rpath
と友人のかなり良いレビューをしました。ここで見つけることができます。