13

我刚刚了解了4k 演示场景竞赛。它包括创建一个 4KB 的可执行文件,它可以渲染一个漂亮的 3D 场景。引用的演示是为 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

代码:

您可能需要进行很多调整和反复试验。有时,循环给出更小的代码,有时是调用,有时是强制内联函数。例如,在我的代码中,我没有一个包含所有花哨多态样式的火焰变换的干净链表,而是有一个固定数组,其中每个元素都是一个包含所有参数(使用或未使用)的大实体,作为所有火焰的联合根据 Scott Draves 火焰纸。

您的技巧不会是可移植的,其他版本的 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 Creating really Teensy ELF Executables 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 回答