Pre-Compiled-Header, Dependency-Management und Anderes



  • Hallo,
    ich arbeite an einem Privat-Projekt, dessen Größe derzeit noch überschaubar ist. Jedoch habe ich von Anfang an Wert darauf gelegt, eine strikte CMake-Target-Struktur einzuhalten.
    Einige meiner Targets binden teilweise größere Dependencies (z.B. Catch, Godot, boost, ...) ein; manche davon ausschließlich innerhalb eines Targets und andere in mehreren.
    Die Struktur sieht in etwa so aus:

    root
    - src
        - Utility (Interface-Target)
        - Simulation (statische lib; linked Utility)
        - Plugin-Backend (statische lib; linked Simulation)
        - Plugin (dynamische lib; linked Plugin-Backend)
    - tests
        - UtilityTests (executable)
        - SimulationTests (executable)
        - PluginBackendTests (executable)
    

    Dependencies werden in der Regel als PUBLIC/INTERFACE gelinked und somit über alle Targets vererbt.
    Die Tests sind hierbei eigene Executable-Targets, welche sich jeweils ihre Test-Dependencies (Catch2 und mimic++) in das Projekt einziehen.

    Jetzt habe ich zwei Überlegungen/Wünsche, die ich gerne miteinander vereinen würde.

    1. Pre-Compiled-Headers sollen dabei helfen, die Abhängigkeiten nur einmalig zu parsen und dann im gesamten Projekt von einem Compile-Time-Boost zu profitieren.
      Lokal ist mir das nicht so wichtig; da ich mein Projekt allerdings in einem privaten Github-Repo via CI/CD teste, sollte die Laufzeit auch mit zunehmender Größe nicht explodieren (Runner-Laufzeit ist monatlich begrenzt).
    2. Einige Dependencies lassen sich z.B. über Makros konfigurieren. Hierbei ist es dann wichtig, dass dieses Configs vor dem eigentlichen Includes passiert. Dies lagere ich in der Regel in spezielle header aus, jedoch erfordert dies dennoch eine hohe Selbst-Disziplin diese Configs immer und ständig in jede *.cpp als erstes zu include; Fehler passieren hier und bleiben teilweise längere Zeit unentdeckt.
      Durch die PCHs hätte ich die Möglichkeit das auf Target-Ebene festzulegen.

    Nun bin ich derzeit dabei ein CommonDependencies-Target zu erzeugen, welches die geteilten Dependencies aufsammelt (und ggf. konfiguriert) und entsprechend von allen anderen Targets gelinkt wird. Dieses würde dann auch den PCH erzeugen, welcher dann von allen anderen Targets mittels REUSE_FROM-Attribut genutzt wird (dadurch müssen diese Targets den PCH nicht selbst erzeugen, was entsprechend Build-Zeiten einspart).
    Der Nachteil ist, dass ich diesen generierten PCH nicht erweitern kann. D.h. spätestens bei den Test-Targets muss ich dann doch wieder den gesamten PCH neu erzeugen und durch die Test-Dependencies erweitern. Das bringt mich entsprechend wieder zum Zweifeln, ob mein Vorhaben überhaupt der richtige Weg ist oder ob ich mich hier nicht ein wenig verrenne.
    Was ich auf keinen Fall möchte, ist, Targets zusammenzulegen. Ich empfinde das zum einen aus der Draufsicht auf das Projekt als hilfreich und zum anderen ist es für mich beim testen angenehm, mehrere Test-Executables statt nur eines Einzigen zu benutzen. Ggf. würde dies in Zukunft sogar noch granularer aufgeteilt werden. Das möchte ich mir für die Zukunft offen halten.

    Ich denke, ein paar Meinungen oder sogar Erfahrungsberichte würden mir an dieser Stelle durchaus weiterhelfen.

    MfG Dominic

    EDIT: Wären Modules hier ggf. einen Blick wert?



  • @DNKpp sagte in Pre-Compiled-Header, Dependency-Management und Anderes:

    EDIT: Wären Modules hier ggf. einen Blick wert?

    Für die Zukunft ist das sicherlich eine Option. Bisher ist es mir aber nur gelungen mit GCC 14.1.0 oder neuer nicht triviale Beispiele mit GCC als Module zu übersetzen. Da ich dazu GNU make nutzte, kann ich Dir nicht sagen, ob es mit CMake überhaupt geht. Ich habe noch kein perfektes GNU Makefile geschrieben, da er zuweilen Dinge neu übersetzt, die das nicht nötig hätten.

    Wie das nun mit clang aussieht keine Ahnung. Intels Compiler und der von nVidia unterstützen noch keine Module. Sie basieren zwar beide auf clang hinken aber den aktuellen clang Version hinterher.


Anmelden zum Antworten