In a typical system, a number of programs are running. Each program relies on a number of functions, some of which are standard C library functions, like printf(), malloc(), write(), and so on. If every program uses the standard C library, it follows that each program would normally have a unique copy of this particular library present within it. Unfortunately, this results in wasted resources. Since the C library is common, it makes more sense to have each program reference the common instance of that library, instead of having each program contain a copy of the library. This approach yields several advantages, not the least of which is the savings in terms of total system memory required.
In a typical system, a number of programs are running. Each program relies on a number of functions, some of which are standard C library functions, like printf(), malloc(), write(), and so on. This means that the binding between the program and the particular library is fixed and known at linktime—well in advance of the program's ever running. It also means that we can't change this binding, unless we relink the program with a new version of the library.
You might consider linking a program statically in cases where you weren't sure whether the correct version of a library is available at runtime, or if you were testing a new version of a library that you don't yet want to install as shared.
Programs that are linked statically are linked against archives of objects (libraries) that typically have the extension of .a. An example of such a collection of objects is the standard C library, libc.a.
The term dynamically linked means that the program and the particular library it references aren't combined together by the linker at linktime. Instead, the linker places information into the executable that tells the loader which shared object module the code is in and which runtime linker should be used to find and bind the references. This means that the binding between the program and the shared object is done at runtime—before the program starts, the appropriate shared objects are found and bound.
This type of program is called a partially bound executable, because it isn't fully resolved—the linker, at linktime, didn't cause all the referenced symbols in the program to be associated with specific code from the library. Instead, the linker simply said: This program calls some functions within a particular shared object, so I'll just make a note of which shared object these functions are in, and continue on. Effectively, this defers the binding until runtime.
Programs that are linked dynamically are linked against shared objects that have the extension .so. An example of such an object is the shared object version of the standard C library, libc.so.
You use a command-line option to the compiler driver qcc to tell the tool chain whether you're linking statically or dynamically. This command-line option then determines the extension used (either .a or .so).
Augmenting code at runtime
Taking this one step further, a program may not know which functions it needs to call until it's running. While this may seem a little strange initially (after all, how could a program not know what functions it's going to call?), it really can be a very powerful feature. Here's why. Consider a generic disk driver. It starts, probes the hardware, and detects a hard disk. The driver would then dynamically load the io-blk code to handle the disk blocks, because it found a block-oriented device. Now that the driver has access to the disk at the block level, it finds two partitions present on the disk: a DOS partition and a Power-Safe partition. Rather than force the disk driver to contain file system drivers for all possible partition types it may encounter, we kept it simple: it doesn't have any file system drivers! At runtime, it detects the two partitions and then knows that it should load the fs-dos.so and fs-qnx6.so file system code to handle those partitions.
By deferring the decision of which functions to call, we've enhanced the flexibility of the disk driver (and also reduced its size).
Last modified: 2015-03-31