Photo by Ria Puskas on Unsplash

The Comparison Between Static and Dynamic Libraries in C

What are they, their differences, how they work, and how to create and use them.

Michelle Giraldo
4 min readDec 17, 2019

--

Libraries can be useful tools for programmers as libraries are collections of pre-compiled code such as functions, structs, and more. This code can be constantly used and re-used in whatever program the library was added to.

While static libraries and dynamic libraries both are kinds of libraries, they are still really different. Even with the way they are created.

Creating Libraries

First, every .c to be added to the library must be compiled into source code. For static libraries, or archive libraries, to do this one would run:

gcc -c

While dynamic libraries, also known as shared libraries, run an additional flag like so:

gcc -c -fpic

Both of these would be followed by the wanted .c files. If it was every .c file in the directory, then this could be shortened to *.c

Next is actually creating the library from the object file(s). For dynamic libraries you just compile with gcc again with another flag:

gcc -shared -o [insert name of library].so [insert .o file(s)]

Static libraries on the other hand:

ar -crs [insert name of library].a [insert .o file(s)]

So dynamic libraries ends with .so while static libraries ends with .a

Using Static Libraries

To use static libraries is pretty straight forward. When compiling your final program, just include the library along with everything else you’re compiling. For example:

gcc main.c [library name].a

This would compile a program to a.out (as no name was specified… in order to do that then one would add the -o flag followed by the name they want). The files being compiled here would the main file, which ends with .c, and the static library specified.

But for dynamic libraries there’s actually some extra steps to compiling and running the program.

Linking Shared Libraries

A shared library actually needs to be linked to the main file during compilation. This is done by adding a very specific flag:

-l[library name]

This flag works because GCC (the GNU Compiler Collection) automatically assumes the library name starts with lib, which is what the l is representing, and ends with either .so (like in this case) or .a. Which is why the user doesn’t need to add the extension name to what’s above.

Overall, it’d look something like this:

gcc main.c -l[library name]

But wait! There’s actually one other thing… the linker wouldn’t be able to find the library because it’s in any of the places GCC looks at by default. This can be solved by telling the GCC where to look for the library by using the -L flag:

-L[path to directory with the library]

And since this directory with the library would actually be the current directory, this could be shortened and written as:

-L.

Since . represents the current working directory. The final line would look like so:

gcc -L. main.c -l[library name]

Making Shared Libraries Available

Now that the program is compiled… there is still another thing to do before it can be run. This is actually making the library available, which can be done by using the LD_LIBRARY_PATH variable.

The user has to prepend the current working directory to the already existing LD_LIBRARY_PATH like so:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

The reason why export was added to the beginning was because if the changes wasn’t exported then this wouldn’t have been inherited by the child processes. Also, notice the period(.)? Just like before, this represents the current working directory.

Now the program can be run!

Some Other Ways Static and Dynamic Libraries Differ

  • Static libraries take up more memory than dynamic libraries. This is because for shared libraries, external programs are built into the executable file, while there’s only one copy of the dynamic memory in memory. This is why dynamic libraries take extra steps before being able to run the executable program.
  • Which is why these programs are a bit faster at running with dynamic libraries, since the code is already in memory. Shared libraries cause them to take a bit longer because it’d have to load into the program each time.
  • While for dynamic libraries the executable program wouldn’t need to be recompiled if there’s an external file change, shared libraries would need to be.
  • There can be an issue if a dynamic library is deleted, as the program wouldn’t have the code anymore and wouldn’t work. Meanwhile, static libraries would still work, even if the original library was deleted, because all the code was added to the executable.

So as you can see, there are still advantages and disadvantages to using one library over the other. That’s why it’s better to judge which library would be better through a case by case system.

--

--

Michelle Giraldo
Michelle Giraldo

Written by Michelle Giraldo

Graduate of Holberton School, New Haven as the former Student Tutor of Cohort 11, with a completion of the AR/VR specialization.

No responses yet