GNU/Linux >> Linux の 問題 >  >> Linux

生成されたバイナリのサイズを小さくするには?

明らかなことは別として (-Os -s )、関数をクラッシュしない最小の値に調整すると(ARMの調整要件はわかりません)、関数ごとに数バイトが圧迫される可能性があります。
-Os すべき すでに整列機能を無効にしていますが、これはまだデフォルトで 4 や 8 などの値になっている可能性があります。 to 1 は ARM で可能で、数バイト節約できます。

-ffast-math (または研磨の少ない -fno-math-errno ) は errno を設定せず、いくつかのチェックを回避するため、コード サイズが削減されます。ほとんどの人と同じように、とにかく errno を読まない場合、それはオプションです。

__restrict を適切に使用する (または restrict ) と const 冗長なロードを取り除き、コードをより速く、より小さく (そしてより正確に) します。純粋な関数をそのように適切にマークすると、関数呼び出しが排除されます。

LTO を有効にすると役立つ場合があります。それが利用できない場合は、すべてのソース ファイルを一度にバイナリにコンパイルします (gcc foo.c bar.c baz.c -o program foo.c をコンパイルする代わりに 、 bar.c 、および baz.c 最初にオブジェクトファイルにリンクしてからリンクする)と同様の効果があります。オプティマイザが一度にすべてを可視化できるため、より適切に機能する可能性があります。

-fdelete-null-pointer-checks オプションの場合があります (これは通常、任意の "O" で有効になりますが、無効 であることに注意してください 埋め込みターゲット)

静的グローバル (あまり多くないことを願っていますが、それでも) を構造体に配置すると、多くのオーバーヘッドを排除できます。 それらを初期化しています。初めて OpenGL ローダーを作成したときに、そのことを知りました。構造体にすべての関数ポインターを持ち、構造体を = {} で初期化する memset への 1 つの呼び出しを生成します 、一方、「通常の方法」でポインターを初期化すると、それぞれを個別にゼロに設定するためだけに 100 キロバイトのコードが生成されます。

非自明なコンストラクタの static local を避ける 悪魔のような変数 (POD タイプは問題ありません)。 -fno-threadsafe-statics でコンパイルしない限り、Gcc は非自明なコンストラクターの静的ローカル スレッドセーフを初期化します。 、たくさんリンクしています (スレッドをまったく使用しない場合でも) 余分なコードはありません。

通常の crt の代わりに libowfat のようなものを使用すると、大きく バイナリ サイズを小さくしてください。


バイナリから最後の一滴までスペースを絞り出したい場合は、おそらくアセンブリを学習する必要があります。非常に興味深い (そして面白い) イントロについては、次のリンクを参照してください:

Linux 用の非常に小さな ELF 実行可能ファイルの作成に関する旋風チュートリアル


次も使用できます -nostartfiles および/または -nodefaultlibs または両方の組み合わせ -nostdlib .標準の開始ファイルが必要ない場合は、独自の _start 関数を作成する必要があります。 oompf のこのスレッド (アーカイブ済み) も参照してください:

(ペリンの言葉を引用)

# man syscalls
# cat phat.cc
extern "C" void _start() {
        asm("int $0x80" :: "a"(1), "b"(42));
}
# g++ -fno-exceptions -Os -c phat.cc
# objdump -d phat.o

phat.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <_start>:
   0:   53                      push   %rbx
   1:   b8 01 00 00 00          mov    $0x1,%eax
   6:   bb 2a 00 00 00          mov    $0x2a,%ebx
   b:   cd 80                   int    $0x80
   d:   5b                      pop    %rbx
   e:   c3                      retq
# ld -nostdlib -nostartfiles phat.o -o phat
# sstrip phat
# ls -l phat
-rwxr-xr-x 1 tbp src 294 2007-04-11 22:47 phat
# ./phat; echo $?
42

要約:上記のスニペットは 294 バイト のバイナリを生成しました 、各バイト 8 ビット。


別のツールも許可されていると仮定します;-)

次に、UPX を検討してください。これは、ランタイム解凍を使用するバイナリ用の究極のパッカーです。

コーディングをお楽しみください。


Linux
  1. Linux –ツリーとディレクトリサイズを組み合わせる方法は?

  2. Apache でファイル ダウンロード サイズの制限を増やす方法

  3. stat コマンドはファイルのブロックをどのように計算しますか?

  1. Linuxのソケットバッファサイズを見つける方法

  2. Linux でファイルとディレクトリのサイズを確認するにはどうすればよいですか?

  3. RAID5 ディスク上のデータはどの程度スクランブルされていますか?

  1. Linuxでファイルの物理サイズを取得するには?

  2. Linux で ext3 パーティションのブロック サイズを確認するにはどうすればよいですか?

  3. dd コマンドの最適なバイト サイズを決定する方法