Was macht es beispielsweise für den visuellen C ++ - Compiler unter Windows schwierig, eine ausführbare Linux-Binärdatei zu generieren?
Abgesehen von der mangelnden Bereitschaft von Microsoft, dies zu tun, absolut nichts. Die Hindernisse sind nicht technisch.
Entwicklungs-Toolchains sind nur Programme, die Input nehmen und Output produzieren. Visual C ++ erstellt eine x86-Assembly und konvertiert diese dann mithilfe eines Assemblers in eine COFF-Objektdatei. Wenn Microsoft stattdessen ELF generieren möchte, ist es nur Code: Assembly kommt herein, ELF geht raus. Objektdateien oder Bibliotheken sind nichts Magisches. Sie sind nur Datenblobs in einem gut verstandenen Format.
In der Steinzeit war die Kreuzkompilierung viel schwieriger, da Sie häufig die Werkzeugkette für Ihre Zielplattform in Montage für die Plattform geschrieben hätten, auf der sie ausgeführt werden sollte. Dies bedeutete, dass, wenn es auf der Welt nur die VAX-, M68K- und Alpha-Architekturen gäbe, für eine vollständige Suite von Cross-Compilern neun davon geschrieben werden müssten, meistens von Grund auf neu. (VAX-zu-VAX, VAX-zu-M68K, VAX-zu-Alpha, M68K-zu-VAX, M68K-zu-M68K usw.) Das ist etwas übertrieben, da Teile des VAX-Compilers wiederverwendet werden könnten und an Codegeneratoren für jedes Ziel angehängt (z. B. VAX, M68K und Alpha, jeweils für VAX geschrieben).
Dieses Problem verschwand, als wir anfingen, Compiler in einer Sprache zu schreiben, die nicht an einen bestimmten Prozessor gebunden war, wie z. B. C. Wenn Sie diesen Weg gehen, schreiben Sie die gesamte Toolchain einmal in C und verwenden eine für die lokale Plattform geschriebene C-Compiler zum Erstellen. (Sie haben den Compiler häufig verwendet, um sich selbst neu zu kompilieren, nachdem er auf dem Compiler der lokalen Plattform gebootet wurde. Dies ist jedoch eine weitere Diskussion.) Das Ergebnis ist, dass das Erstellen eines Cross-Compilers im Wesentlichen den gleichen Aufwand darstellt wie das Erstellen eines nativen Compilers die lokale Plattform. Der einzige signifikante Unterschied besteht darin, dass Sie irgendwo im Erstellungsprozess angewiesen haben, im Codegenerator für Ihre Zielplattform anstelle des für die lokale Plattform zu kompilieren, was die logische Wahl gewesen wäre.
Als sich die Architektur der Compiler weiterentwickelte, wurde es bequem, einfach alle Codegeneratoren in das Produkt einzubeziehen und zu erstellen und auszuwählen, welcher zur Laufzeit verwendet wird. Clang / LLVM macht das und ich bin mir sicher, dass es noch andere gibt.
Sobald Sie über eine funktionierende Toolchain (Compiler, Assembler, Linker) verfügen, werden Bibliotheken aus Quellen erstellt, und Sie erhalten schließlich alles, was Sie zum Erstellen einer ausführbaren Datei für eine andere Plattform benötigen.