I'm trying to create a minimal sized executable for a demoscene contest. I'm trying to minimize the size of the executable by linking it myself.
Here is my minimal main.c, taken from http://www.int21.de/linux4k/ It draws a white triangle on the screen:
#include "SDL/SDL.h"
#include "GL/gl.h"
void _start(){
SDL_Event event;
SDL_SetVideoMode(640,480,0,SDL_OPENGL|SDL_FULLSCREEN);
SDL_ShowCursor(SDL_DISABLE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.33,1.33,-1,1,1.5,100);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glVertex3i(1,1,-10);
glVertex3i(1,-1,-10);
glVertex3i(-1,1,-10);
glEnd();
SDL_GL_SwapBuffers();
do{
SDL_PollEvent(&event);
} while (event.type!=SDL_KEYDOWN);
SDL_Quit();
}
I am using void _start() instead of int main(), because I don't want to use the C runtime. Here are my build commands (my machine is running Ubuntu Linux):
gcc -c main.c
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -lSDL -lGL main.o -o main
The program crashes on SDL_SetVideoMode. gdb reports:
Program received signal SIGSEGV, Segmentation fault.
_dl_map_object_from_fd (name=0x7ffff77dfcec "libXrender.so.1", fd=-1, fbp=0x7fffffffd908,
realname=0x601de0 "/usr/lib/x86_64-linux-gnu/libXrender.so.1", loader=<optimized out>, l_type=<optimized out>,
mode=-1879048190, stack_endp=0x7fffffffdc68, nsid=0) at dl-load.c:1574
What is wrong? If I change void _start() to int main(), and compile the whole thing with gcc main.c -o main -lSDL -lGL, it works just fine. This working version and the self-linked broken version have exactly the same list of linked libraries when I inspect the executables with ldd.
TL;DR: Patient: "Doctor, it hurts when I do ${THAT}" – Doctor: "Then don't do ${THAT}".
If you don't want to have the C runtime in there you must make sure that you don't use any code that relies on the C runtime being available and more importantly being initialized. SDL strongly depends on the facilities of libc (which is why you probably added that
-lcso that SDL can be properly linked), so when you link it, you need all that libc stuff. However for libc to properly work it must be initialized, which is what_start()does.If you want to get your executable size down, which yes also involved getting rid of the (bloated GNU) libc, you'll have to do a lot of things yourself and/or patch libraries you use not to rely on the things you want to remove.