特定のプロジェクトでフレームワークを使用する静的ライブラリ 質問する

特定のプロジェクトでフレームワークを使用する静的ライブラリ 質問する

すべての汎用クラスを含む静的ライブラリを作成しました。これらのクラスの一部はフレームワークを使用します。

現在、フレームワークを使用するクラスを使用するプロジェクトと、フレームワークを使用するクラスをまったく使用しないプロジェクトの 2 つがあります。

静的ライブラリはフレームワークの組み込みをサポートしていないためです (私の記憶が正しければ)。フレームワークを使用するプロジェクトにフレームワークを組み込む必要があります。しかし、フレームワーク クラスをまったく使用しないプロジェクトをコンパイルすると、フレームワークがまだ必要なためコンパイラが壊れます。リンカー フラグ '-ObjC' を使用して '認識されないセレクター' エラーを防止しているため、ライブラリからすべての (未使用の) クラスをコンパイルしようとしていることがわかりました。

プロジェクトごとに必要なソース ファイルのみをコンパイルする方法を知っている人はいますか? また、静的ライブラリを使用するすべてのプロジェクトにすべてのフレームワークを含める必要がないようにする方法はありますか?

ベストアンサー1

まず、静的ライブラリにはフレームワークや他の静的ライブラリを含めることはできず、その特定の静的ライブラリを構成するすべてのオブジェクト ファイル (*.obj) のコレクションのみであることはご指摘のとおりです。

プロジェクトごとに必要なソース ファイルのみをコンパイルする方法を知っている人はいますか?

リンカーは、デフォルトでは、アプリケーションによって参照されるシンボルを含む静的ライブラリのオブジェクト ファイルのみをリンクします。したがって、静的ライブラリにa.mと の2 つのファイルがあり、メイン プログラムで のシンボルのみを使用する場合、( から生成されたオブジェクト ファイル) は最終的な実行可能ファイルには表示されません。サブケースとして、 が宣言のみの (実装されていない)関数/クラスを使用する場合、リンカー エラーは発生しません。プログラムにのシンボルをいくつか含めるとすぐにもリンクされ、 の実装がないためリンカー エラーが発生します。b.ma.mb.ob.cb.mcb.mb.oc

この種の選択をオブジェクト レベルの粒度ではなくシンボルで実行する場合は、Xcode でデッド コードの除去を有効にします。これは、gcc オプション -Wl,-dead_strip (プロジェクトのビルド設定情報ペインのリンカー オプション -dead_strip) に対応します。これにより、さらなる最適化が保証されます。

ただし、あなたの場合、あなたが正しく述べているように、このメカニズムを無効にするのは「-ObjC」リンカー フラグの使用です。したがって、これは実際にはあなた次第です。-Objc フラグを削除すると、セレクターのより厳格なチェックは失われますが、希望する動作は無料で得られます。

そして、静的ライブラリを使用するすべてのプロジェクトにすべてのフレームワークを含める必要がないようにしますか?

Xcode/GCCは「弱いリンク」を使用すると、フレームワークまたは静的ライブラリを遅延ロードできます。つまり、そのシンボルの 1 つが実際に使用されている場合にのみロードできます。「弱いリンク」は、リンカー フラグ (上記の Apple ドキュメントを参照) または Xcode UI (ターゲット -> 情報 -> 全般 -> リンクされたライブラリ) を通じて有効にできます。

いずれにせよ、フレームワークまたはライブラリは、コンパイル/リンク時に常に使用可能である必要があります。「weak」オプションは、実行時にフレームワークが最初にロードされる瞬間にのみ影響します。したがって、フレームワークをすべてのプロジェクトに含める必要があるため、これは役に立たないと思いますが、これは望ましくありません。

補足として、weak_linkingこれは、新しい SDK バージョン (たとえば 4.3.2) でのみ利用可能な機能を使用しながら、古い SDK バージョン (たとえば 3.1.3) での展開もサポートする場合に最も意味のあるオプションです。この場合、新しい SDK フレームワークが新しい展開デバイスで実際に利用可能であるという事実に依存し、それを必要とする機能を条件付きでコンパイルします。これにより、古いデバイスではそれらの機能が不要になります (したがって、新しいバージョンのフレームワークをロードしようとしてクラッシュが発生することはありません)。


さらに悪いことに、GCC は、ソース ファイル内の #pragma コメントを使用してリンクするライブラリを指定できる、Microsoft コンパイラの「自動リンク」と呼ばれる機能をサポートしていません。これは回避策になる可能性がありますが、現在は存在しません。


したがって、誠に残念ですが、お客様のニーズを同様に満たすことができる別のアプローチを使用する必要があると言わざるを得ません。

  1. -ObjC フラグを削除します。

  2. 外部フレームワークからの依存関係に応じて、静的ライブラリを 2 つ以上の部分に分割します。

  3. ソースファイルを直接含める方法に頼ります。

おすすめ記事