What Do 'Statically Linked' and 'Dynamically Linked' Mean

What do 'statically linked' and 'dynamically linked' mean?

There are (in most cases, discounting interpreted code) two stages in getting from source code (what you write) to executable code (what you run).

The first is compilation which turns source code into object modules.

The second, linking, is what combines object modules together to form an executable.

The distinction is made for, among other things, allowing third party libraries to be included in your executable without you seeing their source code (such as libraries for database access, network communications and graphical user interfaces), or for compiling code in different languages (C and assembly code for example) and then linking them all together.

When you statically link a file into an executable, the contents of that file are included at link time. In other words, the contents of the file are physically inserted into the executable that you will run.

When you link dynamically, a pointer to the file being linked in (the file name of the file, for example) is included in the executable and the contents of said file are not included at link time. It's only when you later run the executable that these dynamically linked files are bought in and they're only bought into the in-memory copy of the executable, not the one on disk.

It's basically a method of deferred linking. There's an even more deferred method (called late binding on some systems) that won't bring in the dynamically linked file until you actually try to call a function within it.

Statically-linked files are 'locked' to the executable at link time so they never change. A dynamically linked file referenced by an executable can change just by replacing the file on the disk.

This allows updates to functionality without having to re-link the code; the loader re-links every time you run it.

This is both good and bad - on one hand, it allows easier updates and bug fixes, on the other it can lead to programs ceasing to work if the updates are incompatible - this is sometimes responsible for the dreaded "DLL hell" that some people mention in that applications can be broken if you replace a dynamically linked library with one that's not compatible (developers who do this should expect to be hunted down and punished severely, by the way).


As an example, let's look at the case of a user compiling their main.c file for static and dynamic linking.

Phase     Static                    Dynamic
-------- ---------------------- ------------------------
+---------+ +---------+
| main.c | | main.c |
+---------+ +---------+
Compile........|.........................|...................
+---------+ +---------+ +---------+ +--------+
| main.o | | crtlib | | main.o | | crtimp |
+---------+ +---------+ +---------+ +--------+
Link...........|..........|..............|...........|.......
| | +-----------+
| | |
+---------+ | +---------+ +--------+
| main |-----+ | main | | crtdll |
+---------+ +---------+ +--------+
Load/Run.......|.........................|..........|........
+---------+ +---------+ |
| main in | | main in |-----+
| memory | | memory |
+---------+ +---------+

You can see in the static case that the main program and C runtime library are linked together at link time (by the developers). Since the user typically cannot re-link the executable, they're stuck with the behaviour of the library.

In the dynamic case, the main program is linked with the C runtime import library (something which declares what's in the dynamic library but doesn't actually define it). This allows the linker to link even though the actual code is missing.

Then, at runtime, the operating system loader does a late linking of the main program with the C runtime DLL (dynamic link library or shared library or other nomenclature).

The owner of the C runtime can drop in a new DLL at any time to provide updates or bug fixes. As stated earlier, this has both advantages and disadvantages.

Difference between static linking and dynamic linking

Static linking is done at 'compile time' by a tool called a linker. Dynamic linking is done at run time, by the operating system.

Difference between static linking and dynamic linking

Static linking is done at 'compile time' by a tool called a linker. Dynamic linking is done at run time, by the operating system.

Static linking vs dynamic linking

  • Dynamic linking can reduce total resource consumption (if more than one process shares the same library (including the version in "the same", of course)). I believe this is the argument that drives its presence in most environments. Here "resources" include disk space, RAM, and cache space. Of course, if your dynamic linker is insufficiently flexible there is a risk of DLL hell.
  • Dynamic linking means that bug fixes and upgrades to libraries propagate to improve your product without requiring you to ship anything.
  • Plugins always call for dynamic linking.
  • Static linking, means that you can know the code will run in very limited environments (early in the boot process, or in rescue mode).
  • Static linking can make binaries easier to distribute to diverse user environments (at the cost of sending a larger and more resource-hungry program).
  • Static linking may allow slightly faster startup times, but this depends to some degree on both the size and complexity of your program and on the details of the OS's loading strategy.

Some edits to include the very relevant suggestions in the comments and in other answers. I'd like to note that the way you break on this depends a lot on what environment you plan to run in. Minimal embedded systems may not have enough resources to support dynamic linking. Slightly larger small systems may well support dynamic linking because their memory is small enough to make the RAM savings from dynamic linking very attractive. Full-blown consumer PCs have, as Mark notes, enormous resources, and you can probably let the convenience issues drive your thinking on this matter.


To address the performance and efficiency issues: it depends.

Classically, dynamic libraries require some kind of glue layer which often means double dispatch or an extra layer of indirection in function addressing and can cost a little speed (but is the function calling time actually a big part of your running time???).

However, if you are running multiple processes which all call the same library a lot, you can end up saving cache lines (and thus winning on running performance) when using dynamic linking relative to using static linking. (Unless modern OS's are smart enough to notice identical segments in statically linked binaries. Seems hard, does anyone know?)

Another issue: loading time. You pay loading costs at some point. When you pay this cost depends on how the OS works as well as what linking you use. Maybe you'd rather put off paying it until you know you need it.

Note that static-vs-dynamic linking is traditionally not an optimization issue, because they both involve separate compilation down to object files. However, this is not required: a compiler can in principle, "compile" "static libraries" to a digested AST form initially, and "link" them by adding those ASTs to the ones generated for the main code, thus empowering global optimization. None of the systems I use do this, so I can't comment on how well it works.

The way to answer performance questions is always by testing (and use a test environment as much like the deployment environment as possible).

What does it mean for statically linking and dynamically linking in Python?

In python there's no static linking. All the imports requires the correct dependencies to be installed on our target machine. The choice of the version of such libraries are in our decision.

Now let's come to the binary builders for python. In this case, we'll have to determine the linking type based on the GNU definitions. If the user can replace the dependency as he likes, it's dynamic. If the dependency is attached together with the binary itself, it's static linking. In case of cx_freeze or pyinstaller, if we build this as one file, it's static linking. If we build this in normal mode where all the dependencies are collected as separate files, it's dynamic linking. Idea is, whether we can replace the dependency in target machine or not.

What is static library and what is dynamic library, what is the difference and what is better to use and why?

A static library is meant to be combined with your code into a single executable file by a linker.

A dynamic library is meant to be loaded by the operating system after the main executable has been loaded, and the linking of the symbol addresses will be done by the OS at that time. This may be done automatically based on dependency information in the executable, or it may be done explicitly by the program. This is called "dynamic linking" because the library may change at any point before the OS has loaded it.

Regarding Static and Shared Libraries Linking in C

The linker takes whatever it finds. This is usually the shared library.

On a Linux system, you can use

file hello

to find out, whether it is linked statically or dynamically.

E.g.

file /bin/bash

gives

/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x6dafe33f9353cbb054b1b1f7b079545992575757, stripped

whereas

file /bin/busybox

gives

/bin/busybox: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=0xac4943b7daf7c3c204a2866ea5398f2337ff93c9, stripped

You can force a static link, by adding the -static option to gcc

gcc -static -o hello hello.c

file hello

/tmp/hello: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.24, BuildID[sha1]=0x790ec9b287fd2a276162560e5e6669ba6b73e68f, not stripped

Update:

Linking is the process of putting object files, dynamic and static libraries and some boilerplate objects together, to form a binary executable file.

You can use both dynamic and static libraries in one executable. The needed object files of a static library are copied into the executable. On the other side, dynamic libraries (dynamic objects actually) are not copied, but rather referenced by the resulting binary.

Update:

There are two kinds of libraries, static libraries (ar archives, see man ar)

file /usr/lib/libnet.a

/usr/lib/libnet.a: current ar archive

and dynamic libraries (dynamic objects)

file /usr/lib/libnet.so.1.5.0 

/usr/lib/libnet.so.1.5.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0x0c596357947e79001025b3c57be933690085dffb, stripped

You can have both types of library installed at the same time, e.g.

ls -l /usr/lib/libnet.*

-rw-r--r-- 1 root root 207780 Okt 28 2011 /usr/lib/libnet.a
-rw-r--r-- 1 root root 802 Okt 28 2011 /usr/lib/libnet.la
lrwxrwxrwx 1 root root 15 Okt 28 2011 /usr/lib/libnet.so -> libnet.so.1.5.0
lrwxrwxrwx 1 root root 15 Okt 28 2011 /usr/lib/libnet.so.1 -> libnet.so.1.5.0
-rw-r--r-- 1 root root 92712 Okt 28 2011 /usr/lib/libnet.so.1.5.0

An ar archive contains one or more object files, which are selected by the linker if needed by the executable file. A shared object is an object with subroutines, which allows to be called by other shared objects or executables at runtime.

If you're interested in this subject, you can also look at this Wikipedia - Library (computing) article.



Related Topics



Leave a reply



Submit