Static vs Dynamic(Shared) Library

Heart Bleed
Obscure System
Published in
3 min readMay 23, 2019

Before we go to the difference between static and dynamic library let us understand what a library is and its uses.

Library

Library is a piece of packaged code that can be reused across multiple executable. Lets try a simple example to understand it.

The above program is a simple calculator which performs basic arithmetic operations. Lets build a library of this simple calculator. Below are the steps to build the library. “-c” option specifies the compiler to compile but not link as we do not have main function. “ar” is the tool used to build static library.

$ gcc -c simple_calc.c -o simple_calc.o
$ ar rcs libsimple_calc.a simple_calc.o

Now that we have a simple calculator library. We can use it in our programs. Lets look at an example on how to use it.

$ gcc calc_usage.c -L./ -lsimple_calc -o calc_usage
$ ./calc_usage
11
4

“-L” to specify the path where the library is there(above it specifies the current directory where the library is available). We skip the prefix “lib” in the libsimplecalc.a as gcc understands it is prefixes with the lib by the “-l” option. Similarly the library can be used across multiple executable thereby avoiding redundant code and code maintainability.

Now lets try to understand static vs dynamic library. There are a lot of nuance details of static and dynamic library. We will not be covering it in this article. We will be trying to understand the basic difference between the two using a simple example. We will be creating a simple shared and static library which provides value of pi(3.14). The library will do nothing more than provide the value of “pi”. I am keeping the library very simple to make the understanding easy.

Let begin with creating the static library

$ gcc -c pi_static.c -o pi_static.o
$ ar rcs libpi_static.a pi_static.o

Now lets build the shared library

$ gcc -c pi_shared.c -o pi_shared.o
$ gcc -shared -o libpi_shared.so pi_shared.o

Now we have both the static and shared library libpi_static.a and libpi_shared.so respectively. Let’s use it in a program.

$ gcc static_shared.c -o static_shared -L./ -lpi_static -lpi_shared
$ ./test
Static pi value = 3.140000
Shared pi value = 3.140000

The output is same. and we see no difference. Now lets make a small change to both static and shared library.

Now compile both static and shared library only. Do not compile the static_shared executable. Let’s look at the difference between static and shared after this.

$ gcc -c pi_static.c -o pi_static.o
$ ar rcs libpi_static.a pi_static.o
$ gcc -c pi_shared.c -o pi_shared.o
$ gcc -shared -o libpi_shared.so pi_shared.o

Now lets execute static_shared executable without recompiling it.

$ ./static_shared 
Static pi value = 3.140000
Shared pi value = 3.141590

As you can see the above output shows that static and shared pi value. We can see the static pi value is the same as before where as the shared pi value is updated with the latest modified value.

This is the typical difference between static and stared library. Static library are packed into the executable where as shared library are loaded while the executable is loaded. For the static pi value to reflect, we need to recompile the static_shared executable with the new static library.

$ gcc static_shared.c -o static_shared -L./ -lpi_static -lpi_shared
./static_shared
Static pi value = 3.141590
Shared pi value = 3.141590

Bisecting the Executable

$ nm static_shared
0000000100000000 T __mh_execute_header
0000000100000f20 T _main
U _pi_shared
0000000100001020 D _pi_static
U _printf
U dyld_stub_binder

Bisecting the executable using “nm” we see that “pi_shared” symbol type U and pi_static symbol type as D. Reading through the linux reference https://linux.die.net/man/1/nm , we can see the,

“U” — The symbol is undefined.

“D”/“d” — The symbol is in the initialized data section.

To understand more about NM , please visit the my article on NM

Conclusion

Static library is compiled as part of the executable whereas shared library are loaded during run time. Both have their have own advantages and disadvantages. For example static library increases size of the executable whereas the shared library impacts the performance of the executable since it need to load the library during run time.

--

--