Static Libraries in C
In the previous blog post we learned about Compiling Process and that in the linking part of it compiler connects binary code to libraries and then returns executable file. So now let’s talk a bit more in detail about those libraries.
First… What is a library? Well library is a file containing several object files. Ok… But what does that mean and how did those files get there? Answering this question would probably prompt a few other ones so let’s see what static libraries in C are all about. Here we will learn how do they work, why we use them, how to create them and how do we use them.
- How they work?
When in last stage of compilation process linker generates executable file it also adds (copies from the library) code of a function we are using in our program. That function is part of the static library which we included in our code in order to be able to use that function. For every function in our code that is from the static library, linker will include code for it in our executable file. This is an issue if we use a lot of functions in the same program because for every function that we include the size of the program will increase because we are copying code of that function into executable file.
One other problem with static linking would be portability. So what happens when we move that executable file? Nothing! And that is the problem. If some changes were made to the library or library got updated in the meantime, those changes will not reflect in our program unless we recompile it with the updated library.
2. Why we use them?
One must wonder now… Why would we ever use libraries if they increase size of our program and make us recompile it every time some changes are made to it? But even with these drawbacks of static libraries; if you think about it, what if you move the program and there is no library you need it to be linked with. In this case the code is already copied into your executable file and you don’t have to worry about it. This at the same time allows easier distribution and installation of your program.
But why do we use them you might ask? Have you ever written the same code over and over again in different programs and you wish there was some magical way to just skip that part. Well that’s what libraries do. You can add those pieces of code to the library and just include a library in your compilation process and compiler will insert that code into your program when you want it to, without you having to write it over and over again.
Now let’s see how we make that happen.
3. Creating a static library
The basic tool used to create static libraries is a program called ‘ar’, for ‘archiver’ and this is how it would look like in command line.
ar rc libname_of_your_library_here.a file1.o file2.o file3.o
This command creates a static library named ‘libname_of_your_library.a’ and puts copies of the object files “file1.o”, “file2.o” and “file3.o” in it. Every library name starts with lib and ends with .a extension.
Let’s take a look at some examples.
First we write some programs to individually perform some tasks we use often and write all their prototypes in the header file. Now in order to place all the object files into our library we first need to create our object files from all those .c files and we do that by using gcc to compile them but with option -c which returns the same file names but as object files and with extension .o. Now those .o files are our object files that we want to save in our library (named my_lib in the example) and we do that by using the above mentioned command ar and with ‘rc’ option so that in case library does not exist one gets created (c option) and in case it does old files get replaced with new ones (r option).
Just to make sure all of our object files were added correctly to our library we can use ar -t to display a table listing the contents of archive.
Once we create our archive, or modify it, we need to index it. And why do we do that? Well just like when you are looking for a specific chapter in a book you look at the table of contents to find it faster. Compiler does the same thing if our archive is indexed. And to index our library (archive) we run this command:
4. How to use C library
So we created our library and now we want to see it in action so here is how we do that. We do this by adding the library name to the list of object file names given to the linker. And to accomplish this we use a special flag -l attached in front of our library name without lib at the beginning and .a at the end. Linker takes care of this for us. Flag -L. tells the linker that libraries might be found in the given directory. So we are looking at something like this:
gcc main.c -L. -lname_of_your_library_here -o your_exe_file_name
This will create a program using object file main.o created from main.c and any functions we used from the specified static library.
Let’s look at the example for that too.
Now we know that just by adding our library during compiling process we can save so much time because static libraries allow us to add to them functions that we don’t want to write over and over again.