Shared (dynamic) Libraries vs. Static Libraries —Differences in performance.
This post will explain in detail:
What are shared libraries?
How does one create shared libraries?
How does one use shared libraries?
Differences between static and shared libraries
If you’d like to learn more about static libraries, check out my post here. This post will go in detail into dynamic libraries.
What are Shared Libraries in C?
Shared libraries are libraries that use dynamic linking vs static linking in the compilation steps for compiling a file. Static and dynamic linking are two processes of collecting and combining multiple object files in order to create a single executable file. The main difference between the two is the type of linking they do when creating an executable file.
Dynamic linking defers much of the linking process until a program starts running. Compared to static libraries where a file in compiled and all the machine code is put into an executable file at compile time, dynamic linking performs the linking process “on the fly” as programs are executed in the system. In dynamic linking, dynamic libraries are loaded into memory by programs when they start. When you compile a shared library, the machine code is then stored on your machine, so when you recompile the program that has newly added code to it, the compilation process just adds the new code and store it to memory vs. recompiling an entire file into an executable file like a static library.
How to create Shared Libraries?
$ gcc -g -fPIC -Wall -Werror -Wextra -pedantic *.c -shared -o libholberton.so
The -g flag include debugging information
The -fPIC flag enables “position independent code” generation, which is a requirement for shared libraries. This allows the code to be located at any virtual address at runtime.
The -shared flag created a shared library, hence the .so extension for shared object. The -o created an output file. When you use both, you created a shared output file name libholberton.so.
The -Wall -Wextra -pendantic flags are all warning and error flags that should be included when compiling your code
When we use this sequence of flags with the
gcc command, we are compiling all the C files in the current directory and created a shared library called
libholberton.so that now exists in memory on our machine.
If we have C files that provide some sort of functionality that we want to use in a shared library, we use the command above to create a shared library that now will be able to be reference the shared library in memory instead of recompiling an entire file.
How to use the Shared Libraries?
$ gcc -Wall -Werror -Wextra -pedantic -L. 0-main.c -lholberton -o len
We’ve created a shared library called
libholberton.so and now we want to use it on a file called
0-main.c . So what do we do it? Use the command above.
The -L after the library name telling the linker that the library might be found in the current directory
The 0-main.c file is the file we want to use that references the shared library to execute our program
The -lholberton flag is the shared library name without the .so extension.
The -o flag is to create an executable filename len
After running the command, we now have an executable file name
len that references the shared library
libholberton.so which is stored in memory in our machine. If you then run the
len executable file, it will not work because there’s one step you need to do before executing the
len file! You need to set your LD_LIBRARY_PATH environment variable so that the runtime linker can find and load your
.so file into the executable at runtime.
$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
The command above installs the library into your current working directory. To install it in your
/usr/lib folder, use the command below:
$ export LD_LIBRARY_PATH=$HOME/lib:$LD_LIBRARY_PATH
Now you can use your
len executable file, which prints out the length of the string “Holberton” which is 9. Enjoy.
Differences between Shared and Static Libraries?
- All the code to execute the file is in one executable file, with little to virtually zero compatibility issues
- Constant load time every time a file is compiled and recompiled
- Larger in size because the file has to be recompiled every time when adding new code to the executable
- Only one copy of the shared library is kept in memory, making it much faster to compile programs and significantly reducing the size of the executable program
- Dynamic linking load time will be reduced if the shared library code is already present in memory
- Slower execution time compared to static libraries
- Potential compatibility issues if a library is changed without recompiling the library into memory
Questions, comments or concerns, feel free to comment below, follow me or find me on Twitter @ NTTL_LTTN.