4

It seems even a hello world program depends on several libraries:

libc.so.6 => /lib64/libc.so.6 (0x00000034f4000000)
/lib64/ld-linux-x86-64.so.2 (0x00000034f3c00000)

How can I static link all stuff ?

hmakholm left over Monica
  • 23,074
  • 3
  • 51
  • 73
lexer
  • 1,027
  • 3
  • 14
  • 18
  • 1
    Why does it matter to you? Any Linux system anywhere will have a working C library and dynamic linker. They're part of the ABI. – hmakholm left over Monica Aug 15 '11 at 12:36
  • 3
    @Henning Makholm, where "linux ABI" is described? I mean the ABI, which says that `libc.so.6` and `ld-linux-x86-64.so.2` are part of it. Did you ever see embedded linux without rootfs? – osgx Aug 15 '11 at 14:30
  • @osgx: It's mostly informal (an informal ABI is still an ABI, it's just more difficult to be sure what it is), but I think it's written down in FHS somewhere. – hmakholm left over Monica Aug 15 '11 at 14:41

2 Answers2

8

Link with -static. "On systems that support dynamic linking, this prevents linking with the shared libraries."

Edit: Yes this will increase the size of your executable. You can go two routes, either do what Marco van de Voort recommends (-nostdlib, bake your own standard library or find a minimal one).

Another route is to try and get GCC to remove as much as it can.

gcc  -Wl,--gc-sections -Os -fdata-sections -ffunction-sections -ffunction-sections -static test.c -o test
strip test

Reduces a small test from ~800K to ~700K on my machine, so the reduction isn't really that big.

Previous SO discussions:
Garbage from other linking units
How do I include only used symbols when statically linking with gcc?
Using GCC to find unreachable functions ("dead code")

Update2: If you are content with using just system calls, you can use gcc -ffreestanding -nostartfiles -static to get really small executable files.

Try this file (small.c):

#include <unistd.h>

void _start() {
    char msg[] = "Hello!\n";
    write(1, msg, sizeof(msg));
    _exit(0);
}

Compile using: gcc -ffreestanding -nostartfiles -static -o small small.c && strip small. This produces a ~5K executable on my system (which still has a few sections that ought to be stripable). If you want to go further look at this guide.

Community
  • 1
  • 1
user786653
  • 29,780
  • 4
  • 43
  • 53
  • The size is so large because instead of simply including mere references to the functions and code from the shared libraries, the statically linked program actually includes copies of the libraries and their code. – James O'Doherty Aug 15 '11 at 12:43
  • @James O'Doherty ,how do I instruct the compiler to only include neccesary symbols? – lexer Aug 15 '11 at 12:47
  • The --gc-sections and other section commands in the answer should do that. – Marco van de Voort Aug 15 '11 at 13:27
  • 1
    @lexer(1), try reading [http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html](http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html) (and probably other stuff in [http://www.muppetlabs.com/~breadbox/software/tiny/](http://www.muppetlabs.com/~breadbox/software/tiny/)). – David X Aug 15 '11 at 14:14
1

Or use -nostdlib and implement your own libraries and startup code.

The various "assembler on *nix" sites can give you an idea how to do it.

If you just want your binary to be small, start by using 32-bit.

Marco van de Voort
  • 25,628
  • 5
  • 56
  • 89