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:
-
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.ogcc -c file2.c # This creates file2.o -
Step 2: Create an archive from the object files.
Use the
ar
command to create a static archive (.a
) file. Thear
utility is used to create, modify, and extract from archives in Unix-like systems.Terminal window ar rcs libmylibrary.a file1.o file2.oar
: The utility used to create and manage archives.rcs
: Flags passed toar
: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
. -
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 thelib
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 thelibmylibrary.a
library.
-
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:
gcc -c file1.c # Creates file1.ogcc -c file2.c # Creates file2.ogcc -c main.c # Creates main.o
3. Create the Archive
Create a static library (archive) with the object files:
ar rcs libhello.a file1.o file2.o
4. Link the Program with the Archive
Link the main.o
object file with the libhello.a
library to create the executable:
gcc -o myprogram main.o -L. -lhello
5. Run the Program
Run the executable:
./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:
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)
- Portability: The object files are included in the executable, so the program is self-contained. No need for external libraries at runtime.
- Efficiency: For large projects, you can avoid recompiling shared code by linking against a pre-compiled static library.
- 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
- Larger Executables: Since all the object code is copied into the executable, it will be larger compared to using dynamic/shared libraries.
- Less Flexibility: If you need to update a library, you must recompile the program with the new version of the library.
- 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:
-
Step 1: Create Object Files: First, compile your C source files into object files (
.o
files):Terminal window gcc -c file1.c # file1.ogcc -c file2.c # file2.o -
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 -
Step 3: Run
ranlib
: Now, you runranlib
on the static library to create the index:Terminal window ranlib libmylibrary.aRunning
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 GNUar
) automatically update the index when creating an archive usingar
, it’s still common practice to explicitly runranlib
to ensure that the archive contains a valid index.
Example:
-
Create Object Files:
Terminal window gcc -c file1.cgcc -c file2.c -
Create Static Library:
Terminal window ar rcs libmylibrary.a file1.o file2.o -
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:
ar rcs libmylibrary.a file1.o file2.o
The -s
option will automatically generate the index for the archive when you create it.