As we make computer programs, we realize that some parts of the code are used in many of them. For example, we can have several programs that use complex numbers and the functions of addition, subtraction, etc. are common. It is also possible, for example, that we like to play games, and we realize that we are repeating the code over and over again to move an image across the screen.
It would be great to be able to put these functions in a separate directory from the specific programs and have them already compiled, so that we can use them whenever we want. The huge benefits of this are:
- Not having to rewrite the code (or copy-paste).
- We will save the time of compiling each time that code that is already compiled. In addition, we already know that while we make a program, we test and correct, it is necessary to compile between many and “more many” times.
- The already compiled code will be tested and reliable. Not the first few times, but when we have already used it in 200 different programs and we have corrected the errors.
The way to do this is to make libraries. A library is one or more functions that we have already compiled and prepared to be used in any program that we make. You have to have enough eye when we do them so as not to put any dependency on something specific in our program. For example, if we make our function of moving Lara Croft’s image, we will have to make the function so that it admits any image, since Lara Croft would not hit us at all, jumping in a “space invaders” style game.
How we have to organize our code
In order to put our code in a library, we need to organize it in the following way:
- One or more source files .c with the code of our functions.
- One or more .h header files with the types (typedefs, structs and enums) and prototypes of the functions that we want to be able to use.
As always, we are going to do an example. The files would be these:
It’s a file with a couple of simple addition () and subtraction () functions.
An important detail to take into account is the #define of the header file (.h). When making a library, we do not know in which future programs we are going to use it or how they will be organized. Suppose in a future program that there is a header file file1.h that makes #include ours. Let’s imagine that there is also a file2. h which also makes #include ours. Finally, with a little more effort, imagine that there is a third fichero3.c does #include of fichero1.h and fichero2.h, that is, more or less the following:
Compile and link with static libraries
Once we have our code, to get a static library we must perform the following steps:
- Get the object files (.o) from all our sources (.c). For this they are compiled with cc -c source.c -o source.o . The -c option tells the compiler not to create an executable, but just an object file. Here I put the cc compiler , because it is the one I used for the example, but you can use gcc , or the g ++ (for C ++) or one of fortran, pascal, etc.
- Create the library (.a). To do this, use the ar command with the following parameters: ar -rv libname.a source1.o source2.o … The -r option tells the ar command that it has to insert (or replace if they are already inside) the files object in the library. The -v option is “verbose”, so it displays information while you’re doing things. Next we put all the object files that we want. ar is actually a much more generic command than all this and can be used to package any type of file (not just object files). It also has options to see what files are inside, delete some of them, replace them, etc.