Der Linking-Prozess – Statische vs. Dynamische Bibliotheken
Erstellen einer statischen und dynamischen Bibliothek
Für eine statische Bibliothek wird der Objektcode von Binärdateien (Erweiterung .o
) in einer einzigen Archivdatei mit der Erweiterung .a
zusammengefasst. Dieses Archiv ist vergleichbar mit einem Werkzeugkasten, der alle Werkzeuge enthält, die in Programmen verwendet werden können, die diese Bibliothek beim Linken aufrufen. Die Werkzeuge werden an den Stellen eingefügt, an denen sie benötigt werden. In der Abbildung unten habe ich eine Reihe von .c
-Dateien.
Da eine Bibliothek ein Archiv mit Objektcode ist, muss ich alle diese .c
-Dateien mit dem folgenden Befehl in .o
-Dateien umwandeln:
gcc -Wall -Wextra -Werror -pedantic -c *.c
Die Option -c
stoppt den Kompilierungsprozess unmittelbar vor dem Linken, nachdem Objektcodedateien erzeugt wurden. Ich habe jetzt alle Objektcodedateien:
Wenn ich den Befehl ar -rc libholbertonschool.a *.o
ausführe, kann ich diese Dateien in einer einzigen .a
Bibliotheksdatei archivieren. Der Befehl ar
dient zum Archivieren, die Option -r
zum Verschieben von Elementen mit der Erweiterung .o
und die Option -c
zum Erstellen des Archivs, wenn es noch nicht existiert. Eine Bibliotheksdatei beginnt mit einem Präfix lib
und hat die Erweiterung .a
. Der letzte Schritt, der auf manchen Systemen notwendig ist, besteht darin, den Inhalt des Archivs zu indizieren, um das Linken zu beschleunigen. Dies kann mit ranlib libholbertonschool.a
geschehen. Ich habe jetzt eine Bibliothek, die Objektcode für alle Funktionen in der obigen Abbildung enthält.
Verwendung der statischen Bibliothek
Um diese Bibliothek mit einer Testdatei zu verwenden, muss ich die Testdatei mit der Bibliothek kompilieren, indem ich einen der beiden folgenden Befehle verwende:
gcc test.c ./libholbertonschool.a -o exename
gcc test.c -L. -lholbertonschool -o exename
Beide tun dasselbe, aber der zweite ist etwas kryptischer. Die Option -L.
sucht nach Bibliotheken im aktuellen Verzeichnis und die Option -l
, die mit holbertonschool
verbunden ist, sucht implizit nach der Bibliotheksdatei, wobei ein Präfix lib
und ein Suffix .a
angenommen werden. Ohne Kompilierung mit einer Bibliotheksdatei gibt gcc
einen Fehler aus, da die Funktionen, die es zu linken versucht, nicht bereitgestellt werden. Durch die Bereitstellung einer Bibliothek bei der Kompilierung kann der Compiler nun die Bibliothek nach den benötigten Funktionen durchsuchen und sie dort einfügen, wo sie benötigt werden.
Dynamische Bibliotheken
Die Erstellung dynamischer Bibliotheken unterscheidet sich geringfügig von statischen Bibliotheken, aber die Konzepte sind im Allgemeinen die gleichen. Ich habe die gleiche Anzahl von .c
-Dateien und die Header-Datei, die ihre Prototypen in einer Datei namens lists.h
definiert.
Um die dynamische Bibliothek zu erstellen, die ein .so
(das für Shared Object steht) hat, kann der folgende Kompilierbefehl eingegeben werden:
gcc -fPIC -Wall -Werror -Wextra -pedantic *.c -shared -o libholberton.so
Das -fPIC
-Flag steht für positionsunabhängigen Code, der für das dynamische Linken erforderlich ist. Das bedeutet genau das, wonach es sich anhört – da dynamisch gelinkte Bibliotheken überall im Speicher gespeichert werden können, wo sie hinpassen, ermöglicht dieses Flag die Verwendung der Bibliotheksdatei, unabhängig davon, wo sie gespeichert ist.
Das -shared
-Flag ermöglicht die Erstellung eines gemeinsamen Archivs und die -o
-Option erlaubt es uns, die Ausgabedatei in libholberton.so
umzubenennen.
Nach der Ausführung dieses Befehls habe ich jetzt eine gemeinsame Bibliothek!