Dynamisch oder statisch linken?
« | 08 Oct 2018 | »Nachdem dieses Thema immer wieder Verwunderung auslöst, wenn ich mich offen zum statischen Linken bekenne, fasse ich mal die Details zu dieser Philosophie zusammen.
Update: Eine Anleitung zur technischen Umsetzung befindet sich nun bei den Dokus und Infos: Statisches Linken
Dynamisches Linken ist natürlich ein geniales Schema. Man erstellt geteilte Bibliotheken mit oft genutzten Funktionen, die man unter Windows als DLLs und unter Linux als SOs kennt.
Finale Programme (Executables) beinhalten dann die “Business-Logik” (oder was auch immer) und werden bei ihrer Erstellung “dynamisch” an die Bibliotheken gebunden.
Das OS liest beim Starten des Programms die “Import-Tabelle” und lädt alle verknüpften Bibliotheken in den Speicher, setzt interne Funktionszeiger “dynamisch” an die richtige Stelle und führt main() oder den definierten Einsprungpunkt aus.
Jedes moderne OS ist so aufgebaut und das ist gut so. Vorbei sind die Zeiten, wo eine Software binär auf eine Diskette geschrieben wurde und bei einem notwendigen Update das ganze Medium ausgetauscht werden musste. Nun können die Bibliotheken wie Komponenten unabhängig vom Programm ausgetauscht und aktualisiert werden. …zumindest so lange sich die exportierten Funktionen nicht ändern.
Erstellt man nun sein eigenes Programm, kann man natürlich auch so vorgehen und z.B. UI, Dateihandhabung und Kommunikation in eigene Bibliotheken auslagern.
Aber gerade beim Update schleichen sich dann gerne Problem ein. Denn wenn wir 3 DLLs und 1 EXE haben müssen die untereinander abgestimmt sein. Sobald das formale Interface zwischen diesen 4 Dateien nicht mehr stimmt (also ihre Versionen nicht zusammenpassen), ist der Absturz “vorprogrammiert”.
Beim statischen Linken entstehen ebenfalls 3 Bibliotheken, die aber beim Erstellen des Programms fest in die Programmdatei integriert werden. Versions- und Kompatibilitätsprobleme meldet der Compiler bzw. Linker, und der Entwickler muss das Problem lösen, damit er sein Programm erstellt bekommt. Am Ende erhalten wir eine Datei die als Ganzes aktualisiert werden kann. Man kann also nicht eine Bibliotheken versehentlich vergessen auszuliefern.
Die wichtigere Frage ist also eher: Ab wann ist eine Bibliothek groß, wichtig und stabil genug, dass es sich lohnt eine interne Bibliothek dynamisch zu linken.
Das GATE Framework verfolgt hier folgenden Ansatz: Unabhängigkeit ist hier die Zielsetzung und daher werden alle Bibliotheken grundsätzlich statisch kompiliert und daraus entstehende Apps sind alle Stand-Alone lauffähig.
Weitere Vorteile liegen unter anderem in der Optimierung. In einer DLL oder SO muss eine Funktion ein festes ABI einhalten und der Compiler muss sowohl beim Aufrufer als auch in der Funktion entsprechenden fixen Code generieren. Beim statischen Linken und aktivierter Link-Time-Code-Generation kann der Compiler alle Funktionsaufrufe in die Bibliothek stark optimieren und auch inline-en.
Also man merke: Niemals zeitkritische Teilfunktionen, die oft aufgerufen werden in dynamische Bibliotheken auslagern.
Nachtrag: Statisches Linken ist auch der kleinste gemeinsame Nenner zwischen unseren PCs und Mikrocontroller-Code.