Vielleicht ist es ganz gut hier für das allgemeine Verständnis und äh "Archivzwecke" mal etwas in die Grundlagen auszuholen: Auch wenn C und C++ sich über die Jahre auseinanderentwickelt haben, ist das Prinzip in Sachen Toolchain immer noch weitgehend gleich. Und auch wenn es kleinere Differenzen gibt, sind die meisten real existierenden C-Programme noch immer valide C++-Programme. Wenn man C zum laufen hat, funktioniert daher meist auch C++. Und umgekehrt.
Nun braucht man in einer "gehosteten" Umgebung - das sind alle Umgebungen mit richtigem Betriebssystem und dadurch einer einer recht hohen Abstraktion von der Hardware - mindestens 3 Dinge:
Unter unixoiden Systemen ist das nun alles relativ einfach. Das System selbst stellt eine C Standardbibliothek und Systembibliothek zur Verfügung, die reinen C-Compiler sind damit glücklich. Für C++ wird in der Linux-Welt meist GCCs libstdc++ genutzt, Apple und die BSDs nutzen für Clang die libc++ des LLVM-Projektes und für GCC die der jeweiligen Version zugehörige libstdc++. Unter Windows ist es aber etwas fummeliger. Windows selbst bringt lediglich eine C89-Standardbibliothek mit, die für praktisch nichts ausreichend ist. Man hat daher zwei Möglichkeiten:
Das ist nun alles recht oberflächlich, aber es hilft hoffentlich zum Verständnis. Es ist sehr zu empfehlen sich auch noch mal mit den unterschiedlichen Binärformaten zu beschäftigen. Das unter unixoiden inzwischen meist verwendete ELF, Apples Mach-O und Windows PE-COFF unterscheiden sich konzeptionell schon sehr. Vor allem bei Bibliotheken, eine Windows .dll ist ein komplett anderes Konzept als eine Unix .so.
Nun braucht man in einer "gehosteten" Umgebung - das sind alle Umgebungen mit richtigem Betriebssystem und dadurch einer einer recht hohen Abstraktion von der Hardware - mindestens 3 Dinge:
- Eine Toolchain. Die besteht mindestens aus einem Compiler, der den Quelltext über mehrere Schritte hinweg in Assembler übersetzt. Dann einem Assembler, der daraus Objektdateien erzeugt. Und schließlich den Linker, der die Objektdateien zu dem Programm zusammenfügt. Die einzelnen Schritte können beliebig implementiert sein. Es kann ein großes Programm sein, oder auch verschiedene einzelne Programme. Oft hat man einen sogenannten "Driver", das ist ein kleines Wrapper-Programm, was die einzelnen Teile der Toolchain wie benötigt aufruft. Die drei großen Implementierungen sind:
- Die GNU Compiler Collection in Kombination mit dem GNU Binutils: Der Klassiker, gibt es schon ewig. Implementiert diverse Sprachen, bringt hochqualitative Assembler, mehrere Linker und jede Menge sonstiger Tools mit.
- Microsoft Visual C++ aka MSVC, der Compiler selbst heißt "cl.exe": Für C etwas das ungeliebte Stiefkind, da Microsoft irgendwann in den 1990ern das Interesse an C verloren hat. Für C++ nach einem Durchhänger in den 2000ern aber wieder top. Kann allerdings nur für Windows bauen und ist zur GCC subtil inkomaptibel.
- Clang: Auf LLVM basierend, ursprünglich vor allem von Apple aus Ärger über die geringe Kooperationsbereitschaft der GCC-Entwickler und die GPLv3 ins Leben gerufen. Am Anfang nur ein Compiler, implementiert das LLVM-Projekt inzwischen die ganze Toolchain. Clang kann sich mit GCC und MSVC kompatibel verhalten (sowohl in Sachen Code als auch Aufruf) und auf Wunsch sowohl die GNU- als auch die MSVC-Assembler und Linker benutzen.
- Eine Bibliothek. Für C eine Implementierung der C Standardbibliothek und für C++ eine Implementierung der C++ Standardbibliothek. Sie sind meisten verknüpft, die C++ Bibiliothek braucht eine C Bibliothek. Neben den Bibliotheksfunktionen, Klassen und Datentypen implementieren die Bibliotheken meist auch Startup-Code (also grob alles, was vor dem Aufruf von main() ausgeführt wird) und im Falle von C++ weiteren Supportcode für Laufzeitfunktionalität. Die Bibliotheken sind daher gerade im Fall von C++ mit der Toolchain verknüpft und nicht ohne weiteres austauschbar.
- Eine Systembibliothek. Das sind Funktionen, Datentypen und Interfaces um mit dem Betriebssystem zu interagieren. Unter unixoiden Systemen ist dies vor allem der unistd.h Header unter Windows der windows.h Header. Die Bibliotheken können eigenständig sein, sind aber in der Praxis meist eng mit der C Standardbibliothek verknüpft.
Unter unixoiden Systemen ist das nun alles relativ einfach. Das System selbst stellt eine C Standardbibliothek und Systembibliothek zur Verfügung, die reinen C-Compiler sind damit glücklich. Für C++ wird in der Linux-Welt meist GCCs libstdc++ genutzt, Apple und die BSDs nutzen für Clang die libc++ des LLVM-Projektes und für GCC die der jeweiligen Version zugehörige libstdc++. Unter Windows ist es aber etwas fummeliger. Windows selbst bringt lediglich eine C89-Standardbibliothek mit, die für praktisch nichts ausreichend ist. Man hat daher zwei Möglichkeiten:
- Man nutzt die zu MSVC gehörenden Bibliotheken. Das macht logischerweise MSVC selbst, sowie optional Clang für Windows. Der Vorteil ist, dass man durch Microsofts Bibliotheken die bestmögliche Integration in Windows erreicht. Der Nachteil ist, dass man die Bibliotheken mit seiner Anwendung ausliefern muss. Das ist das berüchtigte "Visual C++ Redistributable" Paket, was zu jedem zweiten Programm installiert wird und wo von sich mit der Zeit etliche Versionen im System ansammeln.
- MinGW in seinen diversen Geschmacksrichtungen hat einen Wrapper über Windows C89-Standardbibliothek geschrieben, auf dem eine angepasste und zu C99 kompatible C-Standardbibliothek und GCCs libstdc++ aufsetzen. GCC nutzt diese, Clang kann sie optional nutzen. Der Vorteil ist, dass man zu Linux sehr ähnliche Bibliotheken (und damit geringen Portierungsaufwand) bekommt. Außerdem muss man kein zusätzliches Paket mit Bibliotheken ausliefern. Der Nachteil ist die vergleichsweise schlechte Integration in Windows, es fühlt sich irgendwie immer wie ein Fremdkörper an.
Das ist nun alles recht oberflächlich, aber es hilft hoffentlich zum Verständnis. Es ist sehr zu empfehlen sich auch noch mal mit den unterschiedlichen Binärformaten zu beschäftigen. Das unter unixoiden inzwischen meist verwendete ELF, Apples Mach-O und Windows PE-COFF unterscheiden sich konzeptionell schon sehr. Vor allem bei Bibliotheken, eine Windows .dll ist ein komplett anderes Konzept als eine Unix .so.