13

4kデモシーンコンテストについて知りました。素敵な 3D シーンをレンダリングする 4KB の実行可能ファイルを作成します。引用されたデモは Windows 用にビルドされたものだったので、Linux で 4KB の OpenGL シーンを作成する方法を知りたいと思っていました。

素の「hello world」はすでに 8KB を消費しています:

$ cat ex.c
#include <stdio.h>

int main()
{
       printf("Hello world\n");
}
$ gcc -Os ex.c -o ex
$ ls -l ex
-rwxrwxr-x 1 cklein cklein 8374 2012-05-11 13:56 ex
4

3 に答える 3

11

標準設定では小さなツールを作成できない主な理由は、多くのシンボルと標準ライブラリへの参照がバイナリに取り込まれるためです。その基本的なものでさえも削除するには、明示的にする必要があります。

これが私がそれをした方法です:

http://phresnel.org/gpl/4k/ntropy2k7/

関連するオプション:

主に自明:

gcc main.c -o fourk0001 -Os -mfpmath=387 \
  -mfancy-math-387 -fmerge-all-constants -fsingle-precision-constant \
  -fno-math-errno -Wall -ldl -ffast-math -nostartfiles -nostdlib  \
  -fno-unroll-loops -fshort-double

マッサージ:

stripバイナリに埋め込まれている不要なシンボルを取り除くのに役立ちます。

strip -R .note -R .comment -R .eh_frame -R .eh_frame_hdr -s fourk0001

コード:

微調整と試行錯誤が必要になる場合があります。ループによって小さなコードが生成されることもあれば、呼び出しが行われることもあり、強制的にインライン化される関数が生成されることもあります。私のコードでは、たとえば、派手な多形スタイルのすべての炎の変換を含むクリーンなリンクリストを作成する代わりに、各要素が、すべての炎の結合として、使用済みまたは未使用のすべてのパラメーターを含む大きなエンティティである固定配列を使用しています。スコット・ドレイブスの炎の紙による。

あなたのトリックは移植性がありません、他のバージョンのg++は次善の結果を与えるかもしれません。

上記のパラメーターを使用して、関数を作成するのmain()ではなく、関数を作成することに注意してください_start()

また、ライブラリの使用は少し異なることに注意してください。SDLと標準ライブラリ関数を上品で便利な方法でリンクする代わりに、手動でリンクする必要があります。例えば

void *libSDL = dlopen( "libSDL.so", RTLD_LAZY );
void *libC = dlopen( "libc.so", RTLD_LAZY );
#if 1
    SDL_SetVideoMode_t sym_SDL_SetVideoMode = dlsym(libSDL, "SDL_SetVideoMode");
    g_sdlbuff = sym_SDL_SetVideoMode(WIDTH,HEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
#else
    ((SDL_SetVideoMode_t)dlsym(libSDL, "SDL_SetVideoMode"))(WIDTH,HEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
#endif


//> need malloc, probably kinda craft (we only use it once :| )
//> load some sdl cruft (cruft!)
malloc_t sym_malloc = dlsym( libC, "malloc" );
sym_rand   = dlsym( libC, "rand" );
sym_srand  = dlsym( libC, "srand" );
sym_SDL_Flip          = dlsym(libSDL, "SDL_Flip");
sym_SDL_LockSurface   = dlsym(libSDL, "SDL_LockSurface");
sym_SDL_UnlockSurface = dlsym(libSDL, "SDL_UnlockSurface");
sym_SDL_MapRGB        = dlsym(libSDL, "SDL_MapRGB");

また、アセンブラに害を及ぼす必要はありませんが、コードによってUBが生成される可能性があります。


編集:

おっと、私は組み立てについて嘘をついた。

void _start() {
    ...
    asm( "int $0x80" :: "a"(1), "b"(42) );
}

これにより、プログラムは42を返します。

于 2012-05-11T13:19:03.717 に答える
8

A Whirlwind Tutorial on Making Really Teensy ELF Executable for Linuxは、可能な限り小さな ELF 実行可能ファイルを作成するための段階的なプロセスを説明する興味深い記事です。

エンディングを台無しにしたくありませんが、作者は4K よりもはるかに小さくしています ;)

于 2012-05-11T13:36:38.410 に答える
1

しばらく前の KSplice ブログのこの記事をご覧ください。標準ライブラリなしでリンクすることについて話します。

https://blogs.oracle.com/ksplice/entry/hello_from_a_libc_free

于 2012-05-11T12:55:23.120 に答える