Skip to content

4.2 Static Libraries

1. What are Archives in C?

In the context of C programming, an archive typically refers to a static library (also known as an archive file) that contains object files. These object files are the compiled versions of source code files (.c files) and are used to create executable programs.

An archive is a collection of object files (.o files), and the archive file has a .a extension in Unix-like systems (e.g., Linux or macOS). The archive allows multiple object files to be grouped into one file, making it easier to link them with your program.

1.1 What is an Archive (Static Library)?

  • An archive is a static library that groups several object files together into one file. When linking a program, the linker can access the object files from the archive, linking them into the executable as needed.
  • Static libraries are linked at compile-time. The library’s object code is included in the final executable, making the executable larger but self-contained.

1.2 Why Use Archives (Static Libraries)?

  • Modularity: You can divide your code into smaller pieces (e.g., different .c files), compile them into object files, and then combine them into a single archive file. This makes managing code easier.
  • Reusability: The same archive can be linked with multiple programs without having to recompile the object files each time.
  • Faster Linking: Instead of compiling and linking each .c file into the final executable separately, you compile once and link against the static library, which can be faster.

1.3 How to Create an Archive (Static Library)?

Here are the steps to create and use a static archive (library) in C:

  1. Step 1: Compile the source files into object files (.o files).

    To create an object file from a C source file, you can use the gcc compiler with the -c flag:

    Terminal window
    gcc -c file1.c # This creates file1.o
    gcc -c file2.c # This creates file2.o
  2. Step 2: Create an archive from the object files.

    Use the ar command to create a static archive (.a) file. The ar utility is used to create, modify, and extract from archives in Unix-like systems.

    Terminal window
    ar rcs libmylibrary.a file1.o file2.o
    • ar: The utility used to create and manage archives.
    • rcs: Flags passed to ar:
      • r: Replace or add object files into the archive.
      • c: Create the archive if it doesn’t exist.
      • s: Create an index (symbol table) for the archive, improving lookup performance when linking.
    • libmylibrary.a: The archive file being created.
    • file1.o file2.o: The object files to include in the archive.

    After this command, you’ll have a static library named libmylibrary.a.

  3. Step 3: Link the archive with your program.

    When you compile your program, you can link it with the static library using the -l flag followed by the library name (without the lib prefix and .a suffix):

    Terminal window
    gcc -o myprogram myprogram.c -L. -lmylibrary
    • -L.: This tells the linker to look in the current directory for libraries.
    • -lmylibrary: This links against the libmylibrary.a library.
  4. Step 4: Run your program.

    After linking, you can run your program as usual:

    Terminal window
    ./myprogram

1.4 Example of Creating and Using an Archive:

1. Source Files

file1.c:

#include <stdio.h>
void hello() {
printf("Hello from file1!\n");
}

file2.c:

#include <stdio.h>
void world() {
printf("Hello from file2!\n");
}

main.c:

#include <stdio.h>
void hello();
void world();
int main() {
hello();
world();
return 0;
}

2. Compile the Source Files

Compile each source file into an object file:

Terminal window
gcc -c file1.c # Creates file1.o
gcc -c file2.c # Creates file2.o
gcc -c main.c # Creates main.o

3. Create the Archive

Create a static library (archive) with the object files:

Terminal window
ar rcs libhello.a file1.o file2.o

Link the main.o object file with the libhello.a library to create the executable:

Terminal window
gcc -o myprogram main.o -L. -lhello

5. Run the Program

Run the executable:

Terminal window
./myprogram

Output:

Hello from file1!
Hello from file2!

1.5 How to Extract Files from an Archive

To extract object files from an archive, you can use the ar command with the x option:

Terminal window
ar x libhello.a

This will extract the object files from the archive (libhello.a) into the current directory.

1.6 Advantages of Static Libraries (Archives)

  1. Portability: The object files are included in the executable, so the program is self-contained. No need for external libraries at runtime.
  2. Efficiency: For large projects, you can avoid recompiling shared code by linking against a pre-compiled static library.
  3. Faster Execution: Static linking generally leads to faster program execution because all the code is bundled into the executable.

1.7 Disadvantages of Static Libraries

  1. Larger Executables: Since all the object code is copied into the executable, it will be larger compared to using dynamic/shared libraries.
  2. Less Flexibility: If you need to update a library, you must recompile the program with the new version of the library.
  3. Redundancy: If you use the same static library in multiple programs, each program will contain a copy of the library code, leading to redundant storage usage.

2. What is ranlib?

ranlib is a utility in Unix-like systems (such as Linux and macOS) that is used to generate an index (symbol table) for a static archive file (a .a file). The index helps the linker quickly locate symbols (such as functions and variables) in the static library when linking a program.

2.1 Why Do We Need ranlib?

When you create a static archive using the ar command (e.g., libmylibrary.a), the archive contains object files but does not initially have an index or a symbol table. This means that the linker has to search through the entire archive file to find the needed object files when performing the final linking. This can make the linking process slower.

To speed up the linking process, ranlib creates an index of all the symbols in the archive. This symbol table allows the linker to quickly find which object files in the archive contain the necessary code, improving linking efficiency.

2.2 How to Use ranlib?

After creating a static library (archive file) using the ar command, you typically run ranlib on the archive to generate the index.

Example of Creating and Indexing a Static Library:

  1. Step 1: Create Object Files: First, compile your C source files into object files (.o files):

    Terminal window
    gcc -c file1.c # file1.o
    gcc -c file2.c # file2.o
  2. Step 2: Create a Static Library (Archive): Use the ar command to bundle the object files into a static library:

    Terminal window
    ar rcs libmylibrary.a file1.o file2.o
  3. Step 3: Run ranlib: Now, you run ranlib on the static library to create the index:

    Terminal window
    ranlib libmylibrary.a

    Running ranlib will create a symbol table within the archive, allowing the linker to perform more efficiently when linking programs with this library.

2.3 How Does ranlib Work?

  • Symbol Table: ranlib generates a symbol table (an index) of all the symbols in the archive. A symbol table contains entries for each symbol in the archive, which can be a function name, variable, etc.

  • Efficiency: The linker can use this index to quickly locate object files that contain the symbols it needs to link into the executable. Without the symbol table, the linker would need to scan the entire archive file, which is slower.

  • Why Run ranlib: While some systems (e.g., modern versions of GNU ar) automatically update the index when creating an archive using ar, it’s still common practice to explicitly run ranlib to ensure that the archive contains a valid index.

Example:

  1. Create Object Files:

    Terminal window
    gcc -c file1.c
    gcc -c file2.c
  2. Create Static Library:

    Terminal window
    ar rcs libmylibrary.a file1.o file2.o
  3. Run ranlib:

    Terminal window
    ranlib libmylibrary.a

This creates the archive libmylibrary.a with an index, making it ready for efficient linking.

2.4 Do You Always Need to Run ranlib?

In some cases, modern versions of the ar command automatically generate the symbol table when you create the archive using the ar command (if the -s option is used). However, running ranlib explicitly can still be a good practice, especially for compatibility with older systems or when you want to ensure the archive is properly indexed.

Example with ar -s (Auto-symbol Table):

Instead of manually running ranlib, you can create the archive and generate the symbol table in one step with ar by using the -s option:

Terminal window
ar rcs libmylibrary.a file1.o file2.o

The -s option will automatically generate the index for the archive when you create it.