Before starting to describe the major differences between static and dynamic libraries let’s define a library first: A library is a collection of pre-processed functions stored in an object code format in a ready to use form. These libraries work by including them at the top of our code or better known as header files, for example, #include <stdio.h>.
In order to get the concept of a library as a whole is important to understand every part of the cycle of a program:
Firstly a program is written using an editor in the form of a text file, this program might make use of other programs or libraries, these libraries are brought together with the program so we can execute it.
However, before getting to execute a program, this must be compiled to translate the text file into an object file that the machine can understand and execute. During the compilation of the program, the process of Linking is performed and what happens during linking is a process of bringing external programs together required by the one written for its successful execution, and is just the last step in the compiling program.
Why use libraries?
Knowing all the before is easy to understand why is so effective to use libraries in our programs. The functions contained in the library or header file are declared as function prototypes, so with this references the real object files where the functions are stored and from where they are inserted or called in our executable program.
Now, the types of libraries are determined on how are named, the filename of a library always starts with lib, followed by their name, and finally ending in two ways:
- .a for Static Libraries.
- .so for Shared Libraries.
How to create a Static library
Follow the next steps to create our own static library:
- Create a C file or multiple C files that contains a function in it: In this example, I’m going to use a simple function _strlen.c that gives the number of characters in a string.
2. Create a header file in the same directory where to write the function prototypes or your function or functions: For example, I’m going to call it holberton.h and include header guards.
3. Compile your program or all your .c files:
I use the de C compiler with the option -c to prevent the compiler to create a complete program and only get the object code file (“.o”).
4. Use the command ar to take all the object files created and bring them together in one file with the option rc.
The library to create is named libholberton.a, and the option r is used to add or replace older files when needed and the option c to create the archive.
After an archive is created, or modified, there is a need to index it. This index is later used by the compiler to speed up symbol-lookup inside the library and the command used to create or update the index is called ‘ranlib’. However, on some systems, the archiver (which is not always ar) already takes care of the index, so ranlib is not needed.
How to create a Dynamic Library
Follow the next steps to create our own Dynamic library:
- Like in the static libraries, create a C file that contains a function in it:
2. Also as before, create a header file for the library for the prototype of the function and others functions:
3. Compile your .c files to get the object files for the library:
As before I use the -c flag to prevent the compiler to create a complete program and only get the object code file (“.o”). The -fPIC flag stands for “Position Independent Code”, which means that generates a position-independent code, this is necessary because the code shouldn’t be dependent on being located at a specific address in order to work whit it in many programs.
4. Create the dynamic library and include into it all the object code files previously compiled:
The library was called libholberton.so and the flag used is -shared, that is the linker option that produces a shared object which can then be linked with other objects to form an executable.
Also, if you use nm -D libholberton.so you can see all the symbol table associated with every object.
5. Export the library location to an environmental variable:
LD_LIBRARY_PATH is the search path environment variable for the Linux shared library.
How to use the libraries:
The use of both libraries are pretty similar:
1. Compile your program with the shared or static library:
The -L flag specifies the path to the library in this case we just put the . (dot) because our library is in the current working directory.
Note aside, if you type ldd followed by the executable file you will get the dynamic library dependencies:
7. Run your program:
Note: you know how the system knows where to find each library?
This is where ldconfig is used. This creates the necessary links and cache to the most recent shared libraries found in the trusted directories.
Differences Between Static and Dynamic Library
What are the advantages and drawbacks of each of them?
There are certain advantages when you use static libraries, some of them are:
- You can take your program to another computer and it will execute normally. It’s Portable!
- If you do changes into the static library this won’t affect the executable. This makes the Static libraries a good option when your programs aren’t so big and kind of simple.
However there also some drawbacks about this libraries:
- All of the objects are in the executable file, making it quite big, especially if you want to add more and more functions. So if the program gets complicated this might be not the best choice library to use.
- If a library code is updated, the programmer has to recompile the program into a new executable file.
On the other hand, the advantages when you use Dynamic libraries are:
- It only needs one copy at runtime. This facility makes it a flexible library that can be used in multiple programs without the need for each file of having its own copy.
- I a library is updated, the executable files don’t need to be recompiled again.
But also its good to have in mind the disadvantages of this kind of libraries:
- It is dependent on the library, for example, if the library is erased the executable file won’t work.
- Again, if the library suffers a problem, like corruption, the executable cannot work.