简体   繁体   English

如何创建渲染3D场景的4KB Linux二进制文件?

[英]How to create 4KB Linux binaries that render a 3D scene?

I just learned about the 4k demo scene contest . 我刚刚了解了4k演示场景比赛 It consists in creating a 4KB executable which renders a nice 3D scene. 它包括创建一个4KB的可执行文件,它可以呈现一个漂亮的3D场景。 The cited demo was build for Windows, so I was wondering, how one could create 4KB OpenGL scenes on Linux. 引用的演示是为Windows构建的,所以我想知道如何在Linux上创建4KB的OpenGL场景。

A bare "hello world" already consumes 8KB: 一个简单的“你好世界”已经消耗了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

The main reason why with the standard settings you can't make a small tool is that a lot of symbols and references to standard libraries are pulled into your binary. 使用标准设置无法制作小工具的主要原因是许多符号和对标准库的引用都被引入到二进制文件中。 You must be explicit to to remove even that basic stuff. 你必须明确删除那些基本的东西。

Here's how I did it: 我是这样做的:

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

Relevant Options: 相关选项:

Mostly self-explaining: 主要是自我解释:

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

Massage: 按摩:

strip helps you get rid of unneeded symbols embedded in your binary: strip帮助您摆脱嵌入在二进制文件中的不需要的符号:

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

Code: 码:

You may have to tweak and trial and error a lot. 您可能需要进行大量调整和反复试验。 Sometimes, a loop gives smaller code, sometimes a call, sometimes a force inlined function. 有时,循环会提供较小的代码,有时会调用,有时会强制使用内联函数。 In my code, eg, instead of having a clean linked list that contains all flame transforms in fancy polymorphic style, I have a fixed array where each element is a big entity containing all parameters, used or unused, as a union of all flames as per Scott Draves flame paper. 在我的代码中,例如,我有一个固定的数组,其中每个元素都是一个包含所有参数的大实体,使用或未使用,作为所有火焰的联合,而不是拥有包含所有火焰变换的清晰链接列表。根据Scott Draves的火焰纸。

Your tricks won't be portable, other versions of g++ might give suboptimal results. 你的技巧将无法移植,其他版本的g ++可能会给出不理想的结果。

Note that with above parameters, you do not write a main() function, but rather a _start() function. 请注意,使用上述参数,您不会编写main()函数,而是编写_start()函数。

Also note that using libraries is a bit different. 另请注意,使用库有点不同。 Instead of linking SDL and standard library functions the classy, convenient way, you must do it manually. 您必须手动执行此操作,而不是以优雅,方便的方式链接SDL和标准库函数。 Eg 例如

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");

And even though no assembler has to be harmed, your code might yield UB. 即使没有汇编程序必须受到损害,您的代码也可能会产生UB。


edit: 编辑:

Oops, I lied about assembly. 哎呀,我骗了装配。

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

this will make your program return 42. 这将使你的程序返回42。

A Whirlwind Tutorial on Creating Really Teensy ELF Executables for Linux is an interesting article that goes through a step-by-step process to create an ELF executable as small as possible. 关于为Linux创建真正的Teensy ELF可执行文件的旋风教程是一篇有趣的文章,它通过逐步创建尽可能小的ELF可执行文件的过程。

I don't want to spoil the ending, but the author gets it down to a lot smaller than 4K ;) 我不想破坏结局,但笔者得到它下降到了不少小于4K;)

Take a look at this article in KSplice blog from a while back. 不久前回顾一下KSplice博客中的这篇文章。 It talks about linking without the standard libraries. 它讨论了没有标准库的链接。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM