Warum generieren Compiler normalerweise nur ausführbare Dateien für die Plattform, auf der sie installiert sind?

10

Ich bin ein C ++ - Entwickler und versuche, die plattformübergreifende Entwicklung besser zu verstehen. Ich versuche, einige Implementierungsdetails von Compilern und deren genaue Erstellung betriebssystemspezifischer Binärdateien besser zu verstehen. Während meiner Studie wurde mir klar, dass die meisten Compiler, die Sie für eine bestimmte Plattform heruntergeladen haben, zumindest für eine Weile nur Binärdateien für diese Plattform kompiliert haben. Wenn Sie also eine IDE heruntergeladen haben, die mit einer Compiler-Exe für Windows geliefert wurde, kann dieser Compiler Ihr Programm nur für x86-x64-Windows-Anwendungen und nicht für Linux- oder Mac-Anwendungen kompilieren.

Jetzt verstehe ich, dass verschiedene Plattformen unterschiedliche Binärformate erfordern, aber was macht es beispielsweise für den visuellen C ++ - Compiler unter Windows schwierig, eine ausführbare Linux-Binärdatei zu generieren? Sollten Sie nicht in der Lage sein, exectuables für jede Plattform auf einem beliebigen Computer zu kompilieren, solange Sie die Montageanweisungen für die CPU haben, auf der Sie ausgeführt werden, sowie die betriebssystemspezifischen Bibliotheken?

Jason
quelle
5
Es gibt viele Cross-Compiler: Ich bin mir nicht sicher, warum Sie Cross-Compiling für ungewöhnlich halten. Visual C ++ ist sinnvoll, da Microsoft Windows sperren möchte, aber in VS2017 sogar Android-Compiler-Tools bereitstellt.
Nun, viele andere Websites schienen es so zu machen, als sei ein Cross-Compilation-Compiler sehr schwierig zu implementieren, und erst vor kurzem sind mehr plattformübergreifende Compiler entstanden. Wenn dies zutrifft, frage ich mich nur, was die Cross-Kompilierung schwierig machen würde, wenn Sie nur bestimmte Anweisungen zum Zusammenbau der CPU benötigen und native Systeme das entsprechende Betriebssystem benötigen
Jason
Ich denke, Sie haben hier ein terminologisches Verständnisproblem, das verwirrend sein kann. Sie verwenden die Tendenz "Cross Compiler" und "Cross Platform Compiler" austauschbar, aber es handelt sich um verschiedene Dinge (wenn auch verwandte): Ein Cross Compiler ist ein Compiler für eine Plattform, die sich von der von Ihnen verwendeten unterscheidet. und solche Dinge sind ungefähr so ​​lange verfügbar wie Compiler. Ein plattformübergreifender Compiler ist ein Compiler, der einen Zwischenschritt verwendet, um die Verarbeitung und Optimierung der Quellsprache von der plattformspezifischen Codegenerierung zu trennen, damit sie verwendet werden kann. ..
Jules
... zum Kompilieren von Code für mehrere Zielplattformen mit minimalen Änderungen. Solche Dinge sind eine neuere Innovation und viel komplexer.
Jules

Antworten:

18

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.

Blrfl
quelle
Dies ist jetzt die beste und ausführlichste Antwort. Ich denke, Geschichte hilft wirklich, den Kontext zu verstehen.
Jason
3
@ Jason Manchmal lohnt es sich, alt zu sein. :-)
Blrfl
4
"Abgesehen von der Unwilligkeit von Microsoft, dies zu tun, absolut nichts." - Ich würde es nicht "Unwillen" nennen. Microsoft ist ein börsennotiertes, gewinnorientiertes Unternehmen. Sie haben bestimmte Verantwortlichkeiten gegenüber ihren Aktionären und Stakeholdern. Sie würden mieten müssen, Zug, und Pay - Entwickler für den Linux - Backend, sie würden mieten müssen, Zug, und Pay - Tester für den Linux - Backend, sie würden mieten müssen, Zug, und Pay - Support - Mitarbeiter vertraut mit dem Linux - Backend, Sie müssten den Code entwerfen, entwickeln, warten, unterstützen und erweitern, alles für eine Plattform, die…
Jörg W Mittag
… Außerhalb ihres Kerngeschäfts. Und das alles nur, um den bereits vorhandenen n Compilern einen n + 1-ten Compiler hinzuzufügen, den Sie genauso gut verwenden könnten. Was wäre der geschäftliche Vorteil für Microsoft, wenn es mit GCC, Clang, ICC (Intel), XLC (IBM), Digital Mars, Tcc, PC, TenDRA, Metrowerks, PathScale usw. konkurrieren könnte? Persönlich glaube ich nicht, dass es welche gibt.
Jörg W Mittag
3
@ JörgWMittag What would be the business benefit ... I don't think there is any.- Das klingt nach einem guten Grund, nicht dazu bereit zu sein.
Blrfl
8

Ja, wenn Sie alle Informationen zu Ihrer Zielplattform haben, sollte es keine Rolle spielen, auf welcher Plattform Sie tatsächlich laufen.

Es gibt zwei Probleme, die häufig auftreten:

  1. Die Leute konzentrieren sich nicht darauf, weil es ein weniger verbreitetes Szenario ist. Oft ist das einzige, was Sie überkreuzen, ein Compiler, damit Sie das Überkreuzen beenden können. Weniger Fokus bedeutet schlechtere Unterstützung.
  2. Nicht triviale Programme benötigen mehr als nur Code. Der Umgang mit der Aufnahme / Verknüpfung von Bibliotheken wird etwas einfacher, wenn Sie Bibliotheken für die Plattform haben, auf der Sie ausgeführt werden. Sie befinden sich an einem bekannten Ort in einer bekannten Kodierung.

Die sind natürlich nicht unüberwindbar. Meistens erhalten Sie Compiler, die auf die Plattform abzielen, auf der sie ausgeführt werden, weil die Leute dies wollen.

Telastyn
quelle
Aha. Danke für die Abklärung. Macht für mich jetzt definitiv mehr Sinn.
Jason
Ich beschuldige Intellisense.
JeffO
2

Ich bin mit Ihrer Prämisse nicht einverstanden. Es gibt Millionen von Android- und iOS-Entwicklern. Und alle verwenden Compiler, die unter Windows oder Mac ausgeführt werden und Code für einen völlig anderen Computer erstellen.

Sie erhalten keinen Cross-Compiler, wenn keine Marktnachfrage dafür besteht. Menschen, die beispielsweise Code für einen Linux-Desktop entwickeln, verfügen meistens über einen Linux-Desktop und verwenden einen Linux-basierten Compiler - viel schneller, wenn Sie Ihre Anwendung direkt auf dem Computer ausführen können, auf dem sie kompiliert wird, ohne sie über das Netzwerk zu transportieren, viel einfacher und schneller um einen Debugger auf demselben Computer laufen zu lassen und so weiter.

Wie viel mehr Geld würde Microsoft verdienen, wenn ihre Compiler auch für Linux bauen würden? Ungefähr 0 US-Dollar. Wie viel mehr Software für Windows würde erstellt? Keiner. Wie viel mehr Linux-Software würde erstellt? Keine Ahnung, aber Microsoft kümmert sich nicht darum. Was wären die Kosten? Ganz erheblich. Compiler müssen fehlerfrei sein. Sie müssen getestet werden.

Ein weiteres Problem: Wenn Sie einen Compiler schreiben, der unter Windows schreibt, benötigen Sie jemanden, der weiß, wie man Windows-Software schreibt. Wenn Sie einen Compiler für Linux schreiben, benötigen Sie jemanden, der weiß, wie man Linux-Software schreibt. Wenn Sie einen Compiler für Linux schreiben, der unter Windows ausgeführt wird, benötigen Sie plötzlich das viel seltenere Brot von Entwicklern, die sowohl Windows als auch Linux kennen.

gnasher729
quelle
"Es gibt Millionen von Android- und iOS-Entwicklern. Alle verwenden Compiler, die unter Windows oder Mac ausgeführt werden und Code für einen völlig anderen Computer erstellen." Ähm nein, nicht sie nicht. Viele, viele Android-Entwickler verwenden Linux, und laut StackExchange-eigener Umfrage ist es die beliebteste Plattform für Entwickler.
Miles Rout