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:

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:

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:

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

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