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?
fonte
Respostas:
Estou muito atrasado para esta festa, mas sua pergunta ainda não parece ter uma resposta completa, e é um sucesso bastante proeminente do google.
Eu tenho exatamente o mesmo problema com C ++ / CMake / Git / Submodules e tenho um problema semelhante com MATLAB / Git / Submodules, que obtém alguma estranheza extra porque o MATLAB não é compilado. Me deparei com este vídeo recentemente, que parece propor uma "solução". Não gosto da solução, porque significa essencialmente jogar fora os submódulos, mas elimina o problema. É exatamente como a @errordeveloper recomenda. Cada projeto não possui submódulos. Para criar um projeto, crie um superprojeto para construí-lo e inclua-o como um irmão de suas dependências.
Portanto, seu projeto de desenvolvimento
graph
pode parecer com:e seu projeto para o estúdio pode ser:
Os superprojetos são apenas um
CMakeLists.txt
submodulo principal e um monte. Mas nenhum dos projetos possui submódulos.O único custo que vejo nessa abordagem é a proliferação de "superprojetos" triviais que são dedicados apenas à construção de seus projetos reais. E se alguém se apossar de um de seus projetos, não há uma maneira fácil de saber sem encontrar também o superprojeto, quais são suas dependências. Isso pode torná-lo realmente feio no Github, por exemplo.
fonte
Suponho que, quando você integra os dois
graph
e osnetwork
submódulosstudio
, sempre deve ter a mesma versãocore
em um dado momento da história dostudio
. Gostaria de vincular ostudio/libs/core
submódulo emstudio/libs/{graph,network}/libs
.Atualizar:
Criei vários repositórios com as dependências que você declarou:
v1
ev2
são duas versões diferentes docore
.graph
lida com a versão 2, enquantonetwork
precisa de algum trabalho e está travado na versão 1. Nastudio
, as versões incorporadas locais decore
ambos os pontos apontamv1
para ter um programa de trabalho. Agora, além da perspectiva da construção, tudo funciona bem com os submódulos.Agora posso remover o seguinte diretório:
E substitua-o por um link simbólico:
Eu comprometo localmente essa alteração e perco a capacidade de ter duas versões separadas do
core
insidestudio
, mas eu só construocore
uma vez. Quando estiver pronto para atualizarv2
, posso:... dentro do estúdio / libs / rede.
fonte
graph/libs/core
fora, não está usando o submódulo. Se você vincularstudio/libs/core
a uma das bibliotecas do submódulo, qual você escolherágraph
ounetwork
? Além disso, o que acontece quando tem três ou mais camadas de profundidade? Finalmente, o que secore
pode ser uma série de revisões. Não é óbvio que você deseja vincular a qualquer versão docore
quegraph
enetwork
está usando.core
seria um sub-módulo buscado nacore
biblioteca original , atualizado para uma versão compatível com ambosgraph
enetwork
(você deve decidir qual é o melhor). Os links simbólicos seriam adicionados no localgraph
e nosnetwork
submódulos (não buscados).graph
enetwork
apontariam para fora de seu próprio repositório (por exemplo, em outro lugar dostudio
projeto). Como eles sabem quando usar seu próprio submódulo versus quando usar o link simbólico? Talvez você deva adicionar um exemplo para demonstrar sua linha de pensamento.Eu o aplainaria para ter profundidade de submódulo de apenas um e ter um repositório que conteria todos os módulos como submódulos e nada além do README e dos scripts de construção. Haveria um script de compilação separado para cada um dos pacotes vinculando suas dependências. Caso contrário, você pode ter um repositório separado para um pacote.
fonte
Eu não usaria submódulos.
É tentador, como costumava ser o caso do svn-externals. No entanto, você pode ter certeza de que todos os projetos vinculados ainda estão no mesmo local em um ano? E em cinco?
Portanto, estou simplesmente copiando todas as dependências necessárias no meu projeto. Isso significa que, enquanto meu repo for válido, posso verificar o estado exato.
Basicamente, eu tenho uma estrutura de pastas da seguinte maneira:
Embora isso não seja muito bom do ponto de vista do espaço em disco, valorizo a garantia de que posso verificar todos os estados registrados, desde que o repo esteja disponível muito mais alto.
Além disso, há vários problemas com os submódulos, conforme descrito aqui
fonte
Enfrentando exatamente o mesmo problema aqui. Uma das soluções poderia ser a de ter algum repo
libs
que iria realizarcore
,network
,graph
como submódulos e CMakeLists apenas que iria dizer cada uma das libs onde encontrar suas dependências. Agora, cada aplicativo terialibs
como submódulo e usaria apenas as bibliotecas necessárias.O teste de cada lib pode ser configurado de 2 maneiras:
fonte
graph
não precisa saber sobrenetwork
- não passamnetwork
coisas -relacionados paragraph
subdir