ライブラリとバイナリをリンクするVS Embed Frameworksで説明されているように、これら2つのオプションの違いについては良い質問があります。
両方を使用するオプションがあるようですが、どちらの場合に埋め込まれたバイナリをより適切に使用する必要があるのか、またはリンクされたフレームワークではなく、
これをより明確にする具体例はありますか?ありがとう
ライブラリとバイナリをリンクするVS Embed Frameworksで説明されているように、これら2つのオプションの違いについては良い質問があります。
両方を使用するオプションがあるようですが、どちらの場合に埋め込まれたバイナリをより適切に使用する必要があるのか、またはリンクされたフレームワークではなく、
これをより明確にする具体例はありますか?ありがとう
回答:
リンクした質問は、「バイナリをライブラリにリンクする」機能を参照しています。これは、埋め込みバイナリとは多少異なります。
「ライブラリとバイナリをリンクする」とは、リンケージに関して期待することを意味します。バイナリが静的ライブラリ、動的ライブラリ、フレームワークのいずれであるかに関係なく、コンパイル後のリンク時にオブジェクトコードにリンクされます。
静的ライブラリとのリンケージについて考えると、何が起こるかは非常に明確です。リンカはライブラリ(例:)から出力バイナリにコードをコピーlibFoo.a
します。出力ファイルのサイズは大きくなりますが、実行時に外部の依存関係を解決する必要はありません。プログラムが実行する必要があるすべて(静的ライブラリに関して)は、ビルド後に存在します。
動的ライブラリー(.dylib、またはシステム提供のフレームワーク)では、リンク先のライブラリーは、プログラムの実行時にシステムの動的ライブラリー・ローダーのパスのどこかに存在することが期待されます。これにより、サードパーティのすべての外部ライブラリをバイナリにコピーするオーバーヘッドがなくなり、そのライブラリにリンクしているコンピューター上のすべての異なるプログラムがそれを見つけることができるため、ディスク領域を最小限に節約できますが、システムがライブラリをキャッシュする方法と場所に応じて、潜在的にメモリ領域。
フレームワークは動的ライブラリによく似ていますが、ディレクトリ構造にリソース(イメージ、オーディオ、その他のフレームワークなど)を含めることができます。この場合、単純な静的ライブラリまたは.dylibファイルはそれをカットしないため、適切に実行するために必要なものを見つけるために、フレームワークにリンクする必要がある場合があります。
サードパーティのフレームワーク(githubからダウンロードして自分でビルドしたものなど)にリンクすると、実行する予定のシステムに存在しない場合があります。この場合、フレームワークにリンクするだけでなく、「フレームワークのコピー」フェーズを使用して、アプリケーションバンドル内に埋め込みます。プログラムが実行されると、ランタイムリンカー(別名リゾルバー)がシステムローダーパスに加えてバンドル内を調べ、埋め込まれたフレームワークを見つけてリンクし、アプリを実行するために必要なコードを提供します。
最後に、適切に「組み込みバイナリ」とは、ファイルコピーフェーズを介して両方ともアプリケーションバンドルに埋め込んだ実行可能ファイルであり、おそらく呼び出しなどで自分で実行しますpopen()
。埋め込まれたバイナリはプログラムから呼び出されることがありますが、リンクされていません。これは完全に外部のエンティティです(/bin
ディレクトリ内のプログラムのように)。
実際には、システムが提供するライブラリとフレームワークの場合は、それらをリンクします。
組み込みリソースを必要としない(つまり、フレームワークの存在を必要としない)作成したライブラリをリンクする必要がある場合は、静的ライブラリに対してリンクするだけで済みます。プログラム内に同じライブラリコードを使用する複数のモジュールがある場合は、それをフレームワークまたはダイナミックライブラリに変換してリンクすると、スペースを節約でき、便利です(特にメモリ使用量が懸念される場合)。
最後に、フレームワークにはリソースだけでなく、ヘッダーやライセンスファイルを含めることができます。これらのファイルを伝達するためにフレームワークを使用することは、実際には便利な配布メカニズムです。そのため、これらのものがタグ付けできるようにフレームワークを組み込むことが必要になる場合があります(つまり、ライセンス要件により、これが必須になる場合があります)。
---編集---
Adam Johnsがコメントとして次の質問を投稿しました:
これは素晴らしい答えです。しかし、私はまだ少し混乱しています。バイナリを自分で実行するとはどういう意味ですか?単に組み込みフレームワークのコードを使用することを意味しますか?popen()について言及しましたが、私のアプリがpopen()を呼び出していると言っているのですか?どういう意味かよくわかりません。
私が言っている埋め込まれたバイナリは、ファイルの代わりに実行可能なコマンドラインツールですが、音声ファイルや画像のように、あなたのバンドル内のちょうど別のリソースファイルです。このpopen()
機能(man popen
ターミナルから詳細を読む)を使用すると、実行中の別のプログラムから任意のプログラムを実行できます。system()
機能は別の方法です。他にもありますが、ここでは、埋め込みバイナリの使用を少し明確にする歴史的な例を示します。
ご存知のように、Mac OS Xでアプリを起動すると、現在のユーザーのユーザーIDで起動されます。ほとんどの一般的なインストール環境admin
では、ユーザーIDが与えられたデフォルトのデスクトップユーザー501
です。
Unixベースのオペレーティングシステムでは、root
ユーザー(ユーザーID 0
)のみがファイルシステム全体へのフルアクセス権を持っています。デスクトップユーザーが起動したインストーラプログラムが、特権のあるディレクトリ(ドライバなど)にファイルをインストールする必要がある場合があります。この場合、アプリケーションプログラムはroot
、これらの制限されたディレクトリに書き込むことができるように、その特権をユーザーに昇格させる必要があります。
OS X 10.7を介してオペレーティングシステムでこれを容易にするために、AppleはAuthorization Services APIに関数AuthorizationExecuteWithPrivileges()を提供しました(これは現在非推奨ですが、まだ有用な例です)。
AuthorizationExecuteWithPrivileges()
として実行するコマンドラインツールへのパスを引数として取りましたroot
。コマンドラインツールは、インストールロジックを実行するために記述した実行可能なシェルスクリプトまたはコンパイル済みバイナリでした。このツールは、他のリソースファイルと同じようにアプリケーションバンドル内にインストールされました。
呼び出されると、OSはユーザーのパスワードを要求する認証ダイアログを表示し(これは以前に確認したことです!)、入力するとroot
、アプリに代わってプログラムが実行されます。このプロセスは、popen()
自分でプログラムを実行するのと似ていますが、それpopen()
だけでは特権の昇格のメリットはありません。
link
つまり、ですが、ファイルのコピーフェーズを介して埋め込む必要があることは間違いありません(それ以外の場合はどのように使用しますか?)。サードパーティのフレームワークまたは埋め込みバイナリを使用する目的は、エンティティが提供するコードを実行することです。埋め込まれたバイナリでは、リンクは必要ありません。実行時にバイナリへのパスを作成し、手動で実行します。フレームワークを使用すると、アプリをビルドするときにコンパイル時リンカーがリンクします(サードパーティのフレームワークの場合)は、ファイルのコピーフェーズを介して埋め込み、最後に、アプリを実行するときにランタイムリンカーが再度リンクします。
Dependency
経営の一部です【概要】
タブのセクションXcode 11
のみが含まれていることに注意してくださいFrameworks, Libraries, and Embedded Content
General
Build Phases -> Link Binary With Libraries
はのミラーですGeneral -> Linked Frameworks and Libraries
。
静的ライブラリとフレームワーク
Static Library or Static Framework
このセクションにを追加すると、Frameworks
グループ[概要](Project Navigator -> <workspace/project> -> Frameworks
)に表示され、プロジェクトに参照が追加されます。次に、によって使用されStatic Linker
ます。Static Linker
コンパイル時に、ライブラリのすべてのコードを実行可能オブジェクトファイルにインクルード/コピーします。Static linker
と組み合わせて動作しますBuild Settings -> <Library/Framework> Search Paths
Static Library
Build Settings -> Library Search Paths
[ライブラリが見つかりません ]static library
このセクションにaを追加しないと、リンカーエラーが発生します [ld:シンボルが見つかりません] Static Framework
Build Settings -> Framework Search Paths
。static framework
このセクションにを追加しないと、コンパイルエラーが発生します[そのようなモジュールはありません]静的ライブラリと静的フレームワーク
埋め込みはのためにどんな意味がありませんStatic Library
し、Static Framework
それらからのシンボルは実行可能なバイナリにコンパイルされているため。Xcode static library
では、埋め込みセクションの下にaをドロップできません。
動的フレームワーク
Build Phases -> Embed Frameworks
はのミラーですGeneral -> Embedded Binaries
。実際に埋め込むと、フレームワークのコピーがアプリケーションバンドルに追加されます。その結果、フレームワークがEmbed
セクションに追加/削除されると、自動的にLinked
セクションに追加/削除されます。デフォルトでは、バンドルのフォルダーはですFrameworks
が、Destination
フィールドを使用して変更できます。さらに、を指定できますSubpath
。
Dynamic linker :dyld
で、ロードまたは実行時見つけようとします埋め込まれたフレームワークを使用して@rpath
、[概要]には、エラーが発生しますが見つからない場合は、[dyldの:ライブラリがロードされていません]