Schön, dass du drangeblieben bist!

Zitat von
Usselwetter
Update:
Inzwischen hat man mir auch bei GitHub geholfen und zwar muss man für SDL-1.2-main im Ordner "include" die "SDL_config.h.default" umbenennen in "SDL_config.h" (also ohne das default) und dann im Ordner "VisualC" die Datei "SDL_VS2010.sln" ausführen, ein Upgrade auf VS2022 ausführen und dann kann man die Datei ganz ohne Fehler erstellen. Hab jetzt die SDL.dll mit der Versionsnummer 1.2.16.0.
Richtig. Das steht auch, etwas gröber formuliert, in meinem letzten Beitrag:

Zitat von
jabu
- [. . .]
- irgendeine Default-Header-Datei, die anscheinend als Vorlage und zum Anpassen gedacht ist, kopiert und passend (ohne "default") umbenannt (sonst hagelt es Fehler, da die Datei unter dem Namen nicht existiert, habe mir nicht die Mühe gemacht, mich mit den Optionen dort zu befassen),
- [. . .]
Und in irgendeinem Readme (daher habe ich es) steht es auch. Readmes zu lesen, ist allgemein ratsam. 

Zitat von
Usselwetter
Jetzt muss ich nur noch das SDL12-compat hinkriegen das muss ja gelinkt werden.
Muss nicht gelinkt werden, denn sonst würde dieses, was du im folgenden Zitat beschreibst, nicht klappen. Es klappt, weil speziell hier die Angabe des Include-Pfades, in dem sich u.a. die SDL.h, die der Compiler vermisst (siehe Fehlermeldung) genügt. Der hier angegebene, anscheinend einem Projektstandard entsprechende, Lib-Pfad ist unter der vorgegebenen "VisualC"-Konfiguration unzutreffend. Es werden die Libs also nicht gefunden. Warum das Erstellen der SDL12-compat-DLL trotzdem klappt, steht weiter unten.

Zitat von
Usselwetter
Update #2:
So, hier die Lösung für SDL12-compat
Download latest SDL2-devel-2.0.xx-VC release
Extract it to C:\SDL2
Start CMake, check the option "Advanced", press Configure, let it fail
Edit SDL2_INCLUDE_DIR = C:\SDL2\include
Edit SDL2_LIBRARY = C:\SDL2\lib\x86\SDL2.lib
Configure again, Generate
Start SDL12-compat.sln with Microsoft Visual Studio, set everything to "Release Win32", rebuild everything
So ähnlich habe ich es im Erstansatz auch gemacht (bin von selber darauf gekommen). Ich habe dieses dann aber durch eine Umgebungsvariable, die ich für den Windows-Benutzer angelegt habe, gelöst (mit verschiedenen funktionierenden Ansätzen, sind nicht alle hier gezeigt).
Die erste wichtige Erkenntnis ist, dass das CMakeSettings.json weder zum Projekt noch zu CMake gehört, sondern von Visual Studio (kürze ich als "VS" ab) aus den im CMakeList.txt angelegten Settings generiert wird, um dem Benutzer ein bequemes GUI zur Steuerung der Eingaben für CMake anzubieten und damit das Intellisense in der IDE funktioniert. Anstatt dass VS CMake anweist, VS-Projektdateien zu erstellen (um das Buildsystem von Microsoft, MSBUILD genannt, zu verwenden), weist VS CMake an, Projektdateien für das Buildsystem Ninja zu erstellen. VS unterstützt anscheinend Ninja, um die Builds anstoßen zu können etc.
Die zweite wichtige Erkenntnis ist, dass einem niemand sagt, ob dieser Weg überhaupt unterstützt wird.
Doch er hat seinen Reiz (leider ohne zu wissen, was genau im Sinne des Erfinders ist, also Fragen wegen Konfigurationsoptionen offen lässt):
VS ist gut darin, halbwegs korrekte parallele Build-Setups, also die typischen vier Varianten (32 Bit Release / 32 Bit Debug / 64 Bit Release / 64 Bit Debug) systematisch nachkonfigurierbar zu machen, was mit CMakeSettings.json (und dann Buildsteuerung durch Ninja) auch gut klappt, aber strukturell eine bis zwei Ebenen zu spät kommt:
Die Vorgabe für CMake beim SDL1.2-compat-Projekt versagt nämlich darin, CMake so anzuweisen, dass es entsprechende (am liebsten VS...)-Projektdateien von vornherein generiert!
Es fehlt ein CMake-Skript, das das von Anfang an richtig macht (egal ob dann Ninja oder MSBUILD zum Zuge kommt). Das wäre nämlich dem Sinn von CMake entsprechend (und nicht dieses Nachfrickeln, obwohl es bei mir funktioniert hat, aber das will man lieber wegautomatisiert haben).
Vielleicht gibt es irgendwo ein Skript, welches CMake die entsprechenden Parameter mitgibt? Auf dem normalen Weg ist es nicht so ganz einfach. Man will ja alle Konfigurationen in einem VS-Solution-File haben und das gleich richtig. Irgendwie scheint das zu fehlen oder nur auf Umwege erreichbar zu sein. Manuell kann ich mir zwar alles hinfummeln, aber das ist nicht der Sinn der Automatisierung. Überhaupt sind die SDL-Projekte kein Paradebeispiel für gelungenes Build-Setup. Trotzdem steckt einige Know-How im Code und sowieso verdammt viel Arbeit, was ich natürlich wertschätze.
Um innerhalb des CMakeSettings.json auf Umgebungsvariablen zuzugreifen, ist folgendes Schema nötig: ${env.EnvironmentVariableName}
Damit ergibt sich zum Beispiel (müsste i.d.R. an die realen Pfade angepasst werden; MY_USER_ENVIRONMENT_VARIABLE_SDL2INCPATH steht hier als Platzhalter für die Benutzer-Umgebungsvariable, die man unter der Windows-Systemsteuerung für den Pfad des Wurzelverzeichnisses der Lib-Builds anlegen würde, wobei natürlich i.d.R. auch die Pfade Anpassungen bedürfen, wobei ein für VS typischer z.B. auf \Win32\Release\SDL2.lib enden kann; wichtige Frage: Warum ist das nicht definiert? Diese Pfade dem Zufall bzw. den jeweils gültigen Visual-Studio-Defaults zu überlassen, ist doch dumm! Oder es müsste die SDL2.lib wenigstens abschließend, z.B. per benutzerdefiniertem Build-Schritt, ans endgültige Ziel kopiert werden.):
Für 32-Bit-Release-Builds
SDL2_INCLUDE_DIR = ${env.MY_USER_ENVIRONMENT_VARIABLE_SDL2INCPATH}
SDL2_LIBRARY = ${env.MY_USER_ENVIRONMENT_VARIABLE_SDL2LIBPATH}\x86\release\SDL2.lib
Für 32-Bit-Debug-Builds
SDL2_INCLUDE_DIR = ${env.MY_USER_ENVIRONMENT_VARIABLE_SDL2INCPATH}
SDL2_LIBRARY = ${env.MY_USER_ENVIRONMENT_VARIABLE_SDL2LIBPATH}\x86\debug\SDL2.lib
Für 64-Bit-Release-Builds
SDL2_INCLUDE_DIR = ${env.MY_USER_ENVIRONMENT_VARIABLE_SDL2INCPATH}
SDL2_LIBRARY = ${env.MY_USER_ENVIRONMENT_VARIABLE_SDL2LIBPATH}\x64\release\SDL2.lib
Für 64-Bit-Debug-Builds
SDL2_INCLUDE_DIR = ${env.MY_USER_ENVIRONMENT_VARIABLE_SDL2INCPATH}
SDL2_LIBRARY = ${env.MY_USER_ENVIRONMENT_VARIABLE_SDL2LIBPATH}\x64\debug\SDL2.lib
Ob bei im Pfad enthaltenen Leerzeichen Anführungszeichen nötig sind und ob hier Backslashes erlaubt sind, bin ich überfragt (Edit: Inzwischen nicht mehr). Ich tippe vorsichtig darauf, dass man hier schon intuitiv ziemlich weit kommt (Edit: Kommt man, denn VS übernimmt das Escaping, im JSON stehen die doppelten Backslashes; Anführungszeichen sind automatisch gesetzt), aber falls nicht, könnte man diese Alternativen probieren (ist von allgemeinem Nutzen):
"${. . . . .}\ . . . . .\SDL2.lib"
"${. . . . .}\ \. . . . .\\SDL2.lib" (Backslash escaped)
"${. . . . .}/ . . . . ./SDL2.lib" (Slash, wie außerhalb von Windows üblich)
${. . . . .}\ \. . . . .\\SDL2.lib (Backslash escaped)
${. . . . .}/ . . . . ./SDL2.lib (Slash, wie außerhalb von Windows üblich)
CMake selbst (z.B. bei CMakeList.txt und von dort aus eingebundenen Dateien) verwendet dagegen folgende Schemata (ENV vorangestellt):
$ENV{EnvironmentVariableName}
und innerhalb von manchen Ausdrücken:
ENV EnvironmentVariableName
Bei CMake selbst leiten in Strings eingebettete Backslashes Escape-Sequenzen (ungefähr wie unter der Sprache C, z.B. \t für Tabulator, \n für einen Zeilenumbruch etc.) ein, weswegen dem Backslash selbst ein Backslash vorangestellt werden muss (\\), da sonst das nächste Zeichen ein Steuerzeichen wäre. Siehe dazu die drei oben aufgeführten Varianten. Was unter VS an Backslashes bei Pfaden noch funktionieren mag, funktioniert direkt in CMake-Skripten nicht mehr. Wo String-Variablen an Listen angehängt werden, ist es ratsam, sie in Anführungszeichen zu setzen, damit ein möglicherweise enthaltenes Leerzeichen nicht als Listentrenner interpretiert wird. Dabei ist hilfreich, dass auch innerhalb von Double-Quotes interpretiert wird. Sonst würde manches nicht sinnvoll funktionieren.
Nach dem kleinen Exkurs zur Fehlervermeidung wieder auf das von Dir angeführte C:\SDL2\lib\x86\SDL2.lib verwiesen:
Das Schema SDL2\lib\x86\SDL2.lib entspricht anscheinend einem Standardpfad von SDL-Build-Setups für Linux. Dagegen passt diese Konvention gar nicht zu den Visual-Studio-Builds von SDL2, und zwar weder über den CMake-Umweg noch direkt über das vorgegebene Solution-File. Deswegen ist das Fehlschlagen des Auffindens normal.
Trotzdem klappt das Erstellen der SDL-1.2-compat-DLL, da eben nicht gegen die SDL2-DLL gelinkt wird. Das liegt daran, dass SDL2.lib Importinformationen beinhaltet, die man nur (durch den Linker) der Importtabelle der SDL-1.2-compat-DLL hinzufügen lassen muss, wenn der Programmlader von Windows gleich beim Programmstart die SDL2-DLL binden soll. Dieses ist bei der vorliegenden Standardkonfiguration der SDL-1.2-compat-DLL nämlich nicht der Fall.
Es gibt dort ein anderes Vorgehen:
Wie kommt es also trotzdem dazu, dass die DLL geladen wird? -> Das veranlasst die SDL-1.2-compat-DLL nach dem Start selber, nämlich per Aufruf der Windows-API-Funktion LoadLibrary.
Wie kommt es dazu, dass die Funktionen aus der SDL2-DLL aufgerufen werden können, so ganz ohne entsprechende Einträge in der Importtabelle? -> Das veranlasst die SDL-1.2-compat-DLL ebenfalls selber, nämlich nach dem Aufruf von LoadLibrary, und zwar per GetProcAdress (<- auch ein Beispiel dabei). GetProcAdress braucht ein Handle zur DLL und den Namen der Funktion, deren Adresse gesucht wird. Der Rückgabewert ist die Adresse der Funktion. Natürlich muss die komplette Signatur der Funktion (bzw. der Typ des Funktionszeigers) bekannt sein, z.B. weil sie im Code steht oder über ein Header-File der Abhängigkeit bekannt gemacht wird.
"SDL2_LIBRARY = C:\SDL2\lib\x86\SDL2.lib" muss also nicht stimmen, weil die Importinformationen aus dieser Import-Lib beim Standard-Build-Setup der SDL-1.2-compat-DLL nicht benötigt werden. Das gibt bestenfalls eine Fehlermeldung, die man ignorieren darf. Der Pfad stimmt nämlich bei Windows-Builds mit Visual-Studio in Standardkonfigurationen nicht. Verwendet man das vorgegebene Solution-File, so kommt bei VS2022 dieser Pfad heraus:
C:\SDL\VisualC\Win32\Release\SDL2.lib
Man kann ihn natürlich in VS (unvorteilhaft) auf C:\SDL2\lib\x86\SDL2.lib abändern. Das ist unvorteilhaft, weil zwischen vielen Varianten (s.o.) - die nicht immer zueinander passen (worunter z.B. ein Debug-Build mit Performancenachteilen oder ein Build mit inkompatiblem Ausgabeformat (falscher Compiler/Linker oder inkompatible Settings derselben Tools) sein kann - nicht differenziert wird.
Natürlich kannst du den Pfad eintragen. Er nützt nur nichts, solange nicht eine SDL-1.2-compat-DLL in einer Variante, die die SDL2.dll durch Windows bereits beim Programmstart geladen haben will, erstellt wird. Ob eine solche Variante angeboten wird, müsste man gucken. Beide Verfahren haben jeweils ihre Vor- und Nachteile. Eine aussagekräftige Fehlermeldung, z.B. dass die SDL2-DLL nicht gefunden wurde und wie eine Fehlerbnehebung aussehen könnte, lässt sich nicht implementieren, wenn die SDL2.dll bereits beim Programmstart von Windows geladen wird und fehlt. Der Programmlader von Windows muss nämlich die Adressen der aufzurufenden (importierten) Funktionen erst einsetzen. Falsche Adressen (Platzhalter) würden jedoch Programmabsturz (besser) oder Vandalismus (schlechter) bedeuten. Deswegen unterbindet Windows den Programmstart konsequent, falls die Abhängigkeit nicht geladen werden konnte oder falls Importe fehlen. Der Entwickler der abhängigen Datei kann demnach keine hilfreiche Reaktion oder Alternative implementieren, da sein Code niemals läuft. Das ist ein Nachteil der, hier unbenutzten (aber ansonsten häufigeren!), Variante mit dem Einbinden der Importbibliothek.
Das Elend mit der Konfiguration geht tiefer:
Eigentlich sollte die CMake-Konfiguration des SDL1.2-compat-Projektes unter Zuhilfename einer Umgebungsbvariable, nämlich mit dem Namen "SDL2DIR", über ein Such-Skript mit dem Namen "FindSDL2.cmake" (liegt unter sdl-1.2-compat\cmake\modules), welches die CMakeLists.txt des SDL1.2-compat-Projektes einbindet, die Pfade automatisch ermitteln. Dieses schlägt aber bei mir an mehreren Stellen fehl:
Das Ergebnis des per Umgebungsvariable ermittelten Pfades lässt sich bei mir nicht direkt in SDL2_INCLUDE_DIR (innerhalb von FindSDL2.cmake) speichern, aber über eine Zwischenspeicherung in einer anderen Variable und dann als Zuweisung an SDL2_INCLUDE_DIR funktioniert es. Es hilft nicht, bloß den Cache immer wieder zu leeren. Das Zuweisen innerhalb von find_path muss anders als normales Zuweisen sein. Die Zuweisung an SDL2_INCLUDE_DIR innerhalb von find_path funktioniert nämlich nicht, wogegen die Zuweisung an eine Hilfsvariable und von dort aus an SDL2_INCLUDE_DIR funktioniert. Also habe ich das als Workaround eingebaut.
Befriedigend ist das nicht, solange die Ursache nicht geklärt ist. Der Ersteller von FindSDL2.cmake sollte damit wohl Erfolg gehabt haben, ich aber nicht. Das ist schon seltsam. Vielleicht handelt es sich um ein obskures Scoping- oder Zugriffsproblem, vielleicht wegen des von VS erstellten CMakeSettings.json? Oder ein komisches Copy-on-write-Artefakt? Irgendwas muss beim Zuweisen per find_path anders als beim normalen Zuweisen sein. Von Windows-Batch-Skripten kennt man (in der Natur der Sache liegende, wohlbekannte) Probleme, die eine ähnliche Symptomatik zeigen. Vielleicht sind die Ursachen ähnlich?
Wie auch immer, der Workaround funktioniert. Dann habe ich noch das Zusammensetzen der Lib-Pfade zu den "VisualC"-Pfaden aus SDL2 passend gemacht. Schlussendlich findet FindSDL2.cmake jetzt anhand der vorgesehenen Umgebungsvariable SDL2DIR alles, was es finden muss, um auch andere Varianten, zum Beipiel die, für welche für man die Import-Lib brauchen würde, zumindest theoretisch, zu unterstützen (obwohl derzeit unbenötigt). Das ist näher an dem dran, wie das System mal angedacht war (universeller verwendbar). Aber im Web lässt sich kaum etwas finden, wie man das System im Sinne des Erfinders betreibt. Wie man es manuell hinfrickelt, weiß ich. Dafür brauche ich keine Tutorials. Interessanter wäre schon, wie man das alles automatisiert und konsistent hinbekäme.
Andere Baustelle:
Ich habe viel Zeit mit der SDL2-VisualC-Konfiguration verbracht und musste feststellen, dass die teilweise suboptimal ist, insbesondere beim Erstellen der Tests, da ist sie unvollständig und auch etwas fehlerhaft, z.B. indem keine Konsole erstellt wird, wo eine nötig ist (leicht zu fixen, nervt trotzdem) oder indem Ressourcen, z.B. Bitmaps, nicht mitkopiert werden (oder nicht an die richtige Stelle). Das habe ich zwar größtenteils gefixt, ist aber unbefriedigend, solange das nur in meiner VS-Projektkonfiguration und in keinem CMake-Skript steht. Eventuell ist auch das Original mit Handarbeit entstanden.
Das Verzeichnis zum Testen für "VisualC" ist ja ein anderes, und zwar das, in welchem auch die anderen Ausgabedateien erstellt werden. Das ist auch gar nicht mal schlecht, weil damit die Ergebnisse anderer Builds nicht überschrieben werden und 32 Bit, 64 Bit, Release und Debug schön auseinandergehalten werden. Dafür hat man die Ressourcendateien viermal zusätzlich vorzuhalten, wenn man alle vier Kombinationen erstellen lässt.
Auch bei den Optimierungen bezüglich SSE und SSE2 ist nicht alles astrein. PGO (Profile Guided Optimization) funktioniert auch nicht. Für manches habe ich Lösungen gefunden, sodass ich jetzt endlich weitgehende SSE2-Builds (auch jenseits der vom Autor mühsam manuell hineingeklöppelten Intrinsics) habe und Whole-Program-Optimization mit Linktime-Code-Generation nutzen kann, geht aber nur mit ein paar kleineren Kompromissen an der einen oder anderen Stelle. Der Autor hat zu viel handoptimiert, und der Compiler von Microsoft hat ein paar Unzulänglichkeiten bei SSE und SSE2. Diese Kombination macht es schwer, den Compiler dazu zu überreden, sein volles Optimierungspotential auszuschöpfen. Zudem ist die originale Optimierung schon ziemlich gut, vorausgesetzt man verwendet keine Debug-Konfiguration, die ist nämlich standardmäßig aktiv. Mit der hättest du eine sehr miese Performance (ist bei Debug-Builds normal). Du müsstest bei SDL2 die Release-Konfiguration wählen.
Unabhängig davon, was dir die SDL-Leute sagen, würde ich immer vorsichtshalber, auch wo die Debug-Konfiguration dicht an einer Release-Konfiguration eingestellt ist (hier bei SDL2 ist es für "VisualC" nicht so, sondern eher wie erwartet, also Release für Performance und Debug für Debugging), und die angeblich genügen soll, extra eine Release-Konfiguration anlegen und die akribisch kontrollieren und nötigenfalls nachkonfigurieren. Bei Debug-Builds könntest du nämlich Probleme mit den performancemindernden Defaults von MSVC bekommen und dich über zu wenig FPS oder Ruckeln wundern. Grundsätzlich kann man die Namen und Settings zwar frei wählen, aber da mit automatischer Generierung gearbeitet wird, weiß man nicht ohne Weiteres, ob die performancemindernden Settings einer Standard-Debug-Konfiguration unter allen Umständen sinnvoll abgeändert wurden bzw. werden, eben wie bei einem Release-Build. Sobald Visual-Studio heruminterpretiert, muss man nämlich damit rechnen, dass es seine Standardsettings wählt und die eben durch das Gefundene lediglich ergänzt, ändert oder überlagert. Alles andere wäre unbelegt und damit mehr oder minder dem Zufall überlassen. Man kann ja nicht immer alle Skripte und jegliches Tool-Verhalten udn alle Projektspezialitäten im Kopf haben. Ich kann es nicht ausstehen, wenn mich Code oder ein Projektsetup anlügt, sodass nur die Eingefleischten mit den Details umzugehen wissen (zumal sie selber den Überblick verloren haben, wenn man sich die Tests anschaut).
Fromme Versprechungen beziehen nicht unbedingt alle Wege der automatischen Generierung ein. Da könnten so komische Sachen herauskommen, dass z.B. Linux-Builds beste Performance liefern, aber Windows-Builds nicht, was dann Windows zugeschoben werden könnte, aber doch bloß an mangelnder Sorgfalt beim Build-Setup für Windows liegen könnte. Es wäre nicht das erste Mal, dass es heißt, dass irgendwas unter Linux besser läuft, wo es dann hauptsächlich doch bloß an schlechterem Support für Windows liegt, da die Entwicklung hauptsächlich von Linux her betreiben wird (und auch die, teils subtilen, Unterschiede der Compiler und Libs nur unzureichend einbezieht). Damit sage ich nicht, dass Linux nicht in Teilbereichen messbare Vorteile gegenüber Windows hätte, aber viele Beobachtungen bezüglich Unterschieden haben ihre Ursachen doch beim "unausgegorenen" Low-Level-Teil eines Cross-Plattform-Unterbaus. Das kann schon wegen der enormen Mühen der Mehrgleisigkeit passieren. Das Betriebssystem ist ein Teil, der Unterschiede ausmachen kann, die Tools und Ansätze zur Anwendungsentwicklung ein anderer. Es ist kaum leistbar, alle relevanten Pitfalls jeder Umgebung zu kennen und sie geschickt zu überbrücken.
Fazit:
Bei der bestehenden Komplexität sind Wartbarkeit und Zuverlässigkeit kaum noch gegeben. Es müssten viel mehr Mühen in Restrukturierung und Komplettierung der Build-Skripte gesteckt werden. Es müsste im Code der Low-Level-Teil modernisiert werden, sodass er den Raum der Möglichkeiten weniger beschränkt. Das ganze System steht kurz vor der vorübergehenden "Unwartbarkeit". Wird irgendwo nochmal am Compiler etwas verändert, kann es leicht komplett brechen. Manches ist zu speziell. Man sieht das erst, nachdem man tiefer eingetaucht ist. Das Projekt ist (mit einigem Fleiß) wegen gewisser Qualitäten rettbar, es ist kein Sackgassenkandidat. Aber es kann leicht passieren, dass sich niemand mehr findet, der den Kram auf ein angenehmeres und leichter wartbares Level bringt. Mit solchen Sachen kann man schlecht punkten, wenn man einen Job sucht, obwohl gerade solche Aufgaben besonders wichtig sind. Man kann auch kein tolles Feature, das man erschaffen hätte, vorzeigen. Es handelt sich um eine Aufgabe für Idealisten, könnte man sagen. Im Grunde wurde mit der Einführung von CMake schon ein guter Ansatz verfolgt. Das müsste konsequenter umgesetzt werden, wie man es bei anderen Projekten schon gesehen hat. Aber wer hat schon Bock darauf, das unbezahlt in seiner Freizeit zu machen? Wer räumt schon gerne anderen Leuten ihre Zimmer auf? Man müsste es schon zum "eigenen Zimmer" machen, und selbst dort klappt es erfahrungsgemäß nicht so recht...
PS
Konsistenz bei Konventionen ist wichtig. Und Meidung von Definitionslücken ist wichtig. Beides vermisse ich bei diesen drei Projekten stark. Es sollte mehr Verlässlichkeiten und weniger Potential für Überraschungen geben. Eine Dokumentation ist kaum vorhanden. In solchen Fällen sollte alles mehr für sich sprechen. Dass die Leute längerfristig vom GNU-Buildsystem weg wollen, ist schon mal eine gute Einsicht.
Leider gibt es nicht viel Gutes für Buildkonfiguration, vermutlich gar nichts Gutes. Wenn mich einer fragen würde, was ich mit hunderttausend Euro, für die ich eine Gegenleistung erbringen müsste, Konstruktives anfangen würde, dann vielleicht genau das, nämlich ein taugliches System für Buildkonfiguration und dazu auch ein Buildsystem erschaffen (habe konkrete Ideen, worauf es ankäme, um es sogar besser als CMake zu machen).
Was ich bisher gesehen habe, ist immer wieder anders, aber nicht gut. Alles Unintuitive in dem Bereich gehört meiner Meinung nach auf die Müllhalde der Geschichte. Systeme, die ein schwer vorhersehbares Verhalten zeigen, da sie stark auf Systemtools und damit auf das Verhalten des unten drunter liegenden Systems angewiesen sind (oder diesen ohne guten Grund ähneln), kann man getrost in die Tonne kloppen. Aber das ist ja, mehr oder minder, meistens so. Und so kommt es meistens zu seltsamen Überraschungen (und einer unsteten Lernkurve).
Es gibt schon gute Gründe dafür, dass Leute sich das nicht antun wollen und sich an ihre IDE ketten oder mit nacktem GNU Make nach der Freiheit suchen (diese aber damit auch nicht erlangen), was eine andere Form der Kapitulation vor einer eigentlich lösbaren Aufgabe ist. Die zu erschaffende Sprache muss erst einmal etwas taugen, sonst sind alle Mühen sinnlos. Bei CMake wurde das leider auch verbockt. Das wird nur so oft verwendet, weil nichts Besseres da ist. Aber ein paar Ansätze davon sind gut. Es geht eben nur mit Trippelschritten weiter. CMake ist universell und mächtig und bevormundet wenig, was schon mal gut ist, aber es fehlen geeignete Abstraktionen für ein Problem, welches tyischerweise und naturgemäß immer dieselben Abstraktionen beeinhaltet. Dass das keiner so richtig merkt, finde ich schon seltsam.
Am dichtesten an der richtigen Abstraktion dran, und zwar weit vor allen anderen Systemen, die ich mir bisher angeguckt habe, ist MSBUILD, welches unter der Haube von Visual Studio eingesetzt wird. Aber es ist zu inflexibel für allgemeinen Gebrauch und eine kaum für Menschen lesbare XML-Hölle, die jedoch ganz passabel Eigenschaftenvererbung ermöglicht (worauf es im Wesentlichen ankommt!), wenn man denn das GUI von VS benutzt. Sonst ist es unbenutzbar! Die Abstraktionen gehören natürlich generalisiert. Es gibt z.B. im Projektbaum der Eclipse-IDE ein paar Freiheiten, die VS nicht bietet. Und Makefiles für GNU Make müssten auch gescheit abbildbar sein. Das muss alles generisch möglich sein, ohne Nachfrickeln. Sonst sind die Abstraktionen untauglich. Eine der überhaupt universellsten IDEs von den Buildsystemen her ist Eclipse. Und komplett anders ist reines GNU Make. Es sollte nicht ganz falsch sein, solche als Prüfstein für ein Buildkonfigurationsprogramm zu benutzen. Damit meine ich nicht, dass man alles von Anfang an als Ausgabeformate konkret untertützbar haben müsste, sondern dass die Abstraktionen grundsätzlich mit abgedeckt werden müssten, also ein Geradeaus-Vererbungssystem ebenso wie rekursive Abhängigkeiten und das alles mit einer einfachen menschenlesbaren Syntax, und zwar mit Einfachheit durch Mächtigkeit des Ansatzes. Denn je mehr man frickeln muss, desto komplizierter wird es.
Man muss Eigenschaften ("Properties") auf einfache Weise erben, explizit kopieren und überschreiben können. Das kann MSBUILD bzw. Visual Studio ganz hervorragend. Aber man kann das dazu nötige XML nicht mehr regelmäßig manuell hinschreiben, ohne davon verrückt zu werden. Ein Teil steckt im VS-Solution-File, ein Teil in den Projektdateien und der interpretierende in MSBUILD. Man müsste MSBUILD sozusagen atmen, um alles auszuschöpfen. Zwar sehen die VS-Solutions und Projekte beim Durchgucken mit einem Editor einfach aus, was schon gut ist, aber der Eindruck täuscht über die Mächtigkeit hinweg. Und selber schreiben kann man den Kram kaum, weil man zu viel von dem, was MSBUILD und die Tools und SDKs verbergen, auswendig wissen müsste und weil der Kram längst nicht so intuitiv ist, wie ihn ein Mensch bräuchte. Man kann sich natürlich an einer Vorlage entlanghangeln, aber dann weiß man noch nicht, welche Alternativen unterstützt werden.
Dieses verborgene "Wissen" zur korrekten Generierung von Build-Setups gehört als eine Art Datenbank für Regelsätze in den Teil für die Transformation zur Ausgabe hinein und müsste einen großen Wartungsaufwand erfordern. Das ist aber der Brot-und-Butter-Fleiß-Teil. Spannender finde ich, den Teil der Formulierung des eigentlichen Problems in für Menschen leicht zugänglicher Form und zugleich mit passenden und einleuchtenden und keine Schranken auferlegenden Abstraktionen zu lösen. Bisher ist jeder Versuch, dieses zu erreichen, gescheitert! Der Weg, den reale Systeme gehen, um universell verwendbar zu sein, sind ihre prozeduralen und imperativen Ausdrucksmittel, die aber von ihrer Auslegung her objektorientierten und deklarativen und damit für Menschen mit viel wneiger Aufwand konfigurierbaren Systemen im Weg stehen. Das miteinander zu vereinen, und zwar so, dass es ein Mensch kapiert, ist eine schwierige Aufgabe.
Menschen verstehen entweder gut:
"Tu dies, dann das, dann..."
oder
"So will ich es haben, wobei X wie Y ist, aber die Komponente X.a anders als Y.a ist, und zwar so und so überschrieben (spezialisiert)."
Dabei gibt es noch die Unterscheidung, ob man die Dinge bei Abhängigkeiten vom Ende her oder von vorne betrachtet, also ob man entweder ein Rezept hat, das etwas nach und nach aufbaut (kann in abbrechende Äste enden) oder ob man zuerst definiert, was erstellt werden soll und dann alle Vorprodukte (Abhängigkeiten) dafür ebenfalls definiert und deren (Unter)-Abhängigkeiten usw., ungefähr wie bei GNU Make (wobei auch damit Mischformen möglich sind), wobei diese Konzeption dazu führen kann, dass schlussendlich gar nichts entsteht und das schwer zu fixen ist. Dafür gibt es einige Garantien für Vollständigkeit, wenn es baut.
Es ist gewiss nicht trivial, geeignete und zugleich beherrschbare Abstraktionsmittel für alles zu finden. Aber der rein wirtschaftliche Wert, sich dem mehr als bisher anzunähern, müsste im Multizigmilliarden-Dollarbereich liegen. Die eingesparte Menschenversklavung wäre der eigentliche Bonus.
Alles zusammen ist schwer zu denken, wird aber selten wirklich im selben Atemzug gebraucht, kann also teils separat behandelt werden. Bestehene Systeme lösen den Übergang und das Zusammenwirken nicht in geeigneter Weise. CMake ist gut (wäre schlimm, wenn es nicht mal das geben würde), aber noch nicht gut genug, um Menschen auf diesem Feld von der Sklaverei durch die Maschine zu befreien. Bei genauerer Betrachtung ist es jedoch nicht Sklaverei durch die Maschine sondern durch frickeligen Code, der aus zu kurz gedachten Ansätzen wegen irgendwelcher Spezialprobleme entstanden ist. Ich finde es schrecklich, wie die IT Menschen versklavt - regelrecht verbrennt! Und es wird immer schlimmer, wenn ich mir die Hipster-Höllen-Ansätze angucke, je moderner, desto menschenverachtender. Und immer wieder kommt Neues hinzu, anstatt etwas einmal besser zu machen.
Ohne zig Programmiersprachen zu lernen (die der Tools mitgerechnet), kommt man nicht mehr zurecht, was aber die Problematik, nachher nichts richtig zu können, impliziert. Man lernt dann nur noch und bekommt nichts produktiv mehr auf die Reihe. Da ist die IT im Jahr 2022 angelangt. Trotz immer mehr Automatisierung wird alles immer schlimmer. Ohne extra angestellte Dev-Ops-Experten kein Produkt etc. Solche Konzepte geißeln die Menschheit. Ich bin schon lange davon überzeugt, dass das mehr schadet als nützt. Man braucht immer mehr Entwickler, um Probleme zu lösen, die früher als einfach galten. Und es wird immer teurer.
Katastrophal ist heutzutage GUI-Entwicklung, was größtenteils daran liegt, dass Microsoft das Windows-API und C++ vernachlässigt und die .NET-Hölle erschaffen hat und damit wichtige Grundlagen und Anreize, um darauf etwas Gescheites aufzubauen, fehlen. Nichts gegen C#, das ist nicht das eigentliche Problem. Es gibt kein einziges rundherum taugliches plattformübergreifendes GUI-Toolkit. Und es gibt nicht mal ein einziges taugliches für Windows. Mit welch kleinem Aufwand wurden einst vor 20 Jahren von winzigen Programmierklitschen kompakte Programme mit Borland Delphi erstellt, die ein GUI haben und auf den Punkt genau das tun, was sie tun sollen? Dafür braucht man heutzutage ca. 150 MB mehr (einen eingebetteten Browser) und mindestens dreimal so viele, nämlich unterschiedlich spezialisierte, Leute. Es ist ja nicht so, dass die Web-Programmierer, die man heutzutage für die grässlichen eingebetteten Browser (Chromium) braucht, die normale Anwendungsprogrammierung beherrschen würden und umgekehrt. Beides zuammen ist für eine Person längst nicht mehr beherrschbar. Und irgendwer muss sich um das überbordend komplexe Gesamtkonstrukt und dessen Wartung, bis hin zu Paketierung und Verteilung, kümmern. Eine etwas andere Variante, wie man ins Verderben laufen kann, ist Bindung an die Knebellizenzen und Abhängigkeiten von Qt. IMO müsste WxWidgets viel mehr Aufmerksamkeit, Unterstützung und Anerkennung finden, nicht etwa weil das technisch ideal wäre, sondern weil es tatsächlich mit am ehesten ein reales Problem, welches von vielen Entwicklern nicht mal als solches erkannt wird, im Rahmen seiner beschränkten personellen und finanziellen Möglichkeiten, tatsächlich löst (eine Art plattformübergreifender MFC-Ersatz). Solche echten Lösungen sind sehr selten in der IT. Leider steckt zu wenige Manpower dahinter, um das auf das für universellen Einsatz und gute Qualität benötigte Level zu heben (es wird ganz allmählich besser, ist also nicht so, dass man sich dessen nicht bewusst wäre). Für mich wesentlich ist, dass das zugrundeliegende Problem verstanden wurde, was nämlich nur sehr selten passiert. Aus meiner Sicht ist schon das lange Weiterpflegen enorm wertvoll, weil damit gezeigt wird, wie es gehen kann bzw. könnte, kleine Macken hin oder her. SDL hat ja auch etwas von dieser Denkweise. Sonst (wenn es Hipsterkram wäre) hätte mich das jetzt gar nicht interessiert. Ich habe schon, trotz einiger Schwächen, gewisse Sympathien dafür.
Die IT geht völlig falsche Wege, indem sie sich längst ihre Probleme selber konstruiert.