Soy un gran admirador de los submódulos Git . Me gusta poder rastrear una dependencia junto con su versión, para que pueda retroceder a una versión anterior de su proyecto y tener la versión correspondiente de la dependencia para construir de forma segura y limpia. Además, es más fácil lanzar nuestras bibliotecas como proyectos de código abierto, ya que el historial de las bibliotecas es independiente del de las aplicaciones que dependen de ellas (y que no serán de código abierto).
Estoy configurando el flujo de trabajo para múltiples proyectos en el trabajo, y me preguntaba cómo sería si tomáramos este enfoque un poco extremo en lugar de tener un solo proyecto monolítico. Rápidamente me di cuenta de que es una lata potencial de gusanos en realidad el uso de sub-módulos.
Supongamos un par de aplicaciones: studio
y player
, y bibliotecas dependientes core
, graph
y network
, donde las dependencias son las siguientes:
core
es independientegraph
depende decore
(submódulo en./libs/core
)network
depende decore
(submódulo en./libs/core
)studio
depende degraph
ynetwork
(submódulos en./libs/graph
y./libs/network
)player
depende degraph
ynetwork
(submódulos en./libs/graph
y./libs/network
)
Supongamos que estamos usando CMake y que cada uno de estos proyectos tiene pruebas unitarias y todos los trabajos. Cada proyecto (incluido studio
y player
) debe poder compilarse de forma independiente para realizar métricas de código, pruebas unitarias, etc.
La cosa es que, de forma recursiva git submodule fetch
, obtienes la siguiente estructura de directorios:
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/
Tenga en cuenta que core
se clona dos veces en el studio
proyecto. Además de este desperdicio de espacio en disco, tengo un problema de sistema de compilación porque estoy compilando core
dos veces y potencialmente obtengo dos versiones diferentes de core
.
Pregunta
¿Cómo organizo los submódulos para obtener la dependencia versionada y la compilación independiente sin obtener múltiples copias de submódulos anidados comunes?
Solución posible
Si la dependencia de la biblioteca es algo así como una sugerencia (es decir, en una forma "conocida por funcionar con la versión X" o "solo la versión X es oficialmente compatible") y las aplicaciones o bibliotecas dependientes potenciales son responsables de construir con la versión que deseen, entonces Me imagino el siguiente escenario:
- Tenga el sistema de compilación
graph
ynetwork
dígales dónde encontrarcore
(por ejemplo, a través de una ruta de inclusión del compilador). Defina dos objetivos de compilación, "independiente" y "dependencia", donde "independiente" se basa en "dependencia" y agrega la ruta de inclusión para apuntar alcore
submódulo local . - Introducir una dependencia adicional:
studio
oncore
. Luego,studio
compilacore
, establece la ruta de inclusión a su propia copia delcore
submódulo, luego construyegraph
ynetwork
en modo de "dependencia".
La estructura de carpetas resultante se ve así:
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)
Sin embargo, esto requiere un poco de magia del sistema de compilación (estoy bastante seguro de que esto se puede hacer con CMake) y un poco de trabajo manual por parte de las actualizaciones de la versión (la actualización graph
también puede requerir la actualización core
y network
obtener una versión compatible core
en todos los proyectos) .
Tiene alguna idea sobre esto?
fuente
Respuestas:
Llego muy tarde a esta fiesta, pero su pregunta aún no parece tener una respuesta completa, y es un éxito bastante destacado de Google.
Tengo exactamente el mismo problema con C ++ / CMake / Git / Submodules y tengo un problema similar con MATLAB / Git / Submodules, lo que tiene una rareza adicional porque MATLAB no está compilado. Me encontré con este video recientemente, que parece proponer una "solución". No me gusta la solución, porque esencialmente significa tirar submódulos, pero elimina el problema. Es tal como lo recomienda @errordeveloper. Cada proyecto no tiene submódulos. Para construir un proyecto, cree un superproyecto para construirlo e inclúyalo como hermano de sus dependencias.
Entonces su proyecto para el desarrollo
graph
podría verse así:y luego tu proyecto para estudio podría ser:
Los superproyectos son solo un
CMakeLists.txt
submódulo principal y un montón de submódulos. Pero ninguno de los proyectos tiene submódulos.El único costo que veo para este enfoque es la proliferación de "superproyectos" triviales que solo se dedican a construir sus proyectos reales. Y si alguien obtiene uno de sus proyectos, no hay una manera fácil de saber sin encontrar también el superproyecto, cuáles son sus dependencias. Eso podría hacer que se sienta realmente feo en Github, por ejemplo.
fuente
Supongo que cuando integra ambos
graph
ynetwork
submódulosstudio
, siempre debe tener la misma versión decore
en un momento dado en la historia destudio
. Me gustaría vincular elstudio/libs/core
submódulo enstudio/libs/{graph,network}/libs
.Actualizar:
Creé múltiples repositorios con las dependencias que usted indicó:
v1
yv2
son dos versiones diferentes decore
.graph
maneja la versión 2, mientras quenetwork
necesita algo de trabajo y está atascado en la versión 1. Enstudio
, las versiones locales incrustadas decore
ambos puntosv1
para tener un programa de trabajo. Ahora, aparte de la perspectiva de construcción, todo funciona bien con submódulos.Ahora puedo eliminar el siguiente directorio:
Y reemplácelo con un enlace simbólico:
Confirmo localmente este cambio y pierdo la capacidad de tener dos versiones separadas de
core
adentrostudio
, pero solo construyocore
una vez. Cuando estoy listo para actualizarv2
, puedo hacer:... dentro de studio / libs / network.
fuente
graph/libs/core
el exterior, no está utilizando el submódulo. Si vincula desdestudio/libs/core
una de las bibliotecas propias del submódulo, ¿cuál elige,graph
onetwork
? Además, ¿qué sucede cuando tiene tres o más capas de profundidad? Finalmente, ¿qué pasa sicore
puede haber una variedad de revisiones? No es obvio que desea vincular a cualquiera de las versiones decore
esograph
ynetwork
está utilizando.core
sería un submódulo obtenido de lacore
biblioteca original , actualizado a una versión que sea compatible con ambosgraph
ynetwork
(debe decidir cuál es el correcto). Los enlaces simbólicos se agregarían en los submódulos localesgraph
ynetwork
(sin recuperar).graph
ynetwork
apuntarían fuera de su propio repositorio (por ejemplo, en otro lugar delstudio
proyecto). ¿Cómo saben cuándo usar su propio submódulo versus cuándo usar el enlace simbólico? Quizás debería agregar un ejemplo para demostrar su línea de pensamiento.Lo aplanaría para tener una profundidad de submódulo de solo uno y un repositorio que contendría todos los módulos como submódulos y nada más aparte de README y los scripts de compilación. Habría un script de compilación separado para cada uno de los paquetes que vinculan sus dependencias. De lo contrario, puede tener un repositorio separado para un paquete.
fuente
No usaría submódulos.
Es tentador, igual que solía ser el caso con svn-externals. Sin embargo, ¿puede estar seguro de que todos los proyectos que vincula siguen en el mismo lugar en un año? ¿Qué tal en cinco?
Por lo tanto, simplemente estoy copiando todas las dependencias requeridas en mi proyecto. Esto significa que mientras mi repositorio sea válido, puedo verificar el estado exacto.
Básicamente, tengo una estructura de carpetas de la siguiente manera:
Si bien esto no es muy bueno desde la perspectiva del espacio en disco, valoro la garantía de que puedo verificar cada estado registrado siempre que el repositorio esté disponible mucho más alto.
Además, hay un montón de problemas con los submódulos como se describe aquí
fuente
Enfrentando exactamente el mismo problema aquí. Una de las soluciones podría ser tener un poco de recompra
libs
que sostendríacore
,network
,graph
como submódulos y CMakeLists sólo que contarían cada una de las librerías donde encontrar sus dependencias. Cada aplicación ahora tendríalibs
como submódulo y usaría solo las librerías necesarias.La prueba de cada lib podría configurarse de 2 maneras:
fuente
graph
no necesita sabernetwork
, no pasenetwork
cosas relacionadas congraph
subdirigir