Externe Abhängigkeiten managen & VCPKG

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Jonathan
Establishment
Beiträge: 2644
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Externe Abhängigkeiten managen & VCPKG

Beitrag von Jonathan »

Ich habe jetzt mal in Rahmen eines Projektes vcpkg ausprobiert. Speziell unter Windows ist C++ kompilieren ja die Hölle, insbesondere mit Abhängigkeiten und sowas wie conda oder pip für Python gibt es so ja erstmal nicht für C++. So erschien es mir zumindest lange, auch, weil ich einfach nicht viel gesucht habe. Aber ein paar Ansätze gibt es schon. vcpkg scheint mit Abstand am etabliertesten zu sein, nur hab ich das bisher immer ignoriert, weil es ja letztendlich selber auch erstmal nur eine weitere Abhängigkeit ist, die Ärger machen könnte. (Das ist ein wenig so wie wenn man für irgendein Problemchen ein nettes Skript findet, was es automatisch und perfekt löst, aber dann ist es in Perl geschrieben und man muss erstmal sehen, wie man das unter Windows ans laufen kriegt und dann fragt man sich, ob es den Ärger überhaupt wert ist.)

Aber siehe da, es funktioniert erstaunlich gut. Man kann es nett mit CMake kombinieren und einfach eine Liste an Paketnamen definieren, die dann automatisch heruntergeladen werden und die Pfade entsprechend gesetzt werden. Es hat ein wenig Zeit gekostet, das ganze System zu verstehen und die Abhängigkeiten richtig zu definieren, aber danach klappen selbst komplexere Dinge wie assimp einfach so ohne weiteres zutun.

Ironischerweise war aber eine Abhängigkeit die ich brauchte, stb. Was eine Sammlung an Header-only Bibliotheken ohne eigene Abhängigkeiten ist, darauf optimiert sie möglichst einfach dem eigenen Projekt hinzuzufügen. Nach 20 Minuten Arbeit klappte es dann auch, dass die automatisch heruntergeladen und benutzt werden (das erste Mal dauert ja immer länger). Aber, und das ist dann die Ironie, ich hätte stb halt auch einfach in meinen Projektordner kopieren können. Dann würde es auch direkt automatisch kompilieren, und ich bräuchte erst gar kein VCPKG.

Was ist letztendlich der Unterschied? Klar, eine Kopie braucht erstmal ein wenig Speicher, aber hey, die aller wenigsten Projekte haben mehr als ein paar MB Code, und jedes Asset im Spiel ist halt größer als das, also ist das kein wirkliches Argument. Jeder Paketmanager bringt Komplexität mit sich, mehr Dinge die kaputt gehen können. Was, wenn mal ein Repository nicht mehr verfügbar ist? Was, wenn man mal offline ist? Wird meistens kein Problem sein, aber alles lokal gebündelt zu haben hat halt 0 dieser Risiken.

Man könnte dann sagen, "Aber was ist mit Versionsverwaltung und automatischen Updates?" Lokal gebündelte Abhängigkeiten haben per Definition nicht das Problem, dass die falsche Version installiert sein kann, was schonmal nett ist. Updaten ist natürlich potentiell mehr aufwand (man muss die neue Version runterladen und ggf. per Hand in sein Projekt integrieren). Allerdings will ich im Zweifelsfalle die Updates ja gar nicht haben, schließlich könnten die inkompatibel sein. Brauche ich ein neues Feature, dann kann ich von Hand upgraden, da das nicht jede Woche passiert, ist etwas extra-Aufwand dann auch ok. Ausnahmen könnten Sicherheitslücken sein, aber ganz ehrlich, ich mache Spiele, wenn da mein Texture-Loader aus lustigen Gründen Code ausführen kann müsste es erstmal eine Mechanik geben, durch die manipulierte Assets in mein Spiel kommen. Und die gibt es halt nicht.

Am Ende des Tages passiert es eben doch oft genug, dass ich alle paar Monate mal 1-2 Tage damit zubringe, irgendetwas mit komplizierten Abhängigkeiten zum Kompilieren zu bewegen. Möglichst viel lokal zu bündeln eliminiert viele Fehler, bevor sie entstehen können und das beste Build-Script ist eines was nichts tut außer zu sagen "kompiliere einfach alle Dateien in diesem Ordner - fertig".

Einen ähnlichen Ansatz gibt es ja mit git und submodules. In der Theorie klingen die sehr nett, aber in der Praxis wird es dann doch oft schnell kompliziert und ich hatte öfters schon lustige Merge-Konflikte, die dann erstmal einen halben Tag gekostet haben. Und dann hat man ja auch so prinzipielle Probleme, wie "Wie clone ich ein Repository?" Vielleicht hab ich mein Projekt ja in "Engine" und "Game" aufgeteilt und benutze "assimp", und möchte damit jetzt auf einen neuen Server umziehen, jetzt muss ich aber zwischen flacher und tiefer Kopie unterscheiden, weil Engine und Game kopiert, das offizielle Assimp repository aber weiter referenziert werden soll. Vielleicht weiß der Profi sofort, wie man das macht, aber für mich erzeugt es erstmal Komplexität, die ich dann ja auch allen potentiellen Mitstreiter, die vielleicht keine git-Helden sind, direkt mit aufzwinge. Hmhmmm.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Antworten