C Programming | Static Libraries vs Dynamic Libraries
Matias Zappino
Helping companies build high-performing IT teams | Driving Sales Growth with Tech Expertise
There are two different types of libraries Static and Dynamic or “Shared” libraries. In this post, I’m going to explain what are Dynamic Libraries, but first I recommend you to check this post where I cover Static Libraries.
Static libraries, while reusable in multiple programs, are locked into a program at compile time. Dynamic, or shared libraries, on the other hand, exist as separate files outside of the executable file.
The downside of using a static library is that its code is locked into the final executable file and cannot be modified without a re-compile.
In contrast, a dynamic library can be modified without a need to re-compile.
They consist of separate files containing separate pieces of object code. These files are dynamically linked together to form a single piece of object code, they contain extra information that the operating system will need to link the library to other programs.
Because dynamic libraries live outside of the executable file, the program need only make one copy of the library’s files at compile-time.
The downside of using a dynamic library is that a program is much more susceptible to breaking. If a dynamic library for example becomes corrupt, the executable file may no longer work. A static library, however, is untouchable because it lives inside the executable file.
The upside of using a dynamic library is that multiple running applications can use the same library without the need for each to have its own copy.
The implication of this is that memory is conserved while using dynamic libraries since each application or program can access the dynamic library without needing an individual copy, as would be the case if we were using static libraries. Although dynamic libraries afford the ability to alter source code without recompiling the entire program, static libraries’ execution speed at run-time is faster because the object code for the functions within the library is already in the executable file. As a result, multiple calls to functions are handled more efficiently than when using dynamic libraries.
Dynamic Library Creation (Linux only)
gcc *.c -c -fpic
The .c source files need to be prepared for use in a dynamic library. Since multiple programs can all use one instance of a dynamic library, the library can’t store data at fixed addresses. This is because the location of the library in memory will vary between programs. This is done by using the compiler flag -fpic. Since we need to apply this step after the compile process has generated the object code, the compiler must be told to halt and return one object file (.o) for each source file. This is done by using the -c flag.
gcc *0 -shared -o liball.so
The object files are now ready to be compiled into a dynamic library. This is done by compiling all of the .o files using by using the -shared flag. Later when compiling program files, the compiler identifies a library by looking for files beginning with ‘lib’ and ending with a library extension (.so for dynamic, .a for static). Therefore it’s important to name a library accordingly.
export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH
Because a program needs to know where to look for library files, we must add that location to the environmental variable LD_LIBRARY_PATH.
Static Library Creation (Linux only)
Creating a static library is much simpler. First, create the object files the same way as step 1 above. Then archive the library using ‘ar rcs liball.a *.0’
Your program should include a prototype for each of the functions that exist in your library. If you’re using a header file for these prototypes, make sure to include the name of that file in your other files by using #include “<header file>”
Program compilation
gcc -L. -lall -o my_program main.c
When compiling program files, we have to tell the compiler to use the library files and where to find them. "-l" tells it we want to include library files. And "all" tells it to look for the libraryu liball.so. It's important to leave the 'lib" preffix and ".so" suffix out of the flag because the compiler already identifies library files that way. "-L" tells the compiler it can find the library file in the current directory.