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: studioy player, y bibliotecas dependientes core, graphy network, donde las dependencias son las siguientes:
corees independientegraphdepende decore(submódulo en./libs/core)networkdepende decore(submódulo en./libs/core)studiodepende degraphynetwork(submódulos en./libs/graphy./libs/network)playerdepende degraphynetwork(submódulos en./libs/graphy./libs/network)
Supongamos que estamos usando CMake y que cada uno de estos proyectos tiene pruebas unitarias y todos los trabajos. Cada proyecto (incluido studioy 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 corese clona dos veces en el studioproyecto. Además de este desperdicio de espacio en disco, tengo un problema de sistema de compilación porque estoy compilando coredos 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
graphynetworkdí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 alcoresubmódulo local . - Introducir una dependencia adicional:
studiooncore. Luego,studiocompilacore, establece la ruta de inclusión a su propia copia delcoresubmódulo, luego construyegraphynetworken 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 graphtambién puede requerir la actualización corey networkobtener una versión compatible coreen 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
graphpodría verse así:y luego tu proyecto para estudio podría ser:
Los superproyectos son solo un
CMakeLists.txtsubmó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
graphynetworksubmódulosstudio, siempre debe tener la misma versión decoreen un momento dado en la historia destudio. Me gustaría vincular elstudio/libs/coresubmódulo enstudio/libs/{graph,network}/libs.Actualizar:
Creé múltiples repositorios con las dependencias que usted indicó:
v1yv2son dos versiones diferentes decore.graphmaneja la versión 2, mientras quenetworknecesita algo de trabajo y está atascado en la versión 1. Enstudio, las versiones locales incrustadas decoreambos puntosv1para 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
coreadentrostudio, pero solo construyocoreuna vez. Cuando estoy listo para actualizarv2, puedo hacer:... dentro de studio / libs / network.
fuente
graph/libs/coreel exterior, no está utilizando el submódulo. Si vincula desdestudio/libs/coreuna de las bibliotecas propias del submódulo, ¿cuál elige,graphonetwork? Además, ¿qué sucede cuando tiene tres o más capas de profundidad? Finalmente, ¿qué pasa sicorepuede haber una variedad de revisiones? No es obvio que desea vincular a cualquiera de las versiones decoreesographynetworkestá utilizando.coresería un submódulo obtenido de lacorebiblioteca original , actualizado a una versión que sea compatible con ambosgraphynetwork(debe decidir cuál es el correcto). Los enlaces simbólicos se agregarían en los submódulos localesgraphynetwork(sin recuperar).graphynetworkapuntarían fuera de su propio repositorio (por ejemplo, en otro lugar delstudioproyecto). ¿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
libsque sostendríacore,network,graphcomo submódulos y CMakeLists sólo que contarían cada una de las librerías donde encontrar sus dependencias. Cada aplicación ahora tendríalibscomo submódulo y usaría solo las librerías necesarias.La prueba de cada lib podría configurarse de 2 maneras:
fuente
graphno necesita sabernetwork, no pasenetworkcosas relacionadas congraphsubdirigir