Betrifft OS:
DragonFlyBSDFreeBSDNetBSDOpenBSD

statisches / dynamisches Linken

Ein Programm, dass auf einer Bibliothek basiert, muss nicht unbedingt fest mit dieser verbunden sein. Der Trick heißt „run -time link-editor“ oder kurz rtld(1).

Grundsätzlich gibt es zwei Arten ein Programm und seine Bibliotheken zusammenzufügen.

  1. statisches Linken
  2. dynamisches Linken

statisches Linken

Dabei setzt der Link Editor ld(1) nach dem Compilen das Programm und die Bibliothek fest und untrennbar zusammen. Statisch halt.

Vorteile

Das hat gewisse Vorteile, wie zum Beispiel das das Programm keine oder nur sehr wenige Abhängigkeiten hat. Kommerzielle Programme werden daher meist statisch gelinkt. Da alle Abhängigkeiten eingebaut sind, musst du dich nicht um sie kümmern, du hast keine Probleme sie zu erfüllen.

Nachteile

Es hat aber auch gravierende Nachteile. Sehr hoher Speicherplatzverbrauch, jede Bibliothek ist in jedes Programm was sie braucht eingebaut und entsprechend oft auf der Platte vorhanden. Stelle dir mal vor, wenn jedes GTK-Programm GTK fest drin hätte. Das wären etliche Megabytes. Außerdem auch hoher Arbeitsspeicherverbrauch, aber das würde nun zu weit führen. Daher hat man die andere Methode erfunden, das dynamische Linken.

dynamisches Linken

Dabei sieht der ld(1) nach dem Compilen nur vor, was an Bibliothken gebraucht wird, fügt sie aber nicht ein. Stattdessen vermerkt er nur den Namen der Bibliothek. Wenn du das Programm startest, kommt rtld(1) ins Spiel. Das „rt“ steht wie oben gesagt für „run time“. Er nimmt dein Programm, schaut nach welche Bibliotheken dort vermerkt sind, lädt sie dynamisch nach und bindet sie ein. Diese dynamisch einzubindenden Bibliotheken enden auf „.so“. In der Praxis wird fast immer dynamisch gelinkt. Das führt zu den Abhängigkeiten. Angenommen, dein Programm braucht libiconv.so. Dann kann es nur funktionieren, wenn auf deinem System eine libiconv ist. Daher ist in den Ports eine Abhängigkeit von deinem Programm auf libiconv vermerkt.

Vorteile

Einmal, die Speicherplatzersparnis. Aber auch Unabhängigkeit. Dazu gleich mehr.

Nachteile

Die Bibliotheken müssen vorhanden sein. Das sicherzustellen, geht praktisch nur mit einem ausgereiften Paketmanament wie den Ports oder Debians dpkg. Microsoft ist mit diesem Problem ziemlich auf die Nase gefallen, dass war nämlich die „DLL Hölle“ früherer Windows-Versionen. Eine „.dll“ ist vom Prinzip her nichts anderes als eine „.so“.

Abhängigkeiten zwischen Programmen und Bibliotheken am Beispiel von libiconv

Nun zur Unabhängigkeit. Wenn du libiconv nach einer Sicherheitslücke neubaust, erhältst du eine neue libiconv.so ohne die Lücke. Sobald du das Programm was sie nutzt neu startest, wird es vollautomatisch mit dieser neuen libiconv.so verbunden, hat die Lücke also auch nicht mehr. Du musst daher alles, was auf libiconv basiert nur neu starten, aber nicht neu bauen. Ich habe mir daher angewöhnt, nach Portupgrades grundsätzlich einmal aus- und anschließend wieder einzuloggen, um sicher zu sein, dass alles neu gestartet wurde. Wer ganz sicher sein will, startet die ganze Kiste neu oder geht einmal in den Singleuser Mode und wieder zurück. Problematisch ist nur, wenn sich die Schnittstelle der Bibliothek ändert, so gerade erst am Wochenende geschehen. libjpeg wurde aktualisiert, die neue Bibliothek war mit der alten inkompatibel, da man ihre Schnittstelle geändert hatte. Alte Programme konnten also mit der neuen libjpeg.so nicht mehr verbunden werden. Daher musstest du alles neubauen, was auf libjpeg basierte, damit die Programme die Schnittstelle bekamen. Diese Schnittstellen werden mit einen kleinen Trick sichtbar gemacht:

lrwxr-xr-x   1 root  wheel        13  6 Feb 09:54 libjpeg.so -> libjpeg.so.11
-rwxr-xr-x   1 root  wheel    244471  6 Feb 09:54 libjpeg.so.11
Bibliotheken bekommen ihre Versionsnummer in den Namen. Sie heißt „.so.11“, also elfte Version der Schnittstelle. Man erstellt dann einen Symlink auf diese Datei, der nur auf „.so“ endet. Den sehen die Programme. So ist am Namen der Blibiothek sichtbar, was da eigentlich installiert ist. Hättest du nur libjpeg aktualisiert, aber die Programme darauf nicht, hätte er sowas wie „libjpeg.so.10 not found“ gesagt und sich beendet, da er eben die Schnittstelle in Version 10 bräuchte, du aber durch das Update Version 11 hast.

Zusammenspiel mit portupgrade

Immer wenn sich die Schnittstelle einer Bibliothek ändert, werden inzwischen die Versionsnummern aller Ports, die diese Bibliothek brauchen, erhöht. Dadurch weiß Portupgrade, dass es all diese neu bauen muss und macht es automatisch. Früher tat man das nicht, da musste man dann wirklich mit -r bei.

Quelle: http://www.bsdforen.de/showthread.php?p=208571#post208571