Ich bin ein großer Fan von Git-Submodulen . Ich möchte in der Lage sein, eine Abhängigkeit zusammen mit ihrer Version zu verfolgen, so dass Sie ein Rollback auf eine frühere Version Ihres Projekts durchführen und die entsprechende Version der Abhängigkeit sicher und sauber erstellen können. Darüber hinaus ist es einfacher, unsere Bibliotheken als Open-Source-Projekte freizugeben, da die Historie für Bibliotheken von der der Anwendungen, die von ihnen abhängen (und die nicht aus Open-Source-Quellen stammen), getrennt ist.
Ich richte den Workflow für mehrere Projekte bei der Arbeit ein und fragte mich, wie es wohl wäre, wenn wir diesen Ansatz ein wenig extrem nehmen würden, anstatt nur ein einziges monolithisches Projekt zu haben. Ich stellte schnell fest, dass es eine potenzielle Dose Würmer gibt, wenn man wirklich Submodule verwendet.
Nimmt man ein Paar von Anwendungen: studio
und player
, und abhängigen Bibliotheken core
, graph
und network
, wo Abhängigkeiten sind wie folgt:
core
ist eigenständiggraph
abhängig voncore
(Submodul bei./libs/core
)network
abhängig voncore
( Submodul bei./libs/core
)studio
abhängig vongraph
undnetwork
(Untermodule bei./libs/graph
und./libs/network
)player
abhängig vongraph
undnetwork
(Untermodule bei./libs/graph
und./libs/network
)
Angenommen, wir verwenden CMake und jedes dieser Projekte hat Unit-Tests und alle Arbeiten. Jedes Projekt (einschließlich studio
und player
) muss eigenständig kompiliert werden können, um Codemetriken, Komponententests usw. durchzuführen.
Die Sache ist, eine rekursive git submodule fetch
, dann erhalten Sie die folgende Verzeichnisstruktur:
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/graph/
studio/libs/graph/libs/ (sub-module depth: 2)
studio/libs/graph/libs/core/
studio/libs/network/
studio/libs/network/libs/ (sub-module depth: 2)
studio/libs/network/libs/core/
Beachten Sie, dass core
im studio
Projekt zweimal geklont wird . Abgesehen von dieser Verschwendung von Speicherplatz habe ich ein Build-System-Problem, weil ich core
zweimal baue und möglicherweise zwei verschiedene Versionen von bekomme core
.
Frage
Wie organisiere ich Submodule, damit ich die versionierte Abhängigkeit und den Standalone-Build erhalte, ohne mehrere Kopien von häufig verschachtelten Submodulen zu erhalten?
Mögliche Lösung
Wenn die Bibliotheksabhängigkeit eher ein Vorschlag ist (dh "bekanntermaßen mit Version X arbeiten" oder "nur Version X wird offiziell unterstützt") und potenziell abhängige Anwendungen oder Bibliotheken für die Erstellung mit einer beliebigen Version verantwortlich sind, dann Ich könnte mir folgendes Szenario vorstellen:
- Haben Sie das Build-System für
graph
undnetwork
teilen Sie ihnen mit, wo sie zu finden sindcore
(z. B. über einen Compiler-Include-Pfad). Definieren Sie zwei Build-Ziele, "Standalone" und "Abhängigkeit", wobei "Standalone" auf "Abhängigkeit" basiert und den Include-Pfad hinzufügt, der auf das lokalecore
Untermodul verweist. - Fügen Sie eine zusätzliche Abhängigkeit hinzu:
studio
oncore
. Dannstudio
bautcore
, setzt den Include-Pfad auf seine eigene Kopie descore
Submoduls, baut danngraph
undnetwork
im "Abhängigkeits" -Modus.
Die resultierende Ordnerstruktur sieht folgendermaßen aus:
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/core/
studio/libs/graph/
studio/libs/graph/libs/ (empty folder, sub-modules not fetched)
studio/libs/network/
studio/libs/network/libs/ (empty folder, sub-modules not fetched)
Dies erfordert jedoch etwas Magie für das Build-System (ich bin mir ziemlich sicher, dass dies mit CMake möglich ist) und ein wenig manuelle Arbeit seitens der Versionsaktualisierungen (Aktualisierungen graph
erfordern möglicherweise auch Aktualisierungen core
und network
eine kompatible Version von core
allen Projekten). .
Irgendwelche Gedanken dazu?