C Static Libraries Empower Programs
Libraries in C allow numerous functions to be used by many C files. First of all, what is a library? A library in any programming language is collection of functions and perhaps other data structures that may be used by other files. In C, perhaps the most well known library is the standard input output library. Within a C file (extension .c), by including a header file (extension .h) that contains all of function declarations (also known as prototypes) related to functions within a library, the C file can then use functions from the library. Within the library being used is all the function definitions. When a C file is compiled, during the linking phase, the header file links all of its function declarations with the function definitions in another file. An executable file is generated afterwards.
During the linking phase in compilation, static linking occurs meaning that every executable file contains every library of functions it needs. This implies that in memory there are copies of the same function several times which takes up space that could otherwise be used for something else. To avoid wasting space, a dynamic library may be used but that is another discussion. Using the C standard input output library involves dynamic memory.
By using static libraries, a copy of the library is not needed in each program. Additionally, with the code being connected at compile time, run-time loading costs are avoided. At runtime, the executable files have no dependencies on the library, meaning only executables are loaded while libraries are not by the compiler at run-time.
Creating a static library:
- Create a header file containing all the prototypes that may be accessed from the C files you are currently working with. In the example below there are some prototypes that can be found in some commonly used libraries. In addition to adding prototypes to the header file, it is important to include #ifndef <HEADERFILE>_H and #define <HEADERFILE>_H at the top and #endif at the bottom. This ensures that the header file is used once instead of multiple times which may cause errors. Below is an example of the holberton.h header file I created to illustrate these points:
2. The next step is to have all the c files related to the prototypes in the same location:
Once all your c files are gathered in one place along with the header file, run the command:
gcc stands for GNU Compiler Collection that is used to compile all the C code in addition to the flags included. “-Wall” enables all warnings and that some users consider questionable and that are easily avoidable. “-pedantic” rejects all programs that use forbidden extensions and some other programs that don’t follow ISO C and ISO C++. “-Werror” reports all warnings as hard errors and source code that triggers warnings will be rejected. “-Wextra” reports command line options that have no documentation association to be displayed. “-c” is the flag that compiles or assembles the source files, but do not link, meaning that object files are only created. Finally, all these flags are applied to all C files in the current directory from “*.c”. After completing the command sequence, all the C files (.c extension) that relate to the header file should also have corresponding object files (.o extension) in the current directory.
3. The next command will compile all the object files into a library file (.a extension). The library file name in this case will libholberton.a. The command is as follows:
“ar” stands for “archiver” which is the basic tool used to create libraries and in this case is being used to create a static library. The “-c” tells “ar” to create a library if it does not exist already. The “-r” flag tells “ar” to place newer objects in place of older objects in the library. Following the flags is the name for library file, libholberton.a. By using “*.o”, “ar” is applied to all object files.
4. Entering the command “nm libholberton.a”, where nm lists symbols from object files, you can see all the files that are included in the static library you’ve just created! Example:
Using functions from a static library!
Now that we have a static library created, let’s see it in action. Here is a an example from a program called main.c below:
The main.c file requires use of the _puts function from the header file holberton.h that contains the prototype (by the way, puts also relies on _putchar). This function simply reprints every character of the string followed by a newline, which is similar to the puts function in the standard output input library.
To access the _puts function from the static library that was just created and see the output, enter:
Here we see gcc is compiling main.c, where the flag -L. tells gcc to add the current directory to the list of directories to be searched for. “-l” tells gcc to link all the files from the static library “holberton”. “-o” tells gcc to write the output to a file named “quote”. Next, by entering “./quote”, you can see that the string from the main.c program is reprinted followed by a newline.
That’s a wrap up on static libraries!!