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

http://stackoverflow.com/questions/311882/what-do-statically-linked-and-dynamically-linked-mean

I often hear the terms 'statically linked' and 'dynamically linked', often in reference to code written in C(++|#) but I don't know much of anything about either, what are they, what exactly are they talking about, and what are they linking?

link | improve this question

 
 
feedback

up vote 76 down vote accepted

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.

link | improve this answer
 
2 
Please correct me if I'm wrong, but on Windows, software tends to include its own libraries with the install, even if they're dynamically linked. On many Linux systems with a package manager, many dynamically linked libraries ("shared objects") are actually shared between software. –  Paul Fisher Nov 23 '08 at 4:57
 
Nice answer, just what I was looking for. –  UnkwnTech Nov 23 '08 at 5:42
1 
@PaulF: things like the Windows common controls, DirectX, .NET and so on ship a lot with the applications whereas on Linux, you tend to use apt or yum or something like that to manage dependencies - so you're right in that sense. Win Apps that ship their own code as DLLs tend not to share them. –  paxdiablo Nov 23 '08 at 6:57
 
+1 for sheer excellence. –  jprete Nov 26 '09 at 2:36
4 
There's a special place reserved in the ninth circle of hell for those that update their DLLs and break backward compatibility. Yes, if interfaces disappear or are modified, then the dynamic linking will fall in a heap. That's why it shouldn't be done. By all means add a function2() to your DLL but don't change function() if people are using it. Best way to handle that is to recode function() in such a way the it calls function2(), but don't change the signature of function(). –  paxdiablo May 12 '10 at 8:26
show 3 more comments
feedback

I think a good answen to this question ought to explain what linking is.

When you compile some C code (for instance), it is translated to machine language. Just a sequence of bytes which when run causes the processor to add, subtract, compare, "goto", read memory, write memory, that sort of thing. This stuff is stored in object (.o) files.

Now, a long time ago, computer scientists invented this "subroutine" thing. Execute-this-chunk-of-code-and-return-here. It wasn't too long before they realised that the most useful subroutines could be stored in a special place and used by any program that needed them.

Now in the early days programmers would have to punch in the memory address that these subroutines were located at. Something like CALL 0x5A62. This was tedious and problematic should those memory addresses ever need to be changed.

So, the process was automated. You write a program that calls printf(), and the compiler doesn't know the memory address of printf. So the compiler just writes CALL 0x0000, and adds a note to the object file saying "must replace this 0x0000 with the memory location of printf".

Static linkage means that the linker program (the GNU one is called ld) adds printf's machine code directly to your executable file, and changes the 0x0000 to the address of printf. This happens when your executable is created.

Dynamic linkage means that the above step doesn't happen. The executable file still has a note that says "must replace 0x000 with the memory location of printf". The operating system's loader needs to find the printf code, load it into memory, and correct the CALL address, each time the program is run.

It's common for programs to call some functions which will be statically linked (standard library functions like printf are usually statically linked) and other functions which are dynamically linked. The static ones "become part" of the executable and the dynamic ones "join in" when the executable is run.

There are advantages and disadvantages to both methods, and there are differences between operating systems. But since you didn't ask, I'll end this here.

link | improve this answer
 
I liked the explanation of linking –  Nathan Fellman Nov 23 '08 at 5:00
 
I did too, however I only get to choose 1 answer. –  UnkwnTech Nov 23 '08 at 11:36
5 
I would have chosen the other one too :P but thanks –  Artelius Nov 23 '08 at 21:54
1 
incredible answer, Artelius. :) –  mahesh Dec 17 '08 at 14:28
 
Artelius, i am looking some in depth about your explanation about how these crazy low level things works. please reply with what books we must read to get indepth knowledge about the above things. thank you. –  mahesh Dec 17 '08 at 14:38
show 2 more comments
feedback

Statically linked libraries are linked in at compile time. Dynamically linked libraries are loaded at run time. Static linking bakes the library bit into your executable. Dynamic linking only bakes in a reference to the library; the bits for the dynamic library exist elsewhere and could be swapped out later.

link | improve this answer
 
 
feedback

up vote 0 down vote

(I don't know C# but it is interesting to have a static linking concept for a VM language)

Dynamic linking involves knowing how to find a required functionality which you only have a reference from your program. You language runtime or OS search for a piece of code on the filesystem, network or compiled code cache, matching the reference, and then takes several measures to integrate it to your program image in the memory, like relocation. They are all done at runtime. It can be done either manually or by the compiler. There is ability to update with a risk of messing up (namely, DLL hell).

Static linking is done at compile time that, you tell the compiler where all the functional parts are and instruct it to integrate them. There are no searching, no ambiguity, no ability to update without a recompile. All your dependencies are physically one with your program image.

link|improve this answer

==============

5.2. Why do we use static linking?

(Thanks to Plasmatic for posting the text on which this is mainly based to one of the LFS mailing lists.)

When making (compiling) a program, rather than having to rewrite all the functions for dealing with the kernel, hardware, files, etc. every time you write a new program, all these basic functions are instead kept in libraries. glibc, which you install later, is one of these major libraries, which contains code for all the basic functions programs use, like opening files, printing information on the screen, and getting feedback from the user. When the program is compiled, these libraries of code are linked together with the new program, so that it can use any of the functions that the library has.

However, these libraries can be very large (for example, libc.a can often be around 2.5 MB), so you may not want a separate copy of each library attached to the program. Just imagine if you had a simple command like ls with an extra 2.5 MB attached to it! Instead of making the library an actual part of the program, or statically linked, the library is stored as a separate file, which is loaded only when the program needs it. This is what we call dynamically linked, as the library is loaded and unloaded dynamically, as the program needs it.

So now we have a 1 KB file and a 2.5 MB file, but we still haven't saved any space (except maybe RAM until the library is needed). The real advantage of dynamically linked libraries is that we only need one copy of the library. If ls and rm both use the same library, then we don't need two copies of the library, as they can both get the code from the same file. Even when in memory, the two programs share the same code, rather than loading duplicates into memory. So not only are we saving hard disk space, but also precious RAM.

If dynamic linking saves so much room, then why are we making everything statically linked? Well, that's because when you chroot into your brand new (but very incomplete) LFS environment, these dynamic libraries won't be available because they are somewhere else in your old directory tree (/usr/lib for example) which won't be accessible from within your LFS root ($LFS).

So in order for your new programs to run inside the chroot environment you need to make sure that the libraries are statically linked when you build them, hence the --enable-static-link, --disable-shared, and -static flags used through Chapter 5. Once in Chapter 6, the first thing we do is build the main set of system libraries, glibc. Once this is made we start rebuilding all the programs we just did in Chapter 5, but this time dynamically linked, so that we can take advantage of the space saving opportunities.

And there you have it, that's why you need to use those weird -static flags. If you try building everything without them, you'll see very quickly what happens when you chroot into your newly crippled LFS system.

If you want to know more about Dynamically Linked Libraries, consult a book or website on programming, especially a Linux-related site.

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值