What is & how to create Static Libraries in C.
Introduction:
When it comes to static libraries, how the code is being called can save a lot of memory and time. Static libraries allow the ability to grab called functions or variables from the library at the time of linking. This allows to use functions as they go and save memory rather than the standard way of compiling and linking all of them and thus the executable would be bigger in size compared to an executable calling and using the functions as they need to be linked with a library. A downside to static libraries is that you have to recompile the library program each time there is a change of the library code. Static libraries are really just collection of object files. By using libraries it is easier to not only group code together but to share it! This can be helpful to make sure your code is compatible with others for a project or to group code together to source bugs. By having the object code linked from the library it becomes faster to link all needed functions rather then having separate files called upon and the linker has fewer files to look for which also helps speed the phase up. Libraries work by having symbols such as functions, variables indexed making it easier to find them during the linking phase and only the symbols called in the main program during the linking phase are used rather than during run-time of the main program.
How to create a static library
You have to create a header file that ends with “.h”. In the header file as shown it is best to provide each prototype (which is the function to be used in a C file). Double inclusion or the act of the header file being defined from multiple C files can occur and it is best to prevent this by creating a macro around the prototypes as shown below.
While there are a lot of compilers out there, this tutorial will be using GCC (Gnu Compiler Collection). More info on GCC can be found here. in order to get output code from GCC, the code goes through 4 steps: Pre-processing, compilation, assembly and linking. the phases that will be used directly for this post are compilation to compile the C files into object code and linking to which the static library created will link with the main code being compiled. In order to have code to go through the compilation phase and stop as to not link it, we use:
gcc -c *.c
This will allow the specified files to go through the compilation phase and not the assembly or linking phase. However how is this grabbing all C files? Well c files end with .c but in order to grab all files of that type we use a wildcard. Wildcards such as *.filetype allow us to invoke certain actions in the linux system but for this case the *.c allows us to grab all files so long as they end with .c as their type. After running gcc this way, all c files with generate an object file that ends with .o with the same file name associated with the C files.
Now having a bunch of object files around can be annoying as they are unorganized and have to be linked one by one by gcc so now is the time to bundle them into a library. Using the command:
ar -rc libholbertonschool.a *.o
ar is an archive utility which allows us to archive the objects files into a single library. The ar flag -r allow us to replace older objects in the library with new ones and the flag -c replaces older object files in the library with updated ones. The command above uses ar to create a library called libholbertonschool.a, .a is the file type used for a library and yet again to grab files of a certain tpye in one shot we use a wildcard but this time we specify the wildcard to help us get all files that with .o, object files into our newly created library. As shown below, if you wanted to see the contents of the library avter creating it, running:
ar -t libholbertonschool.a
Will return the contents of the library which is just a bunch of object files.
Now that the archive or library is created we need to index it so it becomes easier on the linker when it searches for the symbols as well as to make sure the order for the symbols will not matter during linking. To create the index or even update it after creating it we just invoke the following command:
ranlib libholberton.h
The command “nm” can be used to list the symbols from the object files, the T uppercase t is to show the symbol is in text-code and the uppercase U is to show a symbol is undefined within each object file.
Now that the library has been created, it will be useful to use one of the stored functions in an actual C program. so below is a standard C program printing text by calling the function _puts that is within the example library. by compiling the main.c file with gcc we run into an error of undefined reference to _puts, that is because we arent linking the library so we cannot reference that function as nothing connects it to the library. So to link the main file we use this command:
gcc main.c -L. -lholberton -o quote
gcc compiles the main file as well as links it with the holberton library as specified -L -lholberton, the -L flag tells the linker that libraries might be found in the following directory which is just the “.” or current directory the command is being run in, as well the library name doesn't need to end with .a for the command as the linker will add that in itself, same for lib. Then we use the -o quote to specify that the output file should be quote. Now we can run our program by calling quote with ./quote and have the main program run with the library.
Bonus: automate the process
While the process is rich and fulfilling, creating a library all the time can be annoying especially once you learn the concepts well. You can use bash to automate your script as shown below, however this isn't a requirement to get a library but just a recommendation on what to do next, as shown it encompasses all the commands used already in this tutorial to create a library called liball.
That is how you create a library step by step in terminal and where to look next to automate the process. Thank you for reading!