2016-08-26 2 views
1

私は別のチップ上で実行する必要のある小さなCプログラムを持っています。 実行ファイルは32kbより小さくする必要があります。 これには、アーム、ミップスなどのさまざまなコンパイラを持ついくつかのツールチェーンがあります。なぜ私の実行ファイルがリンク後に大きくなったのですか

このプログラムは、それぞれオブジェクトファイルにコンパイルされ、実行可能ファイルにリンクされた複数のファイルで構成されています。

gcc(x86)システムを使用すると、実行ファイルは15kbです。 アームツールチェーンを使用すると、実行ファイルは65kb大きくなります。 別のツールチェーンでは47kbです。

例えば、armの場合、実行可能ファイルに含まれているすべてのオブジェクトは、一緒に14kb大きいです。

オブジェクトは、次のオプションを指定してコンパイルされています。次のオプションをリンクするための

-march=armv7-m -mtune=cortex-m3 -mthumb -msoft-float -Os 

が使用されています:

-s -specs=nosys.specs -march-armv7-m 

nosys.specsライブラリは大きな274バイトです。

私のコードがわずか14kbでライブラリ274バイトのときに、実行ファイルがまだそれほど大きくない(65kb)のはなぜですか?

アップデート:私は私のコードから、すべてのmallocとprintfのコマンドを削除し、未使用が含まれて削除さ

答えからの提案の後。また、コンパイルフラグ-ffunction-sections -fdata-sectionsとリンクフラグ--gc-sectionsを追加しましたが、実行ファイルがまだ大きすぎます。

int main() 
{ 
    return 1; 
} 

私は別のコンパイラでプログラムをコンパイルするとき、私は非常に異なる実行ファイルのサイズを取得します:

8.3 KB : gcc -Os 
22 KB : r2-gcc -Os 
40 KB : arm-gcc --specs=nosys.specs -Os 
1.1 KB : avr-gcc -Os 

なぜそう私の腕-gccを実行可能である私はダミーのプログラムを作成して実験するために

ずっと大きい? avr-gcc実行ファイルも静的リンクを実行します。

+0

これはどのファイル形式ですか?これは未処理のバイナリイメージですか、それともelfやcoff、exeなどですか?ほぼすべての形式のファイルサイズは、必ずしも重要な実際のバイナリの直接の指標ではありません。 x86とarmの間には、動的ライブラリと静的ライブラリがあります。 –

+3

リンカマップファイルの出力を見ることから始めることができます。これは、画像にリンクされているものとすべてのメモリを掘り起こすアイデアを与えるはずです。私は推測することができますが、それはちょうどそのことです - 推測... – Dan

+0

あなたのx86ビルドはホストされていますか?つまり、WindowsやLinuxなどのフルGPOSで動作するように作られていますか?独立したアプリケーションでは、すべてのI/Oとライブラリコードが静的にリンクされている必要があります.GPOSは標準ライブラリとOSライブラリへの動的リンクをサポートし、多くのI/O機能がOSによって提供されます。 – Clifford

答えて

5

あなたのx86実行可能ファイルはおそらく動的にリンクされているので、使用する標準ライブラリ関数 - mallocprintf、文字列と数学関数などはバイナリに含まれません。

ARM実行ファイルは静的にリンクされているため、これらの関数をバイナリに含める必要があります。これが大きい理由です。サイズを小さくするには、-ffunction-sections -fdata-sectionsでコンパイルし、次に--gc-sectionsとリンクして、バイナリから使用されていない関数やデータを破棄してください。

(「nosys.specsライブラリは、」ライブラリではありません。これは、コンフィギュレーション・ファイルです。実際のライブラリファイルは、他の場所である。)

+0

'--gc-sections'(2つのハイフン)または' -Wl、-gc-sections'がgccによってリンカーに渡されることに注意してください。 –

+0

@ChrisStrattonそれを指摘してくれてありがとう! – duskwuff

+0

ヒントありがとうございます。残念ながら、私の場合、フラグはexecのサイズを減らさない。 – superbly

0

組込みソフトウェアの移植対象のハードウェアとソフトウェアプラットフォームに依存します。 ハードウェアプラットフォームはLinux OSを実行できるmcu、cpusに分割されています。 ソフトウェアプラットフォームには、コンパイラツールチェーンとライブラリが含まれています。

mcuとx86ハードウェアプラットフォームのプログラムイメージサイズを比較するのは意味がありません。 しかし、異なるツールチェーンを使用して、同じタイプのCPU上でプログラムイメージのサイズを比較することは価値があります。

関連する問題