Verständnisfrage: Wie spielen Compiler-, Kernel und libc-Versionen zusammen? (8.0->8.2)
Hi Leudels, ich spiel mit dem Gedanken, meine Suse 8.0 auf die 8.2 aufzurüsten. Nun habe ich schon gehört, dass so ein Update in der Regel manuelle Nacharbeiten erfordert; das wäre auch okay. In diesem Fall aber liegen zwischen den Versionen ein neuer Compiler und (nicht sicher) eine neue glibc. Laufen dann nach einem Update (manuell installierte/compilierte) Programme für die alte Distri? Ich hörte da von Problemen. Ist da was dran? Das führt mich endlich zur eigentlichen Frage: Warum spielt die Compiler-Version überhaupt eine Rolle? Sollte es nicht egal sein, mit welchem Compiler ich etwas übersetze (richtige Header/Kernel vorausgesetzt?) Gleiches gilt für die libc. Die ist doch an sich abwärts-kompatibel, oder nicht? Muss nicht ein gegen die glibc Vx compiliertes Programm auch mit der glibc Vx+1 laufen können? Und schließlich der Kernel: Warum funzt ein mit 2.4.18 kompiliertes Modul nicht mit anderen Versionen? Natürlich gibt es bei der Libc und dem Kernel so etwas wie Einsprung-Adressen für die diversen Funktionen. Gibt es da noch andere Knackpunkte? Und liegt da nicht ein fundamentaler Design-Fehler vor, wenn diese Adressen nicht fest definiert sind? Ohne dass ich es genau wüsste: Es scheint es in der MS-Welt besser gelöst zu sein: 32-Bit-Programme für Win95 funktionieren (okay, kann man drüber streiten :) auch unter Win2K - anderer Kernel, anderere Bibliotheken. Sogar manche (alle?) Treiber für Win2K arbeiten unter XP (neuerer Kernel). Warum klappt das mit dem Linux-Kernel nicht? Bin übrigens auch für einen Link dankbar (falls ich nicht fürs Lesen bereits Kernel-Hacker sein müsste :) Danke für die Erleuchtung, Alfred
Alfred Poschmann
In diesem Fall aber liegen zwischen den Versionen ein neuer Compiler und (nicht sicher) eine neue glibc.
Beides richtig.
Laufen dann nach einem Update (manuell installierte/compilierte) Programme für die alte Distri? Ich hörte da von Problemen. Ist da was dran?
Teils ja, teils nein. Dynamisch gelinkte und in C geschriebene Programme stellen kein Problem dar. In C++ geschriebene Programme und Bibliotheken *müssen* neu kompiliert werden, da sich das ABI (binäre Schnittstelle) geändert hat und diese daher nicht kompatibel zu den Bibliotheken der 8.2 sind.
Das führt mich endlich zur eigentlichen Frage: Warum spielt die Compiler-Version überhaupt eine Rolle? Sollte es nicht egal sein, mit welchem Compiler ich etwas übersetze (richtige Header/Kernel vorausgesetzt?)
Soweit sich die Definition der binären Schnittstelle (ABI) nicht ändert
sollte die Version des Compilers keine Rolle spielen. Aber in allen Fällen
wird bestenfalls eine Abwärtskompatibilität garantiert, so gut wie nie eine
Aufwärtskompatibilität.
Bei C++ sieht das anders aus. Hier gibt es einige Faktoren, welche die ABI
bestimmen. Darunter sind:
- Das Namemangling (Namensdekoration), also die Art und Weise, in
welcher der C++-Compiler den Typ des Rückgabewertes und die Typen
der Parameter zu einem Namen kombiniert. Solche Namen sehen dann in etwa
so aus:
_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwj
_ZNKSbIwSt11char_traitsIwESaIwEE16find_last_not_ofEPKwjj
Im Klartext (decodiert mit c++filt, jeweils ohne Zeilenumbruch):
std::basic_string
Gleiches gilt für die libc. Die ist doch an sich abwärts-kompatibel, oder nicht? Muss nicht ein gegen die glibc Vx compiliertes Programm auch mit der glibc Vx+1 laufen können?
Streng genommen gilt dies nur bei gleicher Hauptversion (1.X, 2.X etc.). Gerade die Programmierer der glibc legen hohen Wert auf Abwärtskompatibilität. Dafür ist aber auch ein nicht unbeträchtlicher Aufwand nötig. Wenn aber z.B. ein Programm interne Funktionen der glibc verwendet, die eigentlich *nur* innerhalb der glibc genutzt werden sollten und diese Funktionen dann wegfallen, hört das Programm auf zu arbeiten. In den aktuellen Versionen der glibc verwendet man mittlerweile Mittel, um solche Dinge nach aussen unsichtbar zu machen. Damit stehen sie ausserhalb der glibc nicht mehr zur Verfügung. Aber oft braucht man noch weitere Bibliotheken wie glib, gtk+, libpng oder libsnd, um nur einige zu nennen. Und nicht immer sind die Programmierer so sorgfältig, dass sich z.B. innerhalb der Minor-Version (die Zahl nach dem ersten Punkt) die Schnittstelle nicht ändert. Die Berkeley DB ist z.B. berüchtigt für ihre Inkompatibilitäten.
Und schließlich der Kernel: Warum funzt ein mit 2.4.18 kompiliertes Modul nicht mit anderen Versionen?
Viele Module funktionieren durchaus mit anderen Versionen, auch wenn man das Laden erzwingen muss. Aber der Kernel unterliegt immer gewissen Änderungen, da er ja kontinuierlich weiterentwickelt wird. Und wenn sich da Schnittstellen im Kernel ändern muss das Modul neu kompiliert werden.
Natürlich gibt es bei der Libc und dem Kernel so etwas wie Einsprung-Adressen für die diversen Funktionen. Gibt es da noch andere Knackpunkte? Und liegt da nicht ein fundamentaler Design-Fehler vor, wenn diese Adressen nicht fest definiert sind?
Einsprungpunkte liegen, ausser bei einem BIOS oder ähnlicher Firmware, *nie* fest. Bei dynamischen Bibliotheken hängen z.B. diese Adressen davon ab, an welche Adresse die Bibliothek geladen wird. Daher kann man mit Einsprungadressen herzlich wenig anfangen.
Ohne dass ich es genau wüsste: Es scheint es in der MS-Welt besser gelöst zu sein: 32-Bit-Programme für Win95 funktionieren (okay, kann man drüber streiten :)
Ach ja? Wo verschiedene Versionen der msvc Laufzeitbibliotheken zueinander inkompatibel sind aber gleiche Namen tragen? Treiber für Win95, die unter W2k/XP nicht mehr funktionieren? Philipp
On Sunday 25 May 2003 17:22, Philipp Thomas wrote:
Alfred Poschmann
[25 Mai 2003 13:59:58 +0200]:
Philip, erst mal Danke. War sogar zu erschöpfend geantwortet, will sagen, das zumindest diese Namensbüglerei für mich Fremdsprach ist :) [..]
Teils ja, teils nein. Dynamisch gelinkte und in C geschriebene Programme stellen kein Problem dar. In C++ geschriebene Programme und Bibliotheken *müssen* neu kompiliert werden, da sich das ABI (binäre Schnittstelle) geändert hat und diese daher nicht kompatibel zu den Bibliotheken der 8.2 sind. Dann sollte also allenfalls KDE problematisch sein, sonst programmiert ja kaum jemand in C++. Hoffe ich. Damit sollte zumindest der LTSP-Kram den Update überleben. Sonst hängt hier auch der Haussegen schief :)
Ohne dass ich es genau wüsste: Es scheint es in der MS-Welt besser gelöst zu sein: 32-Bit-Programme für Win95 funktionieren (okay, kann man drüber streiten :)
Ach ja? Wo verschiedene Versionen der msvc Laufzeitbibliotheken zueinander inkompatibel sind aber gleiche Namen tragen? Treiber für Win95, die unter W2k/XP nicht mehr funktionieren?
Die DLL-Hölle ist unbestritten, kommt aber auch nicht bei so vielen Leuten zum Tragen. Ausserdem habe ich beim Schreiben der Mail nicht bedacht, dass unter Windows viel mehr statisch gelinkt wird. Das ist wohl ein Nachteil, wenn man sich weiterbildet - man stößt auf einmal auf Probleme, die man früher mangels Übersicht nicht (bemerkt) hatte :) Nochmals Danke, Alfred (der sich wohl in der nächsten ruhigen Stunde an den Update macht)
participants (2)
-
Alfred Poschmann
-
Philipp Thomas