4 ms·
Well, I mean on my Arch Linux system libc is ~2M, so that's not exactly trivial either. The only reason hello world can be so small is that all the stdlib code
by lomnakkus 9y ago
Well, I mean on my Arch Linux system libc is ~2M, so that's not exactly trivial either. The only reason hello world can be so small is that all the stdlib code already exists on your system -- not so for Java[1].
Of course there are far smaller libc implementations, but they may be missing functionality.
[1] Unless, of course you require an installation of Java... which would kind of go against the premise of this whole exercise.
- blueline 9y agounless you're statically linking the entire standard library, libc being 2M is irrelevant, no? you only pay for what you use if you dynamically link it.
- fgonzag 9y agoso if the jvm is installed in your system, 11M out of the 11M in the example (since it includes the cut down jvm) is irrelevant? Then all you need for the example is a 1k .class file.
- mitchty 9y agoErr, glibc is its own level of derp. Here, a fully static binary on linux with musl libc, designed for static linking unlike glibc. Note, this on 32 bit arm, size might differ on different arches, all I have access to off the cuff: # printf '#include <stdio.h>\n int main(int argc, char**argv) { puts("hi"); }' > /tmp/hi.c # make /tmp/hi cc -c -o /tmp/hi.o /tmp/hi.c cc /tmp/hi.o -o /tmp/hi # du -hs /tmp/hi 12.0K /tmp/hi # ldd /tmp/hi /lib/ld-musl-armhf.so.1 (0x7f5af000) libc.musl-armhf.so.1 => /lib/ld-musl-armhf.so.1 (0x7f5af000) # strip /tmp/hi # du -hs /tmp/hi 8.0K /tmp/hi # rm /tmp/hi # make LDFLAGS=-static /tmp/hi cc -static /tmp/hi.o -o /tmp/hi # du -hs /tmp/hi 92.0K /tmp/hi # ldd /tmp/hi ldd (0x7f5e3000) # file /tmp/hi /tmp/hi: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, with debug_info, not stripped ungh, go home ldd and file, you're both drunk and dead to me right now: # objdump -p /tmp/hi /tmp/hi: file format elf32-littlearm Program Header: LOAD off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**16 filesz 0x00001f68 memsz 0x00001f68 flags r-x LOAD off 0x00002ea4 vaddr 0x00012ea4 paddr 0x00012ea4 align 2**16 filesz 0x00000204 memsz 0x00000798 flags rw- DYNAMIC off 0x00002eb4 vaddr 0x00012eb4 paddr 0x00012eb4 align 2**2 filesz 0x000000e0 memsz 0x000000e0 flags rw- STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**4 filesz 0x00000000 memsz 0x00000000 flags rw- RELRO off 0x00002ea4 vaddr 0x00012ea4 paddr 0x00012ea4 align 2**0 filesz 0x0000015c memsz 0x0000015c flags r-- Dynamic Section: SYMBOLIC 0x00000000 INIT 0x00000468 FINI 0x00001f38 INIT_ARRAY 0x00012ea4 INIT_ARRAYSZ 0x00000004 FINI_ARRAY 0x00012ea8 FINI_ARRAYSZ 0x00000004 GNU_HASH 0x000000d4 STRTAB 0x00000250 SYMTAB 0x00000120 STRSZ 0x000000ee SYMENT 0x00000010 DEBUG 0x00000000 PLTGOT 0x00012f94 PLTRELSZ 0x00000018 PLTREL 0x00000011 JMPREL 0x00000450 REL 0x00000340 RELSZ 0x00000110 RELENT 0x00000008 BIND_NOW 0x00000000 FLAGS_1 0x08000001 RELCOUNT 0x0000001c private flags = 5000400: [Version5 EABI] [hard-float ABI] Note no NEEDED section, so we're indeed fully static. # strip /tmp/hi # du -hs /tmp/hi 16.0K /tmp/hi 16K for a fully static hello world sounds pretty decent to me vs 8k for dynamic. Will be faster than involving ld.so as well. I could probably improve that further, but I'm not about to golf this tonight.
- blueline 9y ago>will be faster than involving ld.so as well isn't this only true for the first time a function is used? once all of the linking is done, the GOT will just contain the address of the function and it's just as if it were linked statically, right?
- mitchty 9y ago> isn't this only true for the first time a function is used? Yes, but it will happen each time the program loads, which means your LD_* variables will get parsed/iterated over. Statically linking stuff in can help if you have a program that needs to be exec()'d in a loop. While it'll probably only shave off 0.001 seconds per exec() call it can add up, more so if you have LD_LIBRARY_PATH set to look on some slow storage like nfs. But its a bit of a hyper optimization at that point. I've used this to really annoy a c++ developer saying c++ was faster than c. Evil trick on my part but my euler solutions were always faster. >.<
- state_less 9y agoSide Note: Nice to see you here. Thanks for your Alpine GHC package :) My Scotty+Haskell+Alpine service is the lightest container in the fleet. It's only using 1.3 MiB of RAM!
- mitchty 9y agoYou're welcome! I made it more because I wanted a static pandoc binary. The rest came along for the ride, glad to hear its of use! That said I really need to get back to debugging the segfault in building ghc 8.2.2 on armhf in the ghc rts. But its gotten me going through everything but ghc and whatnot. Annoying when things worked before and don't now. Even weirder that only the final stage build is at issue, the other two are fine.
- lomnakkus 9y agoOf course, and given the "crowd" I should probably have added a caveat about glibc[1], but using a non-glibc is pretty non-trivial for many developers (and thus, eventually, distros). Even if you don't buy that reasoning, it's just not very common to use non-glibc on most common distros. ... and honestly, I should probably just have been more explicit about the absurdity of comparing "hello world". That would sort of agree with the OP's post, but not for the same reason. I think reasons are important. [1] ... but then you end up with discussions about the importance of locales, nsswitch, etc. etc. Even though I didn't bring it up, it necessitated this footnote. You see what I mean?