Der Linking-Prozess – Statische vs. Dynamische Bibliotheken

Okt 19, 2021
admin

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!

Verwendung der dynamischen Bibliothek

Angenommen, ich habe den folgenden Code:

#include "holberton.h"
#include <stdlib.h>
#include <stdio.h>/**
* main - check the code for Holberton School students.
*
* Return: Always EXIT_SUCCESS.
*/
int main(void)
{
printf("%d\n", _strlen("Holberton"));
return (EXIT_SUCCESS);
}

Ich kann das Programm mit dem folgenden Code kompilieren:

gcc -Wall -pedantic -Werror -Wextra -L. 0-main.c -lholberton -o len 

Gleich wie bei den statischen Bibliotheken wird mit der Option -L. das Verzeichnis nach Bibliotheksdateien durchsucht, und das -l, das am Anfang von holberton angehängt wird, ist eine implizite Suche nach Bibliotheksdateien, die ein Präfix lib, ein Suffix .so und holberton dazwischen haben.

Um die soeben erstellte Bibliotheksdatei zu verwenden, muss ich sicherstellen, dass der Compiler in der Lage ist, alle Bibliotheksdateien im Speicher zu finden, und dass sie zu Beginn ordnungsgemäß in den Speicher geladen sind. Wenn ich jetzt ldd len ausführe, kann ich folgendes sehen:

Die Zeile libholberton.so => not found sagt mir, dass die Abhängigkeit von der dynamischen Bibliothek, die ich gerade erstellt habe, nicht erfüllt ist. Um dies zu beheben, muss die Umgebungsvariable $LD_LIBRARY_PATH verstanden werden. In Linux ist diese Variable eine durch Doppelpunkte getrennte Liste von Verzeichnissen, in denen das System nach Bibliotheksdateien sucht. In der obigen Abbildung können Sie sehen, dass das Echo dieser Variable im aktuellen Zustand zeigt, dass sie leer ist und daher mein Versuch, das Programm (len) auszuführen, nicht funktioniert, weil die gemeinsame Bibliothek nicht geladen werden kann.

Mein aktuelles Verzeichnis sieht wie folgt aus:

Wie Sie sehen, befindet sich die Bibliotheksdatei im gleichen Verzeichnis wie meine Hauptdatei und die Headerdatei (aktuelles Arbeitsverzeichnis). Beachten Sie das folgende Bild:

Der Befehl export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH aktualisiert die Umgebungsvariable $LD_LIBRARY_PATH mit einem .:, das anzeigt, dass das System im aktuellen Arbeitsverzeichnis nach Bibliotheken suchen soll. Der Befehl export macht diese Änderung global, so dass jede Shell auf denselben Wert zugreifen kann. Wenn ich also ein Echo der Variable ausführe, sehe ich meine Aktualisierungen. Wenn ich ldd len erneut ausführe, sehe ich, dass sich libholberton.so an der Adresse 0x00007fb9216b9000 befindet, was wahrscheinlich sein Speicherplatz im aktuellen Arbeitsverzeichnis ist. Damit ist die Abhängigkeit der ausführbaren Datei von der gemeinsam genutzten Bibliothek erfüllt und das Programm gibt 9 zurück, was der Länge des Wortes „Holberton“ entspricht.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.