Warum funktioniert ein unter Linux kompiliertes Programm nicht unter Windows?

Lesezeit: 4 Minuten

Ich bin mir fast sicher, dass mein Problem darauf zurückzuführen ist, dass das kompilierte Programm als ausführbare Linux-Datei kompiliert ist, aber ich möchte dies nur noch einmal überprüfen.

#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("Hello world!\n");
    return EXIT_SUCCESS;
}

Das obige “Programm” sollte unter Windows und Linux problemlos kompiliert werden, da es Quellcode-kompatibel ist, da es keine betriebssystemspezifischen Bibliotheken oder ähnliches gibt.

Wenn ich jedoch “c99 hello.c -o hello.exe” auf meiner Linux-Box eingebe und diese “ausführbare Datei” dann auf einen Windows-Computer übertrage, weigert sie sich, ausgeführt zu werden. Soweit ich weiß, generiert Linux eine ausführbare Datei, die nur unter Linux ausgeführt wird, sodass das Hinzufügen von “.exe” keine Auswirkungen hat. Um dieses Programm unter Linux für Windows zu erstellen, müsste ich dieses Programm auf einem Windows-Computer neu kompilieren? Oder gibt es eine andere einfachere Methode, die funktioniert?

  • Du verstehst (grundsätzlich) recht. Die ausführbaren Dateien auf verschiedenen Betriebssystemen haben unterschiedliche Formate (und unterschiedliche Ausführungsmodelle).

    – Eugen Sch.

    20. August 2015 um 11:56 Uhr

  • Die andere Methode heißt “Cross-Compilation”.

    – Eugen Sch.

    20. August 2015 um 11:58 Uhr

  • Antwort auf die Titelfrage: Aus dem gleichen Grund läuft ein Dieselmotor nicht bleifrei und umgekehrt. Es sind unterschiedliche Systeme.

    – Jens

    20. August 2015 um 12:03 Uhr

  • Neben den unterschiedlichen Dateiformaten (ELF vs. „Portable Executable“-Format unter Windows) verfügen die beiden Betriebssysteme auch über unterschiedliche Application Binary Interfaces (ABIs).

    – André Holzner

    20. August 2015 um 12:06 Uhr

  • “keine betriebssystemspezifischen Bibliotheken”, wofür ist diese Bibliothek? printf? Jedes System verwendet eine andere Methode, um Zeichen auf der Konsole auszugeben. Außerdem ist nicht nur das Binärformat anders, auch die ABI ist anders

    – phuklv

    20. August 2015 um 12:49 Uhr

Benutzeravatar von SirDarius
SirDarius

Ausführbare Windows- und Linux-Dateien verwenden zwei verschiedene inkompatible Formate:

Unter Windows ist es die Portables ausführbares Format.

Unter Linux ist es die ELF (ausführbares und verknüpfbares Format).

Jedes Format nutzt die Besonderheiten des Betriebssystems, auf dem es ausgeführt werden soll, sodass es normalerweise nicht auf einer anderen Plattform ausgeführt werden kann.

Außerdem enthält eine ausführbare Datei nur einen kleinen Teil des Codes, der ausgeführt wird, nachdem er in den Arbeitsspeicher geladen wurde. Eine ausführbare Datei ist mit Systembibliotheken verknüpft, die die meisten Funktionen bereitstellen, die es dem Programm ermöglichen, mit dem System zu interagieren.
Da die Systeme sehr unterschiedlich sind, variieren die Bibliotheken, und ein Programm wie beispielsweise Linux kann nicht unter FreeBSD ausgeführt werden, obwohl letzteres auch ELF verwendet, da sie nicht mit denselben Bibliotheken verknüpft sind.

Um eine ausführbare Windows-Datei unter Linux zu kompilieren, kann eine Technik verwendet werden, die als Kreuzkompilierung bekannt ist. Ein Compiler ist schließlich nur ein Programm, das in eine Binärdatei schreibt, sodass theoretisch jeder Compiler Code für jede Plattform schreiben kann, solange die Bibliotheken des Zielsystems zum Linken verfügbar sind.

Der MinGW-w64 project bietet eine Toolchain, die dies ermöglicht. Beispielsweise können Sie es auf Debian-basierten Systemen mit der installieren sudo apt-get install mingw-w64 Befehl.

Die installierten ausführbaren Dateien können wie folgt verwendet werden:

i686-w64-mingw32-gcc hello.c -o hello32.exe      # 32-bit
x86_64-w64-mingw32-gcc hello.c -o hello64.exe    # 64-bit

  • Beachten Sie, dass dies nicht alles ist, was zählt: Zum Beispiel verwenden sowohl OpenBSD als auch Linux ELF für ihre Binärdateien, aber Sie können keine Linux-Binärdateien auf OpenBSD ausführen. Andererseits können Sie mit Hilfe von Wine Windows-Binaries unter Linux ausführen.

    – fuz

    20. August 2015 um 13:03 Uhr

  • @FUZxxl gute Punkte. Ich glaube jedoch, dass es eine compat_linux-Emulationsschicht für OpenBSD gibt, die es Linux-Binärdateien erlaubt, dort zu laufen.

    – SirDarius

    20. August 2015 um 13:07 Uhr

  • Ich versuche anzudeuten, dass das Binärformat in Bezug auf diese Frage ein Ablenkungsmanöver ist. Die wirkliche Antwort ist, dass das Betriebssystem, mit dem die Binärdatei zu interagieren versucht, nicht das gleiche ist und die Binärdatei nicht ausgeführt werden kann, wenn es keine Art von Systemaufruf-Übersetzungsschicht gibt.

    – fuz

    20. August 2015 um 13:08 Uhr

Es ist eine Kompilierungssituation, anders als Java .exe hat keine virtuelle Maschine, um den Code in verschiedenen Betriebssystemen zu interpretieren. Dann muss er alle spezifischen DLLs und Libs vom Betriebssystem haben, um den Job auszuführen, für den er gemacht wurde.

In .exe werden alle Dinge so gemacht, dass sie auf einem bestimmten Betriebssystem ausgeführt werden. Auf andere Weise ist in Java eine virtuelle Maschine die Magie, die Ihren Code auf verschiedenen Betriebssystemen interpretiert und ausführt.

1443820cookie-checkWarum funktioniert ein unter Linux kompiliertes Programm nicht unter Windows?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy