web-dev-qa-db-ja.com

Xcodeで「リンクされたフレームワーク」ではなく「埋め込みバイナリ」を使用する必要があるのはいつですか?

バイナリをライブラリVS Embed Frameworksとリンクする で説明されているように、これら2つのオプションの違いについて良い質問があります。

両方を使用するオプションがあるように思えますが、どちらの場合に埋め込みバイナリを使用するべきか、リンクされたフレームワークを使用する必要があるのでしょうか?

これに対処するための具体的な例はありますか?ありがとう

124
Forrest

リンクした質問は、「バイナリとライブラリをリンク」機能を参照していますが、これは埋め込みバイナリとは多少異なります。

「ライブラリとバイナリをリンクする」とは、リンケージに関して期待することを意味します。バイナリが静的ライブラリ、動的ライブラリ、またはフレームワークであるかどうかに関係なく、コンパイル後のリンク時にオブジェクトコードにリンクされます。

静的ライブラリとのリンケージを考えると、何が起こるかはかなり明確です。リンカはライブラリからコードをコピーします(例:libFoo.a)出力バイナリに。出力ファイルのサイズは大きくなりますが、実行時に外部依存関係を解決する必要はありません。プログラムの実行に必要なものはすべて(静的ライブラリに関して)ビルド後に存在します。

動的ライブラリ(.dylib、またはシステム提供のフレームワーク)を使用すると、リンク先のライブラリが、プログラムの実行時にシステムの動的ライブラリローダーパスのどこかに存在することが期待されます。この方法では、すべてのサードパーティの外部ライブラリをバイナリにコピーするオーバーヘッドがなく、そのライブラリにリンクしているコンピューター上のすべての異なるプログラムがそれを見つけることができるため、ディスクスペースを最小限に抑えますが、システムがライブラリをキャッシュする方法と場所に応じて、潜在的にメモリ空間。

フレームワークは動的ライブラリによく似ていますが、ディレクトリ構造にリソースを含めることができます(画像、オーディオ、他のフレームワークなど)。この場合、単純な静的ライブラリまたは.dylibファイルはそれをカットしないので、フレームワークにリンクする必要があるかもしれませんitは何を見つけることができます適切に実行する必要があります。

サードパーティのフレームワーク(githubからダウンロードして自分でビルドしたものなど)にリンクすると、実行しようとしているシステムに存在しない場合があります。この場合、フレームワークにリンクするだけでなく、「フレームワークのコピー」フェーズを使用して、アプリケーションバンドルに組み込みます。プログラムが実行されると、ランタイムリンカー(別名リゾルバー)は、システムローダーパスに加えてバンドル内を調べ、組み込みフレームワークを見つけ、リンクして、アプリが実行に必要なコードを持つようにします。

最後に、適切に「埋め込みバイナリ」とは、Copy-Files Phaseを介してアプリケーションバンドルに埋め込み、_popen()または同様の呼び出しを使用して自分で実行する実行可能ファイルです。埋め込まれたバイナリはプログラムによって呼び出される場合がありますが、リンクされていません。これは完全に外部のエンティティです(/binディレクトリ内のプログラムなど)。

実際には、システムが提供するライブラリとフレームワークについては、それらに対してリンクします。それがあなたがする必要があるすべてです。

組み込みリソースを必要としない(つまり、フレームワークの存在を必要としない)構築したライブラリをリンクする必要がある場合は、静的ライブラリにリンクするだけです。プログラムに同じライブラリコードを使用したい複数のモジュールがある場合、それをフレームワークまたは動的ライブラリに変換し、それに対してリンクすると、スペースを節約でき、便利です(特にメモリ使用量が懸念される場合)。

最後に、フレームワークにはリソースだけでなく、ヘッダーやライセンスファイルを含めることができます。フレームワークを使用してこれらのファイルを伝達するのは実際には便利な配布メカニズムなので、多くの場合、フレームワークを組み込むことで、これらがバイナリとともにタグ付けできるようにすることができます(つまり、ライセンス要件により必須になる場合があります)。

---編集---

Adam Johnsは、コメントとして次の質問を投稿しました。

これは素晴らしい答えです。ただし、まだ少し混乱していることがあります。自分でバイナリを実行するとはどういう意味ですか?単に組み込みフレームワークのコードを使用するということですか? popen()に言及したことは知っていますが、私のアプリがpopen()を呼び出していると言っていますか?それが何を意味するのか本当に分かりません。

embedded binaryは、オーディオファイルや画像のようなバンドル内の単なる別のリソースファイルですが、ファイルは代わりに実行可能なコマンドです-ラインツール。 popen()関数(端末からman popenで詳細を読む)を使用すると、実行中の別のプログラムから任意のプログラムを実行できます。 system()関数は別の方法です。他にもあります。ここでは、埋め込みバイナリの使用をもう少しわかりやすくする歴史的な例を示します。

ご存じのとおり、Mac OS Xでアプリを起動すると、現在のユーザーのユーザーIDで起動されます。デフォルトのデスクトップユーザーadminユーザーである最も一般的なインストールでは、ユーザーID 501が与えられます。

Unixベースのオペレーティングシステムでは、rootユーザー(ユーザーID 0)のみがファイルシステム全体にフルアクセスできます。デスクトップユーザーが起動したインストーラープログラムは、特権ディレクトリ(ドライバーなど)にファイルをインストールする必要がある場合があります。この場合、アプリケーションプログラムは、これらの制限されたディレクトリに書き込むことができるように、その権限をrootユーザーにエスカレートする必要があります。

OS X 10.7を介してオペレーティングシステムでこれを容易にするために、 Authorization Services API 関数で提供されるApple AuthorizationExecuteWithPrivileges() (これは廃止されましたが、まだ有用な例です)。

AuthorizationExecuteWithPrivileges()は、rootとして実行するコマンドラインツールへのパスを引数として取りました。コマンドラインツールは、インストールロジックを実行するために作成した実行可能なシェルスクリプトまたはコンパイル済みバイナリでした。このツールは、他のリソースファイルと同様にアプリケーションバンドル内にインストールされました。

呼び出されると、OSはユーザーのパスワードを尋ねる認証ダイアログを表示し(これは以前に見たことがある!)、入力されるとアプリに代わってrootとしてプログラムを実行します。このプロセスは、popen()だけでプログラムを実行するのと似ていますが、popen()だけでは特権昇格のメリットは得られません。

211
par

要するに、

  • システムライブラリ、それらをリンクします。
  • サードパーティのライブラリ、それらを埋め込みます。

どうして?

  • システムライブラリを埋め込もうとしても、ポップアップリストには表示されません。
  • サードパーティのライブラリをリンクすると、おそらくクラッシュします。
23
Bright Future

appターゲットの場合

  • Static Library-Link it
  • Static Framework-Link it
  • Dynamic Framework-Embed it

リンクと埋め込み

0
yoAlex5