Je suis un grand fan des sous-modules Git . J'aime pouvoir suivre une dépendance avec sa version, de sorte que vous puissiez revenir à une version précédente de votre projet et disposer de la version correspondante de la dépendance pour construire en toute sécurité et proprement. De plus, il est plus facile de publier nos bibliothèques sous forme de projets open source car l'historique des bibliothèques est séparé de celui des applications qui en dépendent (et qui ne seront pas en open source).
J'établis un flux de travail pour plusieurs projets au travail, et je me demandais ce qui se passerait si nous adoptions cette approche un peu extrême au lieu de n'avoir qu'un seul projet monolithique. J'ai vite compris qu'il y avait un potentiel de ver à utiliser réellement des sous-modules.
Supposons une paire d'applications: studio
et player
, et des bibliothèques dépendantes core
, graph
et network
, où les dépendances sont les suivantes:
core
est autonomegraph
dépend decore
(sous-module à./libs/core
)network
dépend decore
(sous-module à./libs/core
)studio
dépend degraph
etnetwork
(sous-modules à./libs/graph
et./libs/network
)player
dépend degraph
etnetwork
(sous-modules à./libs/graph
et./libs/network
)
Supposons que nous utilisions CMake et que chacun de ces projets comporte des tests unitaires et tous les travaux. Chaque projet (y compris studio
et player
) doit pouvoir être compilé de manière autonome pour effectuer des métriques de code, des tests unitaires, etc.
La chose est, un récursif git submodule fetch
, alors vous obtenez la structure de répertoire suivante:
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/
Notez que core
deux fois cloné dans le studio
projet. Outre ce gaspillage d'espace disque, j'ai un problème de système de génération, car je construis core
deux fois et j'obtiens potentiellement deux versions différentes de core
.
Question
Comment organiser des sous-modules de manière à obtenir la dépendance versionnée et la génération autonome sans obtenir plusieurs copies des sous-modules imbriqués courants?
Solution possible
Si la dépendance de la bibliothèque est en quelque sorte une suggestion (c'est-à-dire d'une manière "connue pour fonctionner avec la version X" ou "seule la version X est officiellement prise en charge") et que les applications ou bibliothèques potentiellement dépendantes sont responsables de la construction avec la version de leur choix, Je pourrais imaginer le scénario suivant:
- Demandez au système de construction de
graph
etnetwork
dites-leur où trouvercore
(par exemple, via un chemin d’inclusion du compilateur). Définissez deux cibles de construction, "autonome" et "dépendance", où "autonome" est basé sur "dépendance" et ajoute le chemin d'inclusion pour pointer vers lecore
sous-module local . - Introduisez une dépendance supplémentaire:
studio
oncore
. Ensuite,studio
buildscore
, définit le chemin d’inclusion sur sa propre copie ducore
sous-module, puis construitgraph
etnetwork
en mode "dépendance".
La structure de dossier résultante ressemble à ceci:
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)
Cependant, cela nécessite un peu de magie du système de construction (je suis assez confiant, cela peut être fait avec CMake) et un peu de travail manuel de la part des mises à jour de version (la mise à jour graph
peut également nécessiter une mise à jour core
et network
obtenir une version compatible de core
tous les projets) .
Des idées à ce sujet?
la source
Réponses:
Je suis très en retard pour ce parti, mais votre question ne semble toujours pas avoir de réponse complète, et c'est un succès assez connu de Google.
J'ai exactement le même problème avec C ++ / CMake / Git / Submodules et j'ai un problème similaire avec MATLAB / Git / Submodules, ce qui génère un surcroît de bizarrerie car MATLAB n'est pas compilé. Je suis tombé sur cette vidéo récemment, qui semble proposer une "solution". Je n'aime pas la solution, parce que cela signifie essentiellement de jeter des sous-modules, mais cela élimine le problème. C'est exactement ce que @errordeveloper recommande. Chaque projet n'a pas de sous-modules. Pour construire un projet, créez un super-projet et intégrez-le en tant que frère de ses dépendances.
Votre projet de développement
graph
pourrait donc ressembler à:et ensuite votre projet de studio pourrait être:
Les super-projets ne sont que
CMakeLists.txt
des sous-modules principaux. Mais aucun des projets n’a de sous-modules eux-mêmes.Le seul coût que je perçois pour cette approche est la prolifération de "super-projets" triviaux qui sont uniquement dédiés à la construction de vos vrais projets. Et si quelqu'un met la main sur l'un de vos projets, il n'existe pas de moyen facile de savoir sans trouver également le super-projet quelles sont ses dépendances. Cela pourrait le rendre vraiment moche sur Github, par exemple.
la source
Je suppose que lorsque vous intégrez les deux
graph
et lesnetwork
sous - modules dansstudio
, vous devez toujours avoir la même version decore
à un moment donné dans l'histoire destudio
. Je voudrais simlink lestudio/libs/core
sous - module dansstudio/libs/{graph,network}/libs
.Mise à jour:
J'ai créé plusieurs référentiels avec les dépendances que vous avez indiquées:
v1
etv2
sont deux versions différentes decore
.graph
gère la version 2, alors quenetwork
nécessite un peu de travail et est bloqué à la version 1. Dansstudio
, les versions locales incorporées descore
deux points àv1
pour avoir un programme de travail. Maintenant, en dehors de la perspective de construction, tout fonctionne bien avec les sous-modules.Je peux maintenant supprimer le répertoire suivant:
Et remplacez-le par un lien symbolique:
J'engage localement ce changement et perd la possibilité d'avoir deux versions distinctes de
core
insidestudio
, mais je ne construiscore
qu'une seule fois. Quandv2
je suis prêt à passer à , je peux faire:... dans studio / libs / network.
la source
graph/libs/core
l'extérieur, vous n'utilisez pas le sous-module. Si vous vous connectezstudio/libs/core
à l'une des bibliothèques du sous-module, laquelle choisissez-vousgraph
ounetwork
? De plus, que se passe-t-il quand il y a trois couches ou plus de profondeur? Enfin, que se passe-t-il sicore
peut être une gamme de révisions. Il n'est pas évident que vous souhaitiez créer un lien vers l'une ou l'autre version etcore
que vous l' utilisiez.graph
network
core
serait un sous-module extrait de lacore
bibliothèque d' origine , mis à jour vers une version compatible à la foisgraph
etnetwork
(vous devez choisir celle qui convient). Les liens symboliques seraient ajoutés dans les sousgraph
-network
modules locaux et (non récupérés).graph
etnetwork
pointeraient en dehors de leur propre référentiel (par exemple, ailleurs dans lestudio
projet). Comment savent-ils quand utiliser leur propre sous-module et quand utiliser le lien symbolique? Peut-être devriez-vous ajouter un exemple pour illustrer votre pensée.Je voudrais l'aplatir pour avoir une profondeur de sous-module d'un seul et avoir un référentiel qui contiendrait tous les modules en tant que sous-modules et rien d'autre en dehors de README et des scripts de construction. Il y aurait un script de construction séparé pour chacun des paquets reliant ses dépendances. Sinon, vous pouvez avoir un référentiel séparé pour un package.
la source
Je n'utiliserais pas de sous-modules.
C'est tentant, comme c'était le cas avec svn-externals. Cependant, pouvez-vous être sûr que tous les projets que vous associez sont toujours au même endroit au cours d'une année? Qu'en est-il dans cinq?
Par conséquent, je copie simplement toutes les dépendances requises dans mon projet. Cela signifie que tant que mon rapport est valide, je peux vérifier l'état exact.
Fondamentalement, j'ai une structure de dossier comme suit:
Bien que cela ne soit pas très intéressant du point de vue de l'espace disque, j'apprécie de pouvoir vérifier chaque état enregistré tant que le référentiel est disponible bien plus haut.
En outre, il existe toute une série de problèmes avec les sous-modules décrits ici
la source
Face exactement au même problème ici. L' une des solutions pourrait être d'avoir une pension
libs
qui détiendraitcore
,network
,graph
comme et seulement CMakeLists sous - modules qui raconterait chacun des libs où trouver ses dépendances. Chaque application aurait maintenantlibs
comme sous-module et n'utiliserait que les bibliothèques nécessaires.Le test de chaque bibliothèque peut être configuré de 2 manières:
la source
graph
vous n'avez pas besoin de savoir surnetwork
- ne transmettez pas lesnetwork
éléments liés augraph
sous