g ++は小さなプロジェクトにも関わらず大きなバイナリを生成します
-
10-07-2019 - |
質問
おそらくこれはよくある質問です。実際、私は何年も前にそれを尋ねたと思うが...答えを思い出せない。
問題は、6つのソースファイルで構成されるプロジェクトがあることです。それらはすべて200行以下のコードです。多くのSTLコンテナー、stdlib.hおよびiostreamを使用します。現在、実行可能ファイルのサイズは約800kbです。...ライブラリを静的にリンクすべきではないと思います。 GCCでこれを行う方法は?そして、Eclipse CDTで?
編集: 私が望むものから離れて応答するとき、私はそれが明確化の場合だと思う。私が知りたいのは、そのような小さなプログラムが非常に大きなサイズである理由と、静的な共有ライブラリとの関係とその違いは何かということです。話が長すぎる場合は、ドキュメントへのポインタをお気軽にお寄せください。ありがとう
解決
g ++動的ライブラリ名を指定し、-static
フラグを渡さない場合、動的にリンクする必要があります。
サイズを縮小するには、もちろんstrip
バイナリを使用し、-Os
(サイズの最適化)最適化フラグをg++
に渡します。
他のヒント
覚えておくべきことの1つは、STLを使用すると、C ++ライブラリと動的にリンクしている場合でも、余分なコードが実行可能ファイルにある ということです。これは、STLがコードを記述してコンパイルするまで実際にコンパイルされないテンプレートの束であるという事実によるものです。ライブラリはコンテナに何を格納するかを予測できないため、そのコンテナの特定の使用法のコードをライブラリに既に含める方法はありません。 STLのアルゴリズムおよびその他すべてについても同様です。
これが、実行可能ファイルが予想よりもはるかに大きい理由であることは間違いありません。しかし、それは要因かもしれません。
Eclipseは、メイクファイルでリンカーに静的フラグを設定していない限り、デフォルトで動的にリンクする必要があります。
編集への応答:
-静的にリンクすると、実行可能ファイルには、リンクした各ライブラリの完全なコピーが含まれます。
-動的にリンクする場合、実行可能ファイルには、リンクされたライブラリへの参照とフックのみが含まれます。これは、はるかに少ないコードです。
実行可能ファイルには、コード以外のものも含める必要があります。
少なくとも、プログラムを起動する前に、環境を設定し、必要に応じて外部ライブラリをロードするスタートアップコードが含まれています。
ランタイムライブラリを静的にリンクしている場合は、実行可能ライブラリにも含まれます。それ以外の場合は、システムコールを外部ランタイムにリダイレクトするのに十分な大きさの小さなスタブのみを取得します。
コンパイラの設定によっては、多くのデバッグ情報やその他の非必須データも含まれる場合があります。最適化が有効になっている場合、コードサイズも大きくなる可能性があります。
本当の問題は、なぜこれが重要なのかですか? 800KBはまだフロッピーディスクに簡単に収まります! これのほとんどは1回限りの費用です。 2倍のコードを記述した場合、1600KBを占有するという意味ではありません。おそらく、それは810KBまたはそのようなものが必要です。
1回限りの起動コストについて心配する必要はありません。
-O3および-sフラグを使用して、最適化されたバイナリを生成します。詳細については、リンクもご覧ください。
Windows用にビルドする場合は、Microsoftコンパイラの使用を検討してください。そのプラットフォームで常に最小のバイナリを生成します。
サイズにより、通常、静的ライブラリがアプリケーションにリンクされます。
リリースバージョンにコンパイルし、バイナリサイズを最適化することで、コンパイル済みバイナリのサイズを縮小できます。
実行可能サイズの別のソースはライブラリです。あなたはSTD以外の外部ライブラリを使用しないと言ったので、実行可能ファイルにCランタイムを含めている、つまり静的にリンクしていると思います。動的リンクを確認してください。
IMOについてはあまり心配するべきではありませんが、本当に偏執的な場合は、これを確認してください: Smallest x86 ELF Hello World
Visual C ++ 6.0を使用する Windows 95からWindows 7でサポートされていました。 x86プラットフォームとしてコンパイルできますが、Windows専用です。 あなたがWindowsユーザーであるならば、実際にsuxであるGCC以外のWindowsコンパイラに固執するだけです。VisualC ++がsuxであると言う人々のほとんどは、彼らが反Microsoftersです。 また、<!> quot; Visual C ++ 6.0 <!> quot;を使用することも忘れないでください。新しいものを使用すると、おそらくWindows 95でファイルを実行できなくなります。これらすべてをテストしました。 GCCは最大のバイナリを生成しますが、Visual C ++ではなく、インテル®コンパイラーは30%以上のスペースを節約するために使用できますが、パフォーマンスが恐ろしくなければ、インテル®プロセッサーが必要です。 覚えておく必要があるもう1つのことは、小さな行が表示されてもテンプレートを使用する場合です。 コンパイルすると、これらの関数が展開されるため、結果としてバイナリが大きくなります。 小さなバイナリが必要な場合は、Cに移行することをお勧めします。Cは実際には広く使用されていますが、オブジェクト指向ではありません。 infact CはC ++よりも使いやすい これは理にかなっていて、C ++の例
cout <!> lt; <!> lt; <!> quot; Hello World <!> quot; <!> lt; <!> lt; endl; printf(<!> quot;%s <!> quot;、<!> quot; Hello World <!> quot;);
2番目の例では、印刷フィールド%sは文字列を入力することを意味するため、簡単です。 :P