Sou um grande fã dos submódulos do Git . Eu gosto de poder rastrear uma dependência junto com sua versão, para que você possa reverter para uma versão anterior do seu projeto e ter a versão correspondente da dependência para criar de forma segura e limpa. Além disso, é mais fácil lançar nossas bibliotecas como projetos de código aberto, pois o histórico das bibliotecas é separado daquele dos aplicativos que dependem deles (e que não serão de código aberto).
Estou configurando o fluxo de trabalho para vários projetos no trabalho e fiquei imaginando como seria se adotássemos essa abordagem um pouco de extremo, em vez de ter um único projeto monolítico. Eu rapidamente percebi que não é uma lata potencial de vermes em realmente usando sub-módulos.
Supondo um par de aplicativos: studio
e player
, e bibliotecas dependentes core
, graph
e network
, onde as dependências são as seguintes:
core
é autônomograph
dependecore
(submódulo em./libs/core
)network
depdends oncore
(submódulo em./libs/core
)studio
dependegraph
enetwork
(sub-módulos em./libs/graph
e./libs/network
)player
dependegraph
enetwork
(sub-módulos em./libs/graph
e./libs/network
)
Suponha que estamos usando o CMake e que cada um desses projetos tenha testes de unidade e todos os trabalhos. Cada projeto (incluindo studio
e player
) deve poder ser compilado de forma independente para executar métricas de código, testes de unidade etc.
A coisa é, uma recursiva git submodule fetch
, então você obtém a seguinte estrutura de diretório:
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/
Observe que core
é clonado duas vezes no studio
projeto. Além desse desperdício de espaço em disco, tenho um problema no sistema de compilação porque estou construindo core
duas vezes e potencialmente recebo duas versões diferentes do core
.
Pergunta, questão
Como organizo os submódulos para obter a dependência com versão e a construção autônoma sem obter várias cópias dos submódulos aninhados comuns?
Solução possível
Se a dependência da biblioteca é uma sugestão (por exemplo, "conhecida por funcionar com a versão X" ou "apenas a versão X é oficialmente suportada") e os aplicativos ou bibliotecas dependentes em potencial são responsáveis por criar a versão que quiserem, então Eu poderia imaginar o seguinte cenário:
- Tenha o sistema de compilação
graph
enetwork
diga a eles onde encontrarcore
(por exemplo, através de um caminho de inclusão do compilador). Defina dois destinos de construção, "autônomo" e "dependência", em que "autônomo" é baseado em "dependência" e adiciona o caminho de inclusão para apontar para ocore
submódulo local . - Introduzir uma dependência extra:
studio
oncore
. Em seguida,studio
criacore
, define o caminho de inclusão para sua própria cópia docore
submódulo e depois criagraph
enetwork
no modo "dependência".
A estrutura de pastas resultante se parece com:
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)
No entanto, isso requer alguma mágica do sistema de compilação (estou bastante confiante de que isso pode ser feito com o CMake) e um pouco de trabalho manual por parte das atualizações de versão (a atualização graph
também pode exigir atualização core
e network
obter uma versão compatível core
em todos os projetos) .
Alguma idéia sobre isso?