2012-03-29 29 views
10

これはiOSに関する質問です。最後のバイナリのサイズが静的ライブラリのサイズよりもずっと小さいのはなぜですか?

iOSに静的ライブラリ(フレームワーク)を作成してアプリに組み込みました。結果バイナリ(500kb)のサイズは、スタティックライブラリ(6mb)のサイズよりも小さくなります。これはどのように作動しますか?静的ライブラリの私の理解は、静的ライブラリが最終バイナリに含まれていることです。

答えて

21

ライブラリのすべての機能を使用していないためです。アーカイブタイプ.aの静的ライブラリは、.oオブジェクトファイルのコレクションであり、プログラムに必要なオブジェクトファイルのみがリンク時に含まれています。

+1

これに加えて、適切にファクタ化されたライブラリは、別々の '.o'ファイルにそれぞれの関数(または密接に関連する関数群)を持っています。そのような使用法では、 '.o'ファイルのヘッダオーバーヘッドは各.oファイルのファイルサイズの25%になりえます。最悪の場合、オーバーヘッドはコードサイズの数十倍または数百倍になります。つまり、よく熟慮された '.a'ファイルは、通常50%のコードと50%の' .o'ファイルヘッダーです。もちろん、これはouahの答えといっしょに機能します。つまり、ライブラリをよく整理すると、リンカが不要なオブジェクトファイルを省略する機会が増えます。 –

+0

原則として@R ..のコメントに同意します。しかし、最近のツールではこれらのタスクのいくつかを自動的に行うことができます(例えば、gccの '-ffunction-sections'(効果的に各関数を.oファイルに入れます)など)、ソースコードレベルでこれを行うことはできませんかつてと同じくらい重要でした。 – ldav1s

+0

@ ldav1s: '-ffunction-sections'と関連するオプションが利用可能ですが、それらは広く使われているとは思いませんし、必要なリンカオプションがデフォルトで有効になっているかどうかはわかりません。関数ポインタを含む静的構造体のように、 '-ffunction-sections'が不要な関数を取り除くのに不十分であるような場合もあります。 –

3

すべてあなたが知っているシンボルが今すぐリンカに提供されているので、リンカは実行ファイルを静的にリンクすると、すべてのシンボル名を解決することができます.oのファイルと.aのライブラリは、実際には.oファイルのコレクションです)。そこに名前がない場合、リンクエラーが発生します(実行時に別のライブラリをロードできるダイナミックリンクとは異なります)。あなたの場合、実行可能ファイルによって参照されない余分なシンボルがあります。これらのシンボルはリンカに対して未使用であると認識されているため、実行可能な出力から単に削除されます。この場合、実行ファイルは入力ライブラリよりも小さくなります。

+0

'-Objc'または' -all_load'フラグを追加するとどうなりますか? – Tony

+0

'-Objc' [ここに記載されています](https://developer.apple.com/library/content/qa/qa1490/_index.html)の効果は、「Objective- Cクラスまたはカテゴリ "と表示され、"結果として実行可能ファイルが大きくなり、不要なオブジェクトを取得する可能性があります "と警告が表示されます。これにより、実行可能ファイルが通常のリンクよりも大きくなります(それらのオブジェクトがある場合)。 '-all_load'は、より多くのオブジェクトコードを含む[この記述](http://stackoverflow.com/a/2906210/425738)に従ったオブジェクトコードを含め、より積極的に聞こえます。 – ldav1s

+0

これは、フラグを追加するとき、実行ファイルはそれに含まれるライブラリの組み合わせと同じ大きさでなければならないということですか?実際にはそうではないようです。 – Tony

関連する問題