Skip to content

Intermediate · The preprocessor, multi-file programs and make · topic 40 of 60 · 25 min

Libraries: static and shared

Explanation

A library packages compiled code for reuse. A static library (libx.a, made with ar) is copied into each executable at link time. A shared library (libx.so on Linux, .dll on Windows, .dylib on macOS) is loaded at run time and shared between programs. Link with -I (header folders), -L (library folders) and -lname (the library), for example -lm for the math library.

Header plus library equals an API

To use someone else's C code you need two things: the header (.h) with the declarations, so your code compiles, and the library with the compiled machine code, so it links. The standard C library (printf, malloc, strlen) is linked automatically; others must be named on the command line.

c
#include <math.h>
double r = sqrt(2.0);
On Linux, link the math library explicitly: gcc prog.c -o prog -lm

Linker flags

FlagMeaningExample
-I dirAlso search dir for #include files-I include
-L dirAlso search dir for libraries-L lib
-lnameLink libname.a or libname.so-lm, -lpthread, -lsqlite3
bash
gcc -std=c17 -Wall -I include src/app.c -L lib -lgst -o app
Place -l options AFTER the source or object files that use them; the linker resolves left to right.

Making a static library

bash
gcc -std=c17 -Wall -c tax.c money.c      # → tax.o money.o
ar rcs libbilling.a tax.o money.o         # archive them into a static library
gcc main.c -L. -lbilling -o app           # link: the needed code is COPIED into app
ar rcs = replace/insert files, create the archive, write an index.

Making a shared library (Linux)

bash
gcc -std=c17 -Wall -fPIC -c tax.c money.c   # position-independent code
gcc -shared -o libbilling.so tax.o money.o   # build the shared library
gcc main.c -L. -lbilling -o app              # link against it
LD_LIBRARY_PATH=. ./app                      # tell the loader where to find it at run time
Static (.a / .lib)Shared (.so / .dll / .dylib)
When code is attachedAt link time, copied into the executableAt run time, loaded by the system
Executable sizeBiggerSmaller
Updating the libraryRelink every programReplace one file (if compatible)
DeploymentOne self-contained fileLibrary must be present on the machine
Memory with many programsEach has its own copyOne copy shared in memory
Careful: With shared libraries, the program may build fine but fail to START: "error while loading shared libraries: libbilling.so: cannot open shared object file". The run-time loader cannot find the .so; install it in a system folder, set LD_LIBRARY_PATH for testing, or embed a run path (-Wl,-rpath). Also keep the library's interface (ABI) compatible when updating it, or old programs may crash.

Libraries you will meet

  • libm (math), libpthread (threads; part of glibc in recent versions), libdl (dynamic loading).
  • SQLite, zlib (compression), OpenSSL (cryptography), libcurl (HTTP), cJSON (JSON).
  • On embedded systems: vendor HALs (hardware abstraction layers) and RTOS kernels such as FreeRTOS.
Think of it like this: A static library is like photocopying the chapters you need into your own notebook: your notebook works anywhere, but it gets thicker and does not see later corrections. A shared library is like a reference book kept in the library hall: everyone reads the same copy, corrections help everyone at once, but you must be able to reach the hall.
Tip: ldd ./app (Linux) lists the shared libraries a program needs and where the loader finds them; nm -D libx.so lists the functions a shared library exports.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Libraries: static and shared · 1/6

Libraries

In this lesson you will use and build C libraries.

Prefer a video by a teacher? Find free videos on “c static library vs shared library ar gcc -shared fpic linking” on YouTube ↗

In real life: Using SQLite in a C program

A small inventory tool for a hardware shop stores its data in SQLite. The developer installs the SQLite development package (sudo apt install libsqlite3-dev), includes <sqlite3.h> and links with -lsqlite3. The tool then reads and writes a single database file with SQL.

c
#include <sqlite3.h>
#include <stdio.h>

int main(void) {
    sqlite3 *db;
    if (sqlite3_open("shop.db", &db) != SQLITE_OK) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); return 1; }
    sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS item(name TEXT, qty INTEGER);", NULL, NULL, NULL);
    sqlite3_close(db);
    return 0;
}
/* gcc shop.c -o shop -lsqlite3 */

Practice (0/3 done)

Task 1 · Question

The program builds but at start says "error while loading shared libraries: libgst.so: cannot open shared object file". What is wrong?

Task 2 · Question

Which command creates a static library from tax.o and money.o?

Task 3 · Practice

Turn your money module into both a static library (libmoney.a) and a shared library (libmoney.so). Link one program against each, compare the executable sizes with ls -l, run the shared version (setting LD_LIBRARY_PATH if needed), and use ldd to see which libraries each executable needs.

Quick quiz

Question 1

1.Which flag links the math library on Linux?

Question 2

2.When is the code of a static library added to a program?

Question 3

3.What is the main advantage of shared libraries?

Question 4

4.What does -I include do?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

Which flag links the math library on Linux?

Answer: -lm

The library is libm.

When is the code of a static library added to a program?

Answer: At link time

It is copied into the executable.

What is the main advantage of shared libraries?

Answer: One copy shared by many programs, and updates without relinking

Smaller executables and shared memory.

What does -I include do?

Answer: Adds the include folder to the header search path

For finding .h files.

What does extern int count; in a header mean?Related

Answer: count is defined in some .c file; this just declares it

A declaration without storage.

From Splitting a program into files

Which flag asks the compiler to optimise the program for speed?Related

Answer: -O2

-O2 (capital letter O) turns on optimisation. Lowercase -o names the output file.

From What C++ is and how compiling works

Does cross-compiling prove your program works on the target system?Related

Answer: No, you still need to run and test it there

Building and running are different things.

From Cross-compiling and build flags

Why is main declared static?Related

Answer: So the JVM can call it without creating an object

No object exists when the program starts.

From static members and final

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. This is the last topic of “The preprocessor, multi-file programs and make”. The module exam comes next.
  2. Module 8 exam: Preprocessor, multi-file programs and make · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Bits, undefined behaviour and safety. 60 topics left in the course before the final exam.

← Previous: Building with make