SDL2 Cross Compilieren
-
Setze mal das Makro
SDL_MAIN_HANDLED
direkt vor dem Einbinden des SDL-Headers, s.a. undefined reference to WinMain@16 C++, SDL-2 sowie die offizielle Doku SDL_SetMainReady.
-
Wobei das ganze komplett falsch ist.
WinMain ist anders definiert unter windows. Daher wird dein Programm dort nicht laufen.
https://learn.microsoft.com/en-us/windows/win32/learnwin32/winmain--the-application-entry-pointDer Windows build von SDL bietet eine eigene winmain implementierung an, welche dann die standard c main methode aufruft.
Diese gibt es als separate library siehe auch https://github.com/msys2/MINGW-packages/issues/6379@Mathuas du solltest dich aber vorher generell mal mit dem thema cross compiling linux->Windows beschäftigen. Bzw. Mit der Entwicklung von SDL programmen unter windows
Das die ganzen Probleme/Fragen ergeben sich nur aus deinem Unwissen über die entsprechenden Themen.Da stellt sich mir dir Frage wieso überhaupt du das ganze überhaupt via crosscompiling lösen möchtest.
Da wäre es doch einfacher das Programm unter windows zu bauen (das geht dann auch mit mingw)
-
@firefly sagte in SDL2 Cross Compilieren:
@Mathuas du solltest dich aber vorher generell mal mit dem thema cross compiling linux->Windows beschäftigen. Bzw. Mit der Entwicklung von SDL programmen unter windows
Das die ganzen Probleme/Fragen ergeben sich nur aus deinem Unwissen über die entsprechenden Themen.In der Pascal/Lazarus Welt mache ich dies schon sehr lange. Etwas in Linux entwickeln und wen alles läuft das ganze über den Cross-Compiler laufen lassen und schon hat man eine Windows-Version.
Daher wollte ich es auch mit C versuchen. So wie es schien, habe ich unter Linux alle Werkzeuge zur Verfügung.Da stellt sich mir dir Frage wieso überhaupt du das ganze überhaupt via crosscompiling lösen möchtest.
Da ich mich schon fast komplett von Windows gelöst habe, ich habe es nur noch in einer VB am laufen.
Da wäre es doch einfacher das Programm unter windows zu bauen (das geht dann auch mit mingw)
An das habe ich auch schon gedacht, so wie ich es am Rande mitbekommen habe, sollte dies auch mit wine laufen. Wen ich mich nicht täusche, ist mingw der klein Bruder von cygwin ?
-
@Mathuas sagte in SDL2 Cross Compilieren:
Jetzt läuft das Programm wie es sein soll. Nur jetzt die Frage, wieso braucht der WinMain ?
Meines Wissens gibt es unter Windows zwei "Subsytsem"-Typen, wobei der für das Programm verwendete vom Linker im Header der PE-
.exe
hinterlegt wird ("Subsystem"-Feld) - einmal "Konsolen-Programm" und einmal "Windows-Programm".Windows-Programme (GCC/Clang:
-mwindows
/ MSVC:-subsystem:windows
, könnte bei dir evtl. "Default" sein) öffnen bei der Ausführung kein Konsolenfenster und erwarten eineWinMain
-Funktion.Konsolen-Programme (GCC/Clang:
-mconsole
/ MSVC:-subsystem:console
) machen beim Ausführen ein Konsolenfenster auf (sofern sie nicht bereits aus einem heraus aufgerufen wurden) und benötigen lediglich eine klassischemain
-Funktion.Während der Entwicklung ist
-mconsole
ganz nett, da es unkomplizierte Textusgaben mitprintf
,std::cout
oderwrite(fileno(stdout), ...)
ermöglicht und das nicht bedeutet, dass man damit keine Windows- oder SDL-Fenster erstellen kann. Man hat halt lediglich immer noch ein zusätzliches Konsolenfenster, wo sich z.B. Statusmeldungen loggen lassen. Wenn du also keineWinMain
möchtest und dich das Konsolenfenster nicht stört, wäre dem Compiler-mconsole
mitzugeben eventuell eine Option. Du solltest aber recherchieren (oder einfach ausprobieren), ob SDL dabei eventuell eine etwas andere Initialisierung benötigt, da kenne ich mich nicht genau aus.
-
@Mathuas sagte in SDL2 Cross Compilieren:
@firefly sagte in SDL2 Cross Compilieren:
Da stellt sich mir dir Frage wieso überhaupt du das ganze überhaupt via crosscompiling lösen möchtest.
Da ich mich schon fast komplett von Windows gelöst habe, ich habe es nur noch in einer VB am laufen.
Da wäre es doch einfacher das Programm unter windows zu bauen (das geht dann auch mit mingw)
An das habe ich auch schon gedacht, so wie ich es am Rande mitbekommen habe, sollte dies auch mit wine laufen. Wen ich mich nicht täusche, ist mingw der klein Bruder von cygwin ?
Ich finde den Crosscompiling-Ansatz eigentlich ganz gut, sofern dein Primäres OS ohnehin ein anderes ist. Das ermöglicht dir, das Projekt in einem einzigen Build-Prozess für alle unterstützten Zielplattformen zu bauen, ohne dabei umständlich das OS wechseln zu müssen. Aber es stimmt schon, dass Crosscompiling oft etwas komplizierter ist, besonders wenn die Projekte nicht darauf ausgelegt sind (und z.B. Tools und Tests, die während des Build-Prozesses ausgeführt werden sollen, einfach für die Zielplattform kompilieren anstatt für die "Build"-Plattform und dann vor die Wand laufen). Dabei kann man allerdings eine Menge lernen
Auch braucht man für eventuelle eigene, plattformspezifische Tests einen Mechanismus, mit dem man die ausführen kann - z.B. indem eine VM gestartet wird, mit Wine, oder eben "manuell" auf dem jeweiligen Zielsystem.
Von Linux zu Windows ist meiner Erfahrung nach auch etwas leichter als umgekehrt, besonders was Projekte angeht, die primär für Linux entwickelt wurden (Build-Skripte, die ein vollwertiges Linux-System erwarten, Symbolische Links die nicht richtig erstellt werden oder auch Dateinamen, die erfordern, dass das Dateisystem zwischen Groß/Kleinschreibung unterscheidet - die Linux-Header haben z.B. ein paar solcher Dateien). Um z.B. einen GCC-Compiler für Windows zu bauen bin ich daher irgendwann auf einen Linux-Container umgestiegen, der eine GCC/MinGW-Version für Windows auf einem Linux-System cross-kompiliert, anstatt direkt unter Windows zu bauen. Das ist wesentlich einfacher, obwohl es in dem Fall ein (noch komplizierteres) sog. "Canadian Cross" war, auf Linux einen Compiler für Windows bauen, mit dem man Linux-Programme kompilieren kann (die Konstellation gibts aber nur, wenn man Compiler baut).
Zu deiner Cygwin/MinGW-Frage: Ich glaube die haben einen gemeinsamen Ursprung, aber MinGW ist im Gegensatz zu Cygwin keine POSIX-Kompatibilitätsschicht, sondern eine GCC-kompatible C-Standardbibliothek (libc) für Windows und eine Implementierung der Windows-API-Header (und auch solche Sachen wie DirectX). Ziel ist es, Windows-Programme mit GCC (oder auch Clang im GCC-Modus) kompilieren zu können. Die Linux-Kompatibilität spielt dabei nur am Rande eine Rolle, z.B. wenn es um zentrale Funktionen der libc geht, für die es unter Windows keine direkte Entsprechung gibt, die aber von vielen Programmen/Bibliotheken verwendet werden. Wie das "Min" im Namen schon sagt, fokussiert sich MinGW auf das "Minimum", um für Linux entwickelte Programme und Bibliotheken lauffähig zu machen, während Cygwin eher versucht möglichst vollständig POSIX-kompatibel zu sein. Daher muss man für MinGW-Kompatibität Windows auch meist aktiv im Programmcode unterstützen (Compiler-Switches, plattformspezifische
#ifdef
s und sowas), während man mit Cygwin eventuell damit durchkommt, bei der Entwickung ausschließlich Linux zu berücksichtigen.
-
@Finnegan sagte in SDL2 Cross Compilieren:
Von Linux zu Windows ist meiner Erfahrung nach auch etwas leichter als umgekehrt, besonders was
Projekte angeht, die primär für Linux entwickelt wurdenDie ist bei FPC/Lazarus das Gleiche. Linux ist die besser Basis. Auch wen man für den Raspi etwas entwickelt hat dies Vorteile. Ich habe Windows sowieso nur noch, um etwas auszuprobieren. ZB. um zu gucken ob das Cross compilierte Programm läuft.
Zu deiner Cygwin/MinGW-Frage: Ich glaube die haben einen gemeinsamen Ursprung, aber MinGW...
Wen ich mal Zeit und Lust habe werde ich das mal genauer angucken. Ich hatte mal vor vielen Jahren,, etwa 15-20 Jahren, als ich noch primär Windows verwendete, Cygwin installiert. Es war dazumal schon spannend.
Ich denke da ist unterdessen sicher auch noch einiges gegangen. Auch Linux hat sich in dieser Zeit recht entwickelt.
-
@Finnegan sagte in SDL2 Cross Compilieren:
Windows-Programme (GCC/Clang: -mwindows / MSVC: -subsystem:windows, könnte bei dir evtl. "Default" sein) öffnen bei der Ausführung kein Konsolenfenster und erwarten eine WinMain-Funktion.
Konsolen-Programme (GCC/Clang: -mconsole / MSVC: -subsystem:console) machen beim Ausführen ein Konsolenfenster auf (sofern sie nicht bereits aus einem heraus aufgerufen wurden) und benötigen lediglich eine klassische main-Funktion.Bringt leider nichts, das WinMain Problem besteht immer noch.
Einzig was momentan hilft ist dies:
int WinMain(int argc, char* argv[]) { main(argc, argv); }
Übrigens mit SDL3 besteht das Problem nicht, da geht ganz normal main().
-
@Mathuas sagte in SDL2 Cross Compilieren:
Bringt leider nichts, das WinMain Problem besteht immer noch.
Gut möglich. Ich habe den
main
/WinMain
-Zusammenhang auch nur generisch beschrieben, SDL kenne ich kaum. Natürlich gibt es auch wenn der Compiler mit-mconsole
keinenWinMain
-Einstiegspunkt mehr erwartet die Möglichkeit, dass SDL diese Funktion irgendwo explizit referenziert. Das würde dann ebenfalls zu diesem Fehler führen.
-
@Mathuas sagte in SDL2 Cross Compilieren:
Nochwas: Ich denke, diese
WinMain
-Signatur ist nicht korrekt und kann wegen der zu wenigen Parameter zu subtilen Fehlern führen (abgesehen davon, dass die ersten ohnehin nicht die richtigenargc
undargv
sind):int WinMain(int argc, char* argv[]) { main(argc, argv); }
Ich denke das hier ist wahrscheinlich besser als "schnelle Lösung" (siehe hier):
#include <windows.h> int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nCmdShow) { char* argv[1] = { 0 }; main(0, argv); }
Die Kommandozeile wird der
WinMain
soweit ich weiß als zusammenhängender String inpCmdLine
übergeben. Umargc
undargv
korrekt zu initialisieren, müsste man daher die Kommandozeile wahrscheinlich erstmal selbst parsen - daher nur diese Quick&Dirty-Lösung.
-
@Mathuas Du solltest dir Unbedingt die Doku von SDL2 mal genauer durchlesen.
Besonders den Part wie das ganze unter Windows funktioniert.Aktuell bist du nur blind am rumstochern
-
@Mathuas Was lange währt, wird endlich gut. Lass dich von firefly nicht ins Bockshorn jagen.
-
Bei einem anderen Programm musste ich folgendes reinflicken. Es muss doch irgendwie möglich sein das WinMain zu verbannen,
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { main(0, NULL); }
-
@Mathuas: Hattest du meinen Beitrag beachtet?