libfoo.so.major.minor.
Wenn du ein Programm verlinkst, bettet der Linker ld diese
Information in die erzeugte Binary. Du kannst sie mit ldd
sehen.
Später, wenn du das Programm ausführst, verwendet der dynamische Linker
ld.so diese Information, um die richtige dynamische
Bibliothek zu finden:
Die Regeln für Shared Librarys sind recht einfach.
Ab und zu kann es vorkommen, dass eine Bibliothek in mehrere Dateien geschrieben wird und dass interne Funktionen sichtbar sind, damit sie zwischen jenen Dateien kommunizieren können. Solche Funktionsnamen beginnen üblicherweise mit einem Unterstrich und sind kein ordentlicher Teil der API.
Bedenke, dass das Bibliotheks-Namensschema allgegenwärtig auf OpenBSD-Plattformen ist, gleich, ob sie ELF oder a.out verwenden.
gcc -shared -fpic|-fPIC -o libfoo.so.4.5 obj1 obj2
erfolgen sollte.
Zu versuchen, die Bibliothek nach der Erzeugung umzubenennen, um so die Versionsnummer anzupassen, funktioniert nicht: ELF-Bibliotheken verwende einige extra ,magic', um den bibliotheksinternen Namen zu setzen, sodass du sie mit der korrekten Version gleich beim ersten Mal richtig linken musst.
Auf der anderen Seite musst du bedenken, dass du Makefile-Variablen
von der Kommandozeile aus überschreiben kannst, indem du
MAKE_FLAGS in dem Makefile des Ports verwendest.
Dies ist recht nützlich, zum Beispiel, in den libtool-basierten
Ports, welche eine solche Versionsvariable für jede einzelne
Bibliothek, die sie erzeugen, benutzen.
Libtool-basierte Ports kann man am besten verarbeiten, wenn
USE_LIBTOOL=Yes gesetzt wurde. Hiermit wird die
Portstree-Version von libtool aktiviert, wodurch die meisten
Details automatisch abgearbeitet werden:
SHARED_LIBS und ersetzt
automatisch Versionsnummern.
${WRKBUILD}/shared_libs.log,
die direkt in das Makefile des Ports eingebunden werden kann.
ld die
-L-Optionen, um einen Pfad einzurichten, in dem nach
Bibliotheken gesucht wird. Es hört auf zu suchen, sobald es eine
Bibliothek findet, die die Voraussetzungen erfüllt.
ld.so die
Informationen, die durch ldconfig ge,cached' wurden, um
die benötigte Bibliothek zu finden.
qt.1.45
und qt.2.21. Da beide Ports gleichzeitig installiert
werden können, stelle sicher, dass ein gegebenes Programm gegen
qt.1-Bibliothek gelinkt wird, welche als
/usr/local/lib/qt/libqt.so.1.45 vorliegt, und Programme
unter Verwendung von ld -o program program.o -L/usr/local/lib/qt
-lqt gelinkt werden. Ähnlich soll ein Programm, das mit qt.2
linkt, die /usr/local/lib/qt2/libqt.so.2.31-Datei
nutzen und mit ld -o program program.o -L/usr/local/lib/qt2
-lqt gelinkt werden.
Um diese Bibliotheken zur Laufzeit aufzulösen, wurden eine Verknüpfung
mit dem Namen /usr/local/lib/libqt.so.1.45 und eine
Verknüpfung namens /usr/local/lib/libqt.so.2.31
bereitgestellt. Dies ist genug, um ld.so glücklich zu
machen.
Es ist ein Fehler, ein Programm unter Verwendung von qt1 mit
ld -o program program.o -L/usr/local/lib -lqt zu linken.
Dieser Code nimmt an, dass qt.2.21 nicht installiert sei,
was eine Fehlannahme ist.
Solche Tricks sind nur notwendig, wenn der seltene Fall von sehr
weitverbreiteten Bibliotheken vorliegt, bei denen Übergangszeiten
zwischen Hauptversionen bereitgestellt werden müssen. Generell gilt,
dass es genug ist, sicherzustellen, dass eine Bibliothek in
/usr/local/lib auftaucht.
make lib-depends-check
verwenden, um sicherzustellen, dass ein Port alle Bibliotheken
angibt, auf die er aufbaut. Du trennst Bibliotheksangaben mit Kommata,
wie hier:
LIB_DEPENDS=gtk.1.2,gdk.1.2::x11/gtk+.
Es ist kein Fehler, statische Bibliotheken in einer LIB_DEPENDS-Zeile
ebenfalls anzugeben. LIB_DEPENDS werden während der Erzeugungsphase
des Packages vollständig verarbeitet: das resultierende Package wird
eine Bibliotheksabhängigkeitsinformation als Zeilen für
ld.so eingebettet haben, die die tatsächliche
Haupt.Unter-Nummer beinhalten, die beim Erzeugen verwendet wurden und
keine Einträge für statische Bibliotheken.
Du musst ebenfalls RUN_DEPENDS bereitstellen, wenn ein Ports irgendetwas ordentlich benötigt, das über Bibliotheken hinausgeht. Das erlaubt dem Port auf Architekturen ordnungsgemäß erzeugt werden zu können, die keine Shared Librarys bereitstellen.
In der Tat ist das Bereitstellen einer LIB_DEPENDS-Zeile für statische Bibliotheken eine gute Idee: das vereinfacht einen Portupgrade, wenn eine gegebene Abhängigkeit von einer statischen Bibliothek zu einer Shared Library wechselt.
LIB_DEPENDS-Zeilen müssen die gleichen Pfade angeben, die für
ld genutzt werden. Zum Beispiel basiert das standardmäßige
qt2 auf einem Fragment, das sagt:
LIB_DEPENDS+=lib/qt2/qt.2::x11/qt2, sodass die
Bibliotheksabhängigkeitszeile korrekt aufgelöst wird. Dies erlaubt
dem Abhängigkeitsüberprüfungscode das richtige zu tun, wenn er mehreren
Versionen der gleichen Bibliothek begegnet.