Binários no controle de origem


30

Ao desenvolver para dispositivos incorporados e outros mundos estranhos, é muito provável que seu processo de compilação inclua vários binários proprietários, usando versões muito específicas deles. Portanto, a questão é: eles fazem parte do seu controle de origem? Meus escritórios seguem a regra de "fazer check-out do controle de origem inclui tudo o que você precisa para compilar o código" e isso levou a alguns argumentos sérios.

Os principais argumentos que vejo contra isso estão inchando o banco de dados de controle de origem, a falta de arquivos binários diferentes ( consulte as perguntas anteriores sobre o assunto) . Isso é contra a capacidade de verificar, criar, sabendo que você tem o ambiente exato que o desenvolvedor anterior pretendia e sem procurar os arquivos apropriados (com versões específicas, pelo menos!)


3
Como alternativa, você pode escrever o script bash / python / perl / bat para verificar a fonte e fazer o download de todos os outros componentes dependentes em uma única etapa. No entanto, eu ainda recomendaria verificar os binários no seu controle de versão, apenas para manter as revisões. Os únicos arquivos que não devem ser verificados no repositório são aqueles que podem ser facilmente regenerados a partir de arquivos controlados por versão. O espaço em disco é barato e não deve ser uma consideração importante.
Lie Ryan

Respostas:


28

A idéia do VERSION CONTROL (nome impróprio: controle de origem) é permitir que você reverta o histórico, recupere o efeito das mudanças, veja as mudanças e por que as fez. Essa é uma variedade de requisitos, alguns dos quais precisam de coisas binárias, outros não.

Exemplo: Para o trabalho de firmware incorporado, você normalmente terá uma cadeia de ferramentas completa: um compilador proprietário que custa muito dinheiro ou alguma versão do gcc. Para obter o executável da remessa, você precisa da cadeia de ferramentas e da fonte.

Verificar as cadeias de ferramentas no controle de versão é uma tarefa difícil, os utilitários diff são horríveis (se houver), mas não há alternativa. Se você deseja que a cadeia de ferramentas seja preservada para o cara que procura seu código em cinco anos para descobrir o que faz, então não tem escolha: você DEVE ter a cadeia de ferramentas sob controle de versão também.

Ao longo dos anos, descobri que o método mais simples de fazer isso é criar uma imagem ZIP ou ISO do CD de instalação e fazer check-in. O comentário do check-in precisa ser o número da versão específica do fabricante da cadeia de ferramentas. Se gcc ou similar, agrupe tudo o que você está usando em um grande ZIP e faça o mesmo.

O caso mais extremo que eu já fiz foi o Windows XP Embedded, em que a "cadeia de ferramentas" é uma VM do Windows XP em execução, que incluía (naquela época) o SQL Server e uma pilha de arquivos de configuração, juntamente com centenas e centenas de arquivos de correção. Instalar o lote inteiro e atualizá-lo costumava levar cerca de 2-3 dias. Preservar isso para a posteridade significava verificar a VM INTEIRA no controle de versão. Visto que o disco virtual era composto por imagens de cerca de 6 x 2 GB, ele realmente foi muito bem. Parece exagerado, mas tornou a vida muito fácil para a pessoa que veio atrás de mim e precisou usá-la - cinco anos depois.

Resumo: O controle de versão é uma ferramenta. Use-o para ser eficaz, não se prenda a coisas como o significado das palavras e não o chame de "controle de origem" porque é maior que isso.


11
E quando a VM precisa ser atualizada, seus balões de repo para 12 GB? Mesmo se você tiver bom binário diffs o seu ainda falando um 10GB + repo
TheLQ

3
Bem não. Se você usa o VMWare, pode usar instantâneos de disco. Eles armazenam a imagem original do disco da linha de base e adicionam novos arquivos contendo apenas os deltas, que são bem pequenos. Você só precisa se lembrar de verificar os arquivos recém-criados. Por último, observei isso: uma atualização adicionou cerca de 250 mil rações de frango. Além disso, preocupar-se com o tamanho do repositório é inútil - o disco é barato.
quickly_now

Que tal quando sua cadeia de ferramentas incorporada depende de uma licença de rede :)
Dan

18

Neal Ford argumenta no The Productive Programmer que você deve manter binários no controle de origem:

Por que manter binários? Hoje, os projetos dependem de uma variedade de ferramentas e bibliotecas externas. Digamos que você esteja usando uma das estruturas de log populares (como Log4J ou Log4Net). Se você não criar os binários para essa biblioteca de log como parte do processo de criação, mantenha-o no controle de versão. Isso permite que você continue construindo seu software, mesmo que a estrutura ou a biblioteca em questão desapareça (ou, mais provavelmente, introduza uma mudança significativa em uma nova versão). Mantenha sempre todo o universo necessário para construir seu software no controle de versão(menos o sistema operacional, e até isso é possível com a virtualização; consulte “Usar virtualização”, posteriormente neste capítulo). Você pode otimizar os binários de retenção, mantendo-os no controle de versão e em uma unidade de rede compartilhada. Dessa forma, você não precisa lidar com eles a cada hora, mas eles são salvos caso você precise reconstruir algo um ano depois. Você nunca sabe se precisará reconstruir algo. Você o constrói até que funcione e depois esquece. É indutor de pânico perceber que você precisa reconstruir algo de dois anos atrás e não tem todas as partes.

Eu não poderia concordar mais; enquanto isso está subvertendo o VCS para uma tarefa para a qual não foi projetado (mantendo binários), acho que os benefícios superam as desvantagens potenciais. Mas, como o autor observa mais tarde, às vezes manter os binários no VCS pode não ser uma solução prática; portanto, outras opções devem ser consideradas - como mantê-los em uma unidade de rede mapeada.

Se os binários não forem muito grandes, eu definitivamente os manteria no VCS. Isso parece ser ainda mais verdadeiro no seu caso, pois os binários são provavelmente pequenos e você trabalha com versões muito específicas. Eles também podem ser difíceis de encontrar, devido a vários motivos (os autores encerraram o site ou a versão necessária não está mais listada para download). Embora improvável, você nunca sabe o que acontecerá em alguns anos.

Eu gostaria de ler este livro há alguns anos atrás, quando estava trabalhando em um jogo usando uma biblioteca de gráficos (que era um arquivo dll); Interrompi o desenvolvimento por um tempo e, quando quis continuar, não consegui encontrar a dll novamente porque o projeto morreu.


2
Sim, isso acontece com muita frequência. Eu tenho um projeto de hobby em que confio em um gerador de scanner que foi abandonado por seu autor há 3-4 anos. Felizmente, ele sempre esteve sob controle de versão.
Christian Klauser

9

Em princípio, aprecio o campo "verifique tudo o que você precisa para incorporar no controle de origem", mas o gerenciamento de dependências evoluiu bastante nos últimos anos, com ferramentas como Maven, Ivy e NuGet.

Além disso, na prática, encontro binários de check-in para criar vários efeitos colaterais desagradáveis. O Git / Mercurial não está realmente preparado para isso, por exemplo, e o Subversion e o Perforce podem deixá-lo maluco ao mesclar ramificações que contêm binários.

Com uma solução de gerenciamento de dependências, você especifica em um arquivo controlado por fonte em seu projeto quais nomes de pacotes e de quais versões seu projeto depende. Quase todas as ferramentas de gerenciamento de dependências permitem criar um repositório privado de suas dependências, seguindo algum tipo de convenção de versão e nomenclatura; Quando você cria uma compilação, a ferramenta de gerenciamento de dependências resolve todas as dependências de código-fonte aberto e proprietárias de uma lista de fontes aprovadas e as coloca no cache local. Da próxima vez que você criar com as mesmas dependências de versão, tudo já estará lá e será muito mais rápido.

O backup do seu repositório privado pode ser feito com ferramentas convencionais de backup do sistema de arquivos.

Isso evita as lentidões que eu experimentei quando vários binários estão sendo extraídos da árvore de origem e evita que seu repositório tenha muitos arquivos difíceis de diferenciar. Há apenas um local para qualquer dependência, por nome e número da versão, portanto, não há conflitos de mesclagem a serem tratados, e o cache do sistema de arquivos local significa que você não precisa lidar com o custo de avaliar se sua cópia local foi alterada quando você puxa atualizações.


8

O controle de fonte é para fontes. As fontes são o que você não consegue construir com outras coisas. Alguns arquivos que se qualificam como fontes são binários.

Meu VCS tem muitos binários verificados, mas cada um é a unidade de lançamento de algum produto que não escrevi e não mantenho. Isso pode ser algo como o GNU ccRTP, que é lançado como um tarball compactado. Esse tarball é minha fonte e é verificado junto com qualquer infraestrutura necessária para transformá-lo em um produto acabado (uma Makefile e uma especificação de RPM no meu caso) em uma única etapa automatizada. Quando há uma nova versão do ccRTP, trato o novo tarball como uma fonte alterada: ele entra em uma cópia de check-out, é construído, testado e confirmado no VCS. Fiz o mesmo com produtos comerciais que não são fornecidos com o código-fonte (compiladores, bibliotecas etc.) e funciona da mesma maneira. Em vez de descompactar-configurar-compilar-pacote, é apenas descompactar-pacote. O software que faz as compilações noturnas nãomake e obtenha produtos acabados.

A maioria dos VCS possui recursos que tornam a fonte legível por humanos mais fácil de lidar e mais eficiente para armazenar, mas dizer que eles não são adequados para binários não é realmente verdade se os binários colocados voltarem sem serem molestados. O modo como um VCS lida com os binários internamente depende inteiramente se seus autores pensaram ou não que apenas tentar armazenar diferenças valia o esforço. Pessoalmente, acho que armazenar cópias completas de uma distribuição ccRTP a 600K por pop é mais do que compensado pela capacidade de marcar uma versão dela junto com todas as minhas outras fontes.


4

Isso me lembra o problema "jars in repository" que há algum tempo o Java tinha. As pessoas que criavam aplicativos java eram usadas para enviar suas dependências (arquivos jar binários) para os repositórios. Todo mundo ficou feliz com isso, porque você teria um sistema de criação em "um clique" e o espaço em disco é barato, então quem se importa. Então veio o Maven e você pode se livrar de todo esse problema binário e, com o repositório local somente em cache, ainda mantém as construções de bullet-prof. Ainda assim, você tem um sistema de compilação "com um clique", mas o controle de origem não precisa embaralhar arquivos binários que não fazem sentido lá.

Então, sim, você pode obter arquivos binários fora do controle de origem, mas isso exigirá que você ajuste o sistema de compilação, para obtê-los no momento da compilação. Sem um software dedicado (como o Maven), pode ser um grande esforço apenas para liberá-los.


11
Estou preocupado em complicar o processo de compilação, principalmente porque grandes partes da equipe são matemáticas e não grandes fãs do processo.
Daniel Goldberg

3

Seu controle de fonte mantém as fontes no que você faz. Se um determinado blob binário puder ser reconstruído a partir das fontes, ele não é uma fonte e não deve entrar no repositório de código-fonte. Somente blobs não-recriáveis ​​devem fazê-lo no controle de origem.

Você normalmente tem outra pasta de rede de repositórios de blobs binários que você construiu durante o tempo das fontes. Eles podem ser implantados nos clientes ou usados ​​em projetos (em vez de criar tudo do zero todas as vezes).

Então, coloque-o se for uma fonte. Não se não.


Quem negaria isso? Por que é interessante: D

Não fui eu, mas desconfio de quem discordou da segunda metade da resposta.
Joel Coehoorn

@JoelCoehoorn, interessante, pois é exatamente isso que é um repositório Maven.

2

O objetivo é conseguir obter o código mais recente e compilá-lo sem precisar instalar / configurar nada (portanto, uma compilação de "clique único").

Em muitos lugares em que estive, isso significa fazer o check-in de binários de dependências. Em outros, isso significa que os scripts de construção são baixados e obtêm as dependências automaticamente.

Veja este post de Derek Greer sobre o assunto.


2

Estou trabalhando em um projeto com dois estágios de construção diferentes

  • a "construção do programa principal" precisa de apenas alguns binários, em comparação com os milhares de arquivos de texto do código fonte, para que os binários sejam verificados no repositório. Isso funciona bem.

  • a compilação do instalador precisa de muitos componentes de terceiros (alguns deles são apenas copiados para o CD de instalação, como o Adobe Reader). Não estamos colocando esses itens no repositório. Em vez disso, esses componentes residem em uma unidade de rede (mesmo versões mais antigas), e os scripts de construção os copiam para o lugar certo. Obviamente, para ter construções reproduzíveis, qualquer pessoa deve ter cuidado para não alterar nenhuma pasta onde os componentes de terceiros estão armazenados.

Ambas as estratégias funcionam bem e cumprem o requisito "check-out do controle de origem inclui tudo o que você precisa para compilar o código".


1

Você precisa manter tudo o que precisa para reconstruir versões específicas do produto em algum momento no futuro.

No entanto, você não precisa manter tudo no controle de origem.

Uma empresa mantinha um rack de servidor congelado (porque o sistema operacional era executado apenas nesse hardware específico e a cadeia de ferramentas era executada apenas nesse sistema operacional, e a fonte dependia dessa cadeia de ferramentas). Não é possível verificar isso no controle de origem.

Se você precisar dividir os requisitos para uma construção, terá o problema contábil de manter sincronizados dois sistemas de controle de versão. por exemplo, a caixa de hardware neste armário, a VM ou os binários neste volume de backup preservado, acompanhe esta revisão do código-fonte SVN etc. Isso é mais complicado do que usar um sistema de controle de fonte único, mas solucionável.


0

É muito caótico fazer check-in binário no SCM em minha mente. Eu tinha executado um projeto muito complexo, que tinha muitas dependências para bibliotecas de terceiros. Os princípios que adotamos:

  1. Todo o código-fonte é gerenciado com o SCM
  2. Todas as dependências são gerenciadas com o Ivy, que possui ótima integração com o eclipse.

Isso funciona muito bem. Temos um arquivo de configuração sobre a versão de cada biblioteca externa com a qual o código-fonte pode ser compilado. Esse arquivo de configuração é verificado no SCM e, portanto, evolui conforme o código-fonte. Aplicando essa abordagem, podemos reproduzir exatamente uma compilação sem mexer na versão das bibliotecas externas.


0

Pessoalmente, filosoficamente, estou inclinado a permitir que o controle de origem faça check-in de ponteiros para os grandes arquivos binários (pequenos recursos binários estão OK), e não o conteúdo do arquivo. Esse ponteiro conteria um hash do conteúdo do arquivo binário.

O próprio arquivo binário não seria gerenciado pelo controle de origem. Ele seria armazenado em algum tipo de biblioteca em que pode ser recuperado usando o ponteiro ou o hash especificamente.

O Git LFS e o anexo git fazem isso, mas eles também tentam gerenciar os arquivos binários até certo ponto, não quero que eles façam isso. Quero que o Git armazene apenas somas de verificação e me diga se meus arquivos binários foram alterados ou não - mas não quero que ele tente gerenciá-los e armazená-los. Eu quero fazer isso sozinho.

Eu acho que o git pode lidar com arquivos binários de tamanho pequeno e médio, mas não tenho certeza de que seja a ferramenta certa para gerenciar arquivos binários grandes.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.