There are still too many people out there who think (or even
insist) that static linking has benefits. This has never been the
case and never will be the case. Here are a few reasons why
dynamic linking is superior:
fixes (either security or only bug) have to be applied to
only one place: the new DSO(s). If various applications are
linked statically, all of them would have to be relinked. By the
time the problem is discovered the sysadmin usually forgot which
apps are built with the problematic library. I
consider this alone (together with the next one) to be the
Security measures like load address randomization cannot
be used. With statically linked applications, only the stack and
heap address can be randomized. All text has a fixed address in
all invocations. With dynamically linked applications, the kernel
has the ability to load all DSOs at arbitrary addresses, independent
from each other. In case the application is built as a position
independent executable (PIE) even this code can be loaded at
random addresses. Fixed addresses (or even only fixed offsets)
are the dreams of attackers. And no, it is not possible in
general to generate PIEs with static linking. On IA-32 it is
possible to use code compiled without -fpic and
-fpie in PIEs (although with a cost) but this is not true
for other architectures, including x86-64.
more efficient use of physical memory. All processes
share the same physical pages for the code in the DSOs. With
prelinking startup times for dynamically linked code is as good
as that of statically linked code.
all kinds of features in the libc (locale (through
iconv), NSS, IDN, …) require dynamic linking to load the
appropriate external code. We have very limited support for
doing this in statically linked code. But it requires that the
dynamically loaded modules available at runtime must come from
the same glibc version as the code linked into the application.
And it is completely unsupported to dynamically load DSOs this
way which are not part of glibc. Shipping all the dependencies
goes completely against the
advantageof static linking
people site: that shipping one binary is enough to make it work
Related, trivial NSS modules can be used from statically
linked apps directly. If they require extensive dependencies
(like the LDAP NSS module, not part of glibc proper) this will
likely not work. And since the selection of the NSS modules is
up the the person deploying the code (not the developer), it is
not possible to make the assumption that these kind of modules
are not used.
no accidental violation of the (L)GPL. Should a program
which is statically linked be given to a third party, it is
necessary to provide the possibility to regenerate the program
tools and hacks like ltrace, LD_PRELOAD, LD_PROFILE,
LD_AUDIT don’t work. These can be effective debugging and
profiling, especially for remote debugging where the user cannot
be trusted with doing complex debugging work.
There are certainly more reasons. The often used argument
about statically linked apps being more portable (i.e., can be
copied to other systems and simply used since there are no
dependencies) is not true since every non-trivial program needs
dynamic linking at least for one of the reasons mentioned above.
And dynamic linking kills the portability of statically linked
Conclusion: Never use static linking!
There is one aspect where people decide to misinterpret these
recommendations. I do not say that everything should be
stuffed into its own DSO. I would never say this. To the contrary.
belongs together because of the development
process should be kept in the same object. The reason is that the
fewer DSOs are needed the faster everything works (loading, symbol
One example where this still isn’t done right is
OpenOffice.org. If you look at the dependencies of the binaries
(swriter.bin etc) you’ll see lots of files from the OO.org
project. Almost all of them are used in all the OO.org programs
and none is used outside the project. Especially there is
libsoffice.so which itself pulls in a huge number of
DSOs. This is done in all OO.org programs!
During deployment there is no reason to do this. All
the DSOs pulled in by libsoffice.so and probably some of
the others used in the various programs should all be part of one
mega-DSO. Yes, this DSO would be big, but it would be smaller
than sum of all the loaded dependencies. And more: the export
lists can be further restricted making a lot of calls inside the
new DSO much faster.
There is a good reason to have all the separate DSOs during
development. This makes it possible to rebuild only a small part
of the source tree to test out some changes. But this is
development. When the binaries are shipped to users (e.g., as
part of a distribution) this need falls away and so does the
So, combine all the sources from the same project which are
used or at least loaded in all or most situations in one single
DSO. It will be smaller and faster. Just don’t get overzealous
and add 3rd party code as well. E.g., even if you ship
a copy of, say, libxml don’t add it to your DSO. Only
the code which is written as part of the project.