Are you C’ing Static Libraries? If Not, You Probably Should!
Why Use A “C” Library
The question that software engineers ask the most often, is “why?”. Why do we do the things we do? Why do this? Why do that? Which leads me to ask this next question; why use “C” libraries? What’s the real benefit?
The answer to that question begins with; efficiency. When we find ourselves often creating programs that utilize the same few functions, wouldn’t it be in our best interest to organize these functions collectively in one spot, where we can quickly resource them as they are needed? For this purpose, we queue the “C” libraries!
These libraries can be thought of as a collection of object files, that are linked during the compilation process. More specifically, they are linked during the linking phase of the compilation process.
When it comes to creating and using “C” libraries, there are two options:
STATIC LIBRARY vs. SHARED(dynamic) LIBRARY
The main difference between these two libraries comes down to when/how they are added to our program. Static libraries are linked during the compilation process each time, and are not relevant at runtime. While shared libraries use only one copy of the library, and it is attached to the program at run time. Which may directly impact the speed at which the program launches.
For now, I will only be discussing the specifics on creating and using STATIC libraries. There may be another article that addresses SHARED/DYNAMIC libraries later on, so stay tuned.
HOW TO CREATE A C STATIC LIBRARY.
I will take you through the steps it takes to create a “C” static library, using the archive name “libutil.a” , as an example.
To create the static lib libutil.a — Invoke command below:
This uses the “ar” program, archiver, to put copies of object files util_file.o util_net.o and util_math.o in an archive name “libutil.a”
-c flag: creates library if it does not already exist
-r flag: replaces old object files with the new object files
NOW COMES INDEXING
After the archive file gets created, it must then be indexed. This index is later used by the compiler to speed up symbol-lookup inside the library.
The command used when creating/updating an index is “ranlib”.
See below at how it’s invoked:
Some archivers do this automatically and so the “ranlib” command will appear to have done nothing.
If the archive file index is older than the file’s last modified time, the compiler will complain that the index is “out of date” and abort.
Two ways to solve this problem:
- Run “ranlib
- Use cp -p flag to keep all attributes of a file when copying
HOW TO USE THE STATIC LIBRARY
When we want a program to use an archive file, add the library name to the list of object file names given in the linker, with the -l flag.
Example given below:
This will create an object file named main.o and any other symbols needed from “util” static library.
Take note in example:
- -L. ← This flag indicates that the compiler should search for libraries in the current directory, in addition to the usual places the linker checks for standard libraries.
When the linker is searching in order and comes across a libutil.sg(shared library), before reaching a libutil.a(static library), it will prefer the .sg (shared library). UNLESS OVERRIDDEN BY A LINKER FLAG.
You can see if your linker will use either of these:
‘wl, static’ OR ‘-Bstatic’
To learn more about your specific compiler or linker’s option flags, you can always RTFM! Until next time!!