Originally posted by Luke_Wolf
View Post
I think you may also want to static link to save resources, when compared to dynamically linking bundled libraries (aka, your not going to be linking to system libs, or system install of Qt even if you are going dynamic).
I've quoted some noteworthy slides from this link:
Slides 6-24 are the ones that concern static linking.
Different kinds of static linking
Smart static linking
Linker links/extracts only those object files (from an archive) that expose required symbols
This has implications on the size of a static executable
This is the usual case nowadays
Dumb static linking
Linker links full blown archives
Very unusual nowadays, was usual back in the 60s when people kept things in simple and clean states due to hardware limitations
Smart static linking
Linker links/extracts only those object files (from an archive) that expose required symbols
This has implications on the size of a static executable
This is the usual case nowadays
Dumb static linking
Linker links full blown archives
Very unusual nowadays, was usual back in the 60s when people kept things in simple and clean states due to hardware limitations
Joe sez static executables are huge!
Why are static executables huge?
Library bloat! glibc is a disaster - simple hello world results in 600kb overhead for no reason
Use less bloated libraries, start here:
uClibc
dietlibc
bionic
even BSD libc is a lot better than glibc
(Not mentioned in the actual slide but I'll add this: http://www.musl-libc.org/)
Why are static executables huge?
Library bloat! glibc is a disaster - simple hello world results in 600kb overhead for no reason
Use less bloated libraries, start here:
uClibc
dietlibc
bionic
even BSD libc is a lot better than glibc
(Not mentioned in the actual slide but I'll add this: http://www.musl-libc.org/)
Joe sez static executables consume more memory!
$ file grep
grep: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
$ du -h grep
68K grep
$ file /bin/grep
/bin/grep: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
$ du -h /bin/grep
84K /bin/grep
$ ldd /bin/grep
linux-gate.so.1 => (0xb7850000)
libpcre.so.0 => /lib/libpcre.so.0 (0xb780c000)
libc.so.6 => /lib/libc.so.6 (0xb76c5000)
/lib/ld-linux.so.2 (0xb7851000)
$ du -h /lib/libpcre.so.0.0.1
216K /lib/libpcre.so.0.0.1
$ du -h /lib/libc-2.11.1.so
1.5M /lib/libc-2.11.1.so
$ file grep
grep: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped
$ du -h grep
68K grep
$ file /bin/grep
/bin/grep: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
$ du -h /bin/grep
84K /bin/grep
$ ldd /bin/grep
linux-gate.so.1 => (0xb7850000)
libpcre.so.0 => /lib/libpcre.so.0 (0xb780c000)
libc.so.6 => /lib/libc.so.6 (0xb76c5000)
/lib/ld-linux.so.2 (0xb7851000)
$ du -h /lib/libpcre.so.0.0.1
216K /lib/libpcre.so.0.0.1
$ du -h /lib/libc-2.11.1.so
1.5M /lib/libc-2.11.1.so
Joe sez static executables consume more memory!
Ok so 68K vs 84K+216K+1.5M = 1836K
Running multiple static greps still only consumes 68K, since the executable itself isn't loaded into memory twice
Does this scale? Yes, for most parts it scales very well
So is Joe wrong? Yes
Even if he'd use a browser, compile time smart linking is still better than polluting the memory with dynamic libraries
Hold on, isn't there paging? Isn't there... sorry, won't go there!
Ok so 68K vs 84K+216K+1.5M = 1836K
Running multiple static greps still only consumes 68K, since the executable itself isn't loaded into memory twice
Does this scale? Yes, for most parts it scales very well
So is Joe wrong? Yes
Even if he'd use a browser, compile time smart linking is still better than polluting the memory with dynamic libraries
Hold on, isn't there paging? Isn't there... sorry, won't go there!
Joe sez static executables start slower (huge, eh!)!
He is completely wrong.
Let's do some minimalist example, dynamic hello world vs static hello world, harness fork()/execvp()'s it 10000 times:
$ LD_LIBRARY_PATH=. ./harness ./run_dynamic
execution time: 1975592 microseconds
$ ./harness ./run_static
execution time: 732704 microseconds
So starting up performance of this static executable is 63% faster than it's dynamic counterpart
Does it scale? Yes
He is completely wrong.
Let's do some minimalist example, dynamic hello world vs static hello world, harness fork()/execvp()'s it 10000 times:
$ LD_LIBRARY_PATH=. ./harness ./run_dynamic
execution time: 1975592 microseconds
$ ./harness ./run_static
execution time: 732704 microseconds
So starting up performance of this static executable is 63% faster than it's dynamic counterpart
Does it scale? Yes
That doesn't change the fact that if you want the same compiled binary to run across multiple linux systems and be deployed easily, static linking will probably be more resource efficient then bundling a bunch of dynamic libraries into a directory and putting that dir into a .tar or using a .bin installer for distribution. Of course to get the protability advantage you need to static link everything, even the libc, however using a lighter library like musl or uclibc (uclibc is supposed to be glibc source compatible afaik, but is LGPL) removes a lot of overhead as they say.
Although this is a use case for static linking, this still doesn't deal with brosis's complaint, as all this can be done without violationg LGPL. Either give object files, or also make a dynamic version available so you can supply the dynamic version to anyone wishing to relink, giving you lgpl compliance. DRM was the only use case against this, but like you said just static link your DRM libs and do whatever you want with Qt.
Leave a comment: