Home / Tutorials / Static Library
Static Library
Libraries vs Object Files
An object file (.o) is the compiled output of a single source file. It contains machine code and a symbol table, but unresolved references to symbols defined elsewhere.
A library is a collection of object files bundled together. Rather than listing many .o files on the linker command line, you create a library once and link against it by name. This makes builds simpler and allows reuse across projects.
There are two kinds of libraries:
- Static libraries (
.aon Linux/Unix,.libon Windows) — The library code is copied into the executable at link time. The resulting binary is self-contained and does not require the library to be present at runtime. - Dynamic/shared libraries (
.soon Linux,.dllon Windows) — The library is linked at runtime. The executable contains only references to the library; the library file must be present on the target system.
Creating a Static Library with ar
The ar (archive) utility creates, modifies, and extracts files from static libraries.
First, compile your source files to object files:
gcc -c mathutils.c -o mathutils.o
gcc -c stringutils.c -o stringutils.o
gcc -c fileutils.c -o fileutils.o
Then create the archive:
ar rcs libmyutils.a mathutils.o stringutils.o fileutils.o
The flags rcs mean:
r— Insert the files into the archive (replacing existing members with the same name)c— Create the archive if it doesn't exists— Write an object-file index into the archive (equivalent to runningranlibafterwards)
ranlib
ranlib generates an index of the symbols defined in an archive. This index speeds up linking by allowing the linker to quickly find which object file in the archive defines a given symbol.
ranlib libmyutils.a
When you use the s flag with ar (as shown above), ranlib is run implicitly. On modern systems, ranlib is often a synonym for ar -s.
Naming Conventions
Static libraries conventionally follow these naming rules:
- The file name starts with
lib - Followed by the library name
- Followed by the
.aextension
For example, a library called myutils should be in a file named libmyutils.a. This convention is important because it allows the -l flag shorthand: -lmyutils tells the linker to look for libmyutils.a (or libmyutils.so).
Linking Against a Static Library
To link a program against your static library:
gcc main.c -L. -lmyutils -o myprogram
-L.— Add the current directory to the library search path-lmyutils— Link againstlibmyutils.a
The linker searches for libmyutils.a in the directories specified by -L flags, then in the standard library paths (/usr/lib, /usr/local/lib, etc.).
Linking Order Matters
With static libraries, the order of arguments to the linker is significant. The linker processes objects and libraries left to right. When it encounters an unresolved symbol, it looks in subsequent libraries to resolve it. If a library is listed before the object file that needs it, the symbols will not be found.
Wrong (library before object that needs it):
gcc -L. -lmyutils main.c -o myprogram # may fail
Correct (object file before library):
gcc main.c -L. -lmyutils -o myprogram # correct
If libraries depend on each other, you may need to list a library more than once, or use the --start-group/--end-group linker flags to handle circular dependencies:
gcc main.c -Wl,--start-group -la -lb -Wl,--end-group -o myprogram