Static Libraries in C
As the scope of the project becomes larger, we may find it more efficient to reuse previously written functions and those already in the program. Although these functions can be linked as separate files during compilation, it becomes increasingly inefficient to manually enter the name of each file as the number of files exceeds one’s patience. The process becomes even more painful when these functions are located in different directories.
This is where the libraries come into play (:
by having all these functions in one library file, we save ourselves from having to call separate files at compile time.
Just like books in a library are categorized and labeled, files in a library archive are indexed so that it’s easy for the compiler to look up needed functions. So we can have specific libraries for example string manipulation, mathematical operations, among others.
How do libraries work?
Static libraries are added during the linker phase of the compilation process. During the linker phase: the linker links access all the libraries to link functions to the program. Static libraries are merged with other static libraries to create an executable program. During the compilation of a program, the static library is called to execute the program.
Making a Library
Every library consists of two parts: a header file and the actual code file. The header file, normally denoted by a .h suffix, contains information about the library that programs using it need to know. In general, the header file contains constants and types, along with prototypes for functions available in the library.
We create our function, this program contains a pointer to a string, which makes all the path of the string and prints it with putchar():
void _puts(char *s)
for (i = 0; s[i] != 0; i++)
we include the functions in our library .h
void _puts(char *s);
now we will convert our file to object file. We can use the -c option with the GNU compiler (gcc) to stop the compiling process after the assembling stage, translating our files from .c to o.
$ gcc -c _puts.c // produces a _puts.o object file
we use the tool ar with other flags “-rc”
$ ar -rc libholberton.a _puts.o
- -r: replaces existing archive with the new updates
- -c: creates the archive if one does not already exists
The command above will create a static library called “libholberton.a”. Inside of it will be our _putchar() function that has been translated to an object file via the gcc command earlier.
we can use the nm command for listen name of all functions in the archive
$ nm libholberton.a
_puts.o U putchar
000000000000000 T _puts
note: we can also use the flag ar -t to list names of all object files in the archive
How to use them
We make use of our function in our input program
_puts("\"At the end of the day, my goal was to be the best hacker\"\n\t- Kevin Mitnick");
we compile our program as follows
gcc main.c -L. -lholberton -o my_test
- -L says “look in directory for library files”
- . (the dot after ‘L’) represents the current working directory
- -l says “link with this library file”
- holberton is the name of our library. Note that we omitted the “lib” prefix and “.a” extension. The linker attaches these parts back to the name of the library to create a name of a file to look for.
- -o my_test says “name the executable file my_test”
Now that everything went well, we have an executable file
"At the end of the day, my goal was to be the best hacker"
- Kevin Mitnick