Static Dynamic Link
Static Dynamic Link
Static Dynamic Link
Static linking is the process of copying all In dynamic linking the names of the
library modules used in the program into external libraries (shared libraries) are
the final executable image. This is placed in the final executable file while
performed by the linker and it is done as the actual linking takes place at run time
the last step of the compilation process. when both executable file and libraries
The linker combines library routines with are placed in the memory. Dynamic
the program code in order to resolve linking lets several programs use a single
external references, and to generate an copy of an executable module.
executable image suitable for loading
into memory. When the program is
loaded, the operating system places into
memory a single file that contains the
executable code and data. This statically
linked file includes both the calling
program and the called program.
Statically linked files are significantly In dynamic linking only one copy of
larger in size because external programs shared library is kept in memory. This
are built into the executable files. significantly reduces the size of
executable programs, thereby saving
memory and disk space.
In static linking if any of the external In dynamic linking this is not the case
programs has changed then they have to and individual shared modules can be
be recompiled and re-linked again else updated and recompiled. This is one of
the changes won't reflect in existing the greatest advantages dynamic linking
executable file. offers.
Statically linked program takes constant In dynamic linking load time might be
load time every time it is loaded into the reduced if the shared library code is
memory for execution. already present in memory.
Programs that use statically-linked Programs that use shared libraries are
libraries are usually faster than those that usually slower than those that use
use shared libraries. statically-linked libraries.
Hope you have enjoyed reading the difference between static and dynamic linking of
libraries Please do write us if you have any suggestion/comment or come across any
error on this page. Thanks for reading!
When to use dynamic linking and static
linking
The operating system provides facilities for creating and using dynamically linked
shared libraries. With dynamic linking, external symbols referenced in user code and
defined in a shared library are resolved by the loader at load time. When you compile a
program that uses shared libraries, they are dynamically linked to your program by
default.
The idea behind shared libraries is to have only one copy of commonly used routines
and to maintain this common copy in a unique shared-library segment. These common
routines can significantly reduce the size of executable programs, thereby saving disk
space.
You can reduce the size of your programs by using dynamic linking, but there is usually
a trade-off in performance. The shared library code is not present in the executable
image on disk, but is kept in a separate library file. Shared code is loaded into memory
once in the shared library segment and shared by all processes that reference it.
Dynamically linked libraries therefore reduce the amount of virtual storage used by your
program, provided that several concurrently running applications (or copies of the same
application) use the procedures provided in the shared library. They also reduce the
amount of disk space required for your program provided that several different
applications stored on a given system share a library. Other advantages of shared
libraries are as follows:
Load time might be reduced because the shared library code might already be in memory.
Run-time performance can be enhanced because the operating system is less likely to page out
shared library code that is being used by several applications, or copies of an application, rather
than code that is only being used by a single application. As a result, fewer page faults occur.
The routines are not statically bound to the application but are dynamically bound when the
application is loaded. This permits applications to automatically inherit changes to the shared
libraries, without recompiling or rebinding.
Disadvantages of dynamic linking include the following:
From a performance viewpoint, there is "glue code" that is required in the executable program to
access the shared segment. There is a performance cost in references to shared library
routines of about eight machine cycles per reference. Programs that use shared libraries are
usually slower than those that use statically-linked libraries.
A more subtle effect is a reduction in "locality of reference." You may be interested in only a few
of the routines in a library, and these routines may be scattered widely in the virtual address
space of the library. Thus, the total number of pages you need to touch to access all of your
routines is significantly higher than if these routines were all bound directly into your executable
program. One impact of this situation is that, if you are the only user of these routines, you
experience more page faults to get them all into real memory. In addition, because more pages
are touched, there is a greater likelihood of causing an instruction translation lookaside buffer
(TLB) miss.
When a program references a limited number of procedures in a library, each page of the library
that contains a referenced procedure must be individually paged into real memory. If the
procedures are small enough that using static linking might have linked several procedures that
are in different library pages into a single page, then dynamic linking may increase paging thus
decreasing performance.
Dynamically linked programs are dependent on having a compatible library. If a library is
changed (for example, a new compiler release may change a library), applications might have to
be reworked to be made compatible with the new version of the library. If a library is removed
from the system, programs using that library will no longer work.
In statically-linked programs, all code is contained in a single executable module.
Library references are more efficient because the library procedures are statically linked
into the program. Static linking increases the file size of your program, and it may
increase the code size in memory if other applications, or other copies of your
application, are running on the system.
The cc command defaults to the shared-library option. To override the default, when you
compile your programs to create statically-linked object files, use the -bnso option as follows:
Now, create another source code file viz addDemo.c, and insert the following code into
that.
#include <add.h>
#include <stdio.h>
int main()
{
int x= 10, y = 20;
printf("\n%d + %d = %d", x, y, add(x, y));
return 0;
}
Create one more file named add.c that contains the code of add module. Insert the
following code into add.c
After having created above files, you can start building the executable as follows:
Next, create a file sub.c, and add the following code to it. We have add.c already
created.
Now compile sub.c as follows in order to get the binary object file.
[root@host ~]# gcc -c sub.c
Above command will produce binary object file sub.o.
Now, we have two binary object files viz add.o, and sub.o.We have add.o file in working
directory as we have created it for previous example. If you have not done this so far
then create the add.o from add.c in similar fashion as sub.o has been created. We will
now create a static library by collecting both files together. It will make our final
executable object file creation job easier and next time we will have not to specify two
object files along with addDemo in order to generate the final executable object file.
Create the static library libheymath by executing the following command:
[root@host ~]# ar rs libheymath.a add.o sub.o
The above command produces a new file libheymath.a, which is a static
librarycontaining two object files and can be used further as and when we wish to
use add, or sub functions or both in our programs.
To use the sub function in addDemo we need to make a few changes in addDemo.c and will
recompile it. Make the following changes in addDemo.c.
#include <heymath.h>
#include <stdio.h>
int main()
{
int x = 10, y = 20;
printf("\n%d + %d = %d", x, y, add(x, y));
printf("\n%d + %d = %d", x, y, sub(x, y));
return 0;
}
If you see, we have replaced the first statement #include <add.h> by #include
<heymath.h>. Because heymath.h now contains the signatures of
both add and subfunctions and added one more printf statement which is calling
the sub function to print the difference of variable x, and y.
Now remove all .o files from working directory (rm will help you to do that).
Create addDemo.o as follows:
[root@host ~]# gcc -I . -c addDemo.c
And link it with heymath.a to generate final executable object file.
[root@host ~]# gcc -o addDemo addDemo.o libheymath.a
You can also use the following command as an alternate to link
the libheymath.a with addDemo.o in order to generate the final executable file.
[root@host ~]# gcc -o addDemo -L . addDemo.o -lheymath
In above command -lheymath should be read as -l heymath which tells the linker to link
the object files contained in lib<library>.a with addDemo to generate the executable
object file. In our example this is libheymath.a.
The -L option tells the linker to search for libraries in the following argument (similar to
how we did for -I). So, what we created as of now is a static library. But this is not the
end; systems use a lot of dynamic libraries as well. It is the right time to discuss them.
What is Dynamic Linking?
Dynamic linking defers much of the linking process until a program starts running. It
performs the linking process "on the fly" as programs are executed in the system.
During dynamic linking the name of the shared library is placed in the final executable
file while the actual linking takes place at run time when both executable file and library
are placed in the memory. The main advantage to using dynamically linked libraries is
that the size of executable programs is dramatically reduced because each program does
not have to store redundant copies of the library functions that it uses. Also, when DLL
functions are updated, programs that use them will automatically obtain their benefits.
How to Create and Use Shared Libraries?
A shared library (on Linux) or a dynamic link library (dll on Windows) is a collection of
object files. In dynamic linking, object files are not combined with programs at compile
time, also, they are not copied permanently into the final executable file; therefore,
a shared library reduces the size of final executable.
Shared libraries or dynamic link libraries (dlls) serve a great advantage of sharing a
single copy of library among multiple programs, hence they are called shared libraries,
and the process of linking them with multiple programs is called dynamic linking.
Shared libraries are loaded into memory by programs when they start. When a shared
library is loaded properly, all programs that start later automatically use the already
loaded shared library. Following text will demonstrate how to create and use shared
library on Linux.
Let's continue with the previous example of add, and sub modules. As you remember we
had two object files add.o, and sub.o (compiled from add.c and sub.c) that contain code
of add and sub methods respectively. But we will have to recompile
both add.c and sub.c again with -fpic or -fPIC option. The -fPIC or -fpic option
enable "position independent code" generation, a requirement for shared libraries.
Use -fPIC or -fpic to generate code. Which option should be used, -fPIC or -fpic to
generate code that is target-dependent. The -fPIC choice always works, but may
produce larger code than -fpic. Using -fpic option usually generates smaller and faster
code, but will have platform-dependent limitations, such as the number of globally
visible symbols or the size of the code. The linker will tell you whether it fits when you
create the shared library. When in doubt, I choose -fPIC, because it always works. So,
while creating shared library you have to recompile both add.c, and sub.c with
following options:
[root@host ~]# gcc -Wall -fPIC -c add.c
[root@host ~]# gcc -Wall -fPIC -c sub.c
Above commands will produce two fresh object files in current directory add.o,
and sub.o. The warning option -Wall enables warnings for many common errors, and
should always be used. It combines a large number of other, more specific, warning
options which can also be selected individually. For details you can see man page for
warnings specified.
Now build the library libheymath.so using the following command.
[root@host ~]# gcc -shared -o libheymath.so add.o sub.o
This newly created shared library libheymath.so can be used as a substitute
of libheymath.a. But to use a shared library is not as straightforward as static
librarywas. Once you create a shared library you will have to install it. And, the simplest
approach of installation is to copy the library into one of the standard directories (e.g.,
/usr/lib) and run ldconfig command.
Thereafter executing ldconfig command, the addDemo executable can be built as follows.
I recompile addDemo.c also. You can omit it if addDemo.o is already there in your working
directory.
[root@host ~]# gcc -c addDemo.c
[root@host ~]# gcc -o addDemo addDemo.o libheymath.so
or
[root@host ~]# gcc -o addDemo addDemo.o -lheymath
You can list the shared library dependencies which your executable is dependent upon.
The ldd <name-of-executable> command does that for you.
[root@host ~]# ldd addition
libheymath.so => /usr/lib/libheymath.so (0x00002b19378fa000)
libc.so.6 => /lib64/libc.so.6 (0x00002b1937afb000)
/lib64/ld-linux-x86-64.so.2 (0x00002b19376dd000)
Last Word
In this tutorial we discussed how static and dynamic linking in C is performed for static
and shared libraries (Dynamic Link Libraries - DLLs). Hope you have enjoyed reading
this tutorial. Please do write us if you have any suggestion/comment or come across any
error on this page. Thanks for reading!
References
1. Randal E. Bryant, David R. O'Hallaron, Computer Systems: A Programmer's Perspective.
2. Brian J. Gough, An Introduction to GCC
3. Static, Shared Dynamic and Loadable Linux Libraries
4. Shared Libraries
As of version 5.1, LHAPDF's libraries are built using the GNU libtool program,
and will produce both a static library(libLHAPDF.a) and a "dynamic" shared
library with a .so suffix. The "dynamic" shared library is actually compiled as a
version-specific library, e.g. lib/libLHAPDF.so.5.1.0, and symbolic links are
then used to make it available under less specific names, in
particular lib/libLHAPDF.so.
The difference between the static and "dynamic" shared libraries is that the
function symbols encoded in the shared library are position independent,
meaning that they can be referenced from anywhere and the address will be
correct. When you link a program against a static library, the functions in that
library are copied into your executable, which is correspondingly larger.
Dynamic linking, by contrast, just tells the executable that at run time it should
find the symbols in the system's LHAPDF shared library, with the result that
the executable is smaller than with static linking. Of course, that means that
users of a program that is dynamically linked against LHAPDF need to have a
copy of the LHAPDF "dynamic" shared library on their system, but since they
need to have the PDF grid files anyway, that isn't such a crazy assumption.
We recommend using shared libraries unless you have a good reason not to,
since they reduce executable size and allow your programs to pick up bug
fixes in libraries without recompilation/relinking being necessary.
A common reason for the "dynamic" shared library failing to be found at run
time is not having it in the LD_LIBRARY_PATH environmental variable
(DYLD_LIBRARY_PATH on a Mac)
Using the static library
By default, linking your program against LHAPDF using, e.g. gfortran will
attempt to use the "dynamic" shared library. If you definitely want to use the
static library, pass the-static compiler flag, e.g.
Note that we also have to add explicit linking against the C++ standard library
in this case — C++ strings are used to determine the default paths to data
files — because static libraries, unlike shared ones, have no mechanism for
telling the linker about extra libraries that they depend on.