Binari nel controllo del codice sorgente

29

Quando si sviluppa per dispositivi embedded e altri mondi strani, è molto probabile che il processo di build includa più binari proprietari, usando versioni molto specifiche di essi. Quindi la domanda è: fanno parte del controllo del codice sorgente? I miei uffici seguono la regola "il check-out dal controllo del codice sorgente include tutto il necessario per compilare il codice" e questo ha portato ad alcuni argomenti seri.

Gli argomenti principali che vedo contro questo sono gonfiore del DB di controllo del codice sorgente, la mancanza di file binari diffranti ( vedi le domande precedenti sull'argomento) . Questo è contro la capacità di verificare, costruire, sapere di avere l'ambiente preciso che lo sviluppatore precedente ha inteso e senza cercare i file appropriati (con versioni specifiche non meno!)

    
posta Daniel Goldberg 25.09.2011 - 09:09
fonte

10 risposte

27

L'idea di VERSION CONTROL (nome errato: controllo del codice sorgente) consente di eseguire il rollback della cronologia, recuperare l'effetto delle modifiche, vedere le modifiche e il motivo della modifica. Questa è una serie di requisiti, alcuni dei quali richiedono elementi binari, alcuni dei quali no.

Esempio: per il funzionamento del firmware incorporato, normalmente avrai una toolchain completa: un compilatore proprietario che costa un sacco di soldi, o qualche versione di gcc. Per ottenere l'eseguibile di spedizione hai bisogno sia della toolchain che della fonte.

Controllare i toolchain nel controllo della versione è un problema, le utilità diff sono orribili (se non del tutto), ma non c'è alternativa. Se vuoi che la toolchain venga conservata per il tizio che viene a guardare il tuo codice tra 5 anni per capire cosa fa, allora non hai scelta: DEVI avere anche la toolchain sotto controllo di versione.

Ho scoperto nel corso degli anni che il metodo più semplice per farlo è quello di creare un'immagine ZIP o ISO del CD di installazione e verificarlo. Il commento di controllo deve essere il numero di versione specifico della toolchain. Se gcc o simili, raggruppa tutto ciò che stai utilizzando in un grande ZIP e fai lo stesso.

Il caso più estremo che ho fatto è Windows XP Embedded in cui la "toolchain" è una VM Windows XP in esecuzione, che includeva (da allora) SQL Server e una pila di file di configurazione insieme a centinaia e centinaia di file di patch. L'installazione dell'intero lotto e il suo aggiornamento hanno richiesto circa 2-3 giorni. Preservare che per i posteri significava controllare TUTTA la VM nel controllo della versione. Visto che il disco virtuale era costituito da circa 6 x 2 GB di immagini, in realtà è andato abbastanza bene. Sembra esagerato, ma ha reso la vita molto facile per la persona che è venuta dopo di me e ha dovuto usarla - 5 anni dopo.

Riepilogo: il controllo della versione è uno strumento. Usalo per essere efficace, non rimanere impigliato per cose come il significato delle parole, e non chiamarlo "controllo del codice sorgente" perché è più grande di quello.

    
risposta data 25.09.2011 - 11:17
fonte
18

Neal Ford discute in The Productive Programmer che dovrebbe mantenere i binari nella fonte controllo:

Why keep binaries? Projects today depend on a swath of external tools and libraries. Let’s say you are using one of the popular logging frameworks (like Log4J or Log4Net). If you don’t build the binaries for that logging library as part of your build process, you should keep it in version control. That allows you to continue to build your software even if the framework or library in question disappears (or, more likely, introduces a breaking change in a new version). Always keep the entire universe required to build your software in version control (minus the operating system, and even that is possible with virtualization; see “Use Virtualization,” later in this chapter). You can optimize retaining binaries by both keeping them in version control and on a shared network drive. That way, you don’t have to deal with them on an hourly basis, but they are saved in case you need to rebuild something a year later. You never know if you will need to rebuild something. You build it until it works, then forget about it. It is panic inducing to realize you need to rebuild something from two years ago and don’t have all the parts.

Non potrei essere più d'accordo; mentre questo è probabilmente sovvertendo il VCS per un compito che non era progettato per (mantenendo i binari), penso che i benefici superino i potenziali svantaggi. Ma, come nota l'autore più avanti, a volte mantenere i file binari in VCS potrebbe non essere una soluzione pratica, quindi è necessario prendere in considerazione altre opzioni, ad esempio tenerle su un'unità di rete mappata.

Se i binari non sono troppo grandi, li terrei sicuramente in VCS. Questo sembra essere ancora più vero nel tuo caso, dal momento che i binari sono probabilmente piccoli, e lavori con versioni molto specifiche. Potrebbero anche essere difficili da trovare, a causa di una serie di motivi (gli autori chiudono il loro sito Web o la versione di cui hai bisogno non è più elencata per il download). Anche se improbabile, non sai mai cosa succederà tra qualche anno.

Vorrei aver letto questo libro qualche anno fa, quando stavo lavorando a un gioco usando una libreria grafica (che era un file dll); Ho interrotto lo sviluppo per un po 'e, quando volevo continuare, non sono riuscito a trovare di nuovo la DLL perché il progetto è morto.

    
risposta data 25.09.2011 - 12:49
fonte
8

Il controllo del codice sorgente è per le fonti. Le fonti sono ciò che non puoi costruire da altre cose. Alcuni file che si qualificano come fonti sono binari.

Il mio VCS contiene molti binari, ma ognuno è l'unità di rilascio di un prodotto che non ho scritto e non mantengo. Questo potrebbe essere qualcosa come GNU ccRTP, che viene rilasciato come un compresso tarball. Quel tarball è la mia fonte, e viene controllato insieme a qualsiasi infrastruttura di cui ho bisogno per trasformarlo in un prodotto finito (un Makefile e una specifica RPM nel mio caso) in un unico passaggio automatico. Quando c'è una nuova versione di ccRTP, considero il nuovo tarball come cambiato fonte: entra in una copia ritirata, viene costruito, testato e reimpostato sul VCS. Ho fatto lo stesso con prodotti commerciali che non vengono spediti con la fonte (compilatori, librerie, ecc.) E funziona allo stesso modo. Invece di unpack-configure-compile-package, è solo unpack-package. Il software che esegue le build notturne non conosce o non si preoccupa finché può eseguire make e ottenere prodotti finiti.

La maggior parte dei VCS ha caratteristiche che rendono la fonte leggibile dall'uomo più facile da gestire e più efficiente da archiviare, ma dire che non sono adatti ai binari non è proprio vero se i binari vengono rimossi senza molestare. Il modo in cui un VCS gestisce i binari internamente dipende interamente dal fatto che i suoi autori pensassero che tentare di memorizzare solo differenze valesse lo sforzo. Personalmente, penso che la memorizzazione di copie complete di una distribuzione ccRTP a 600K un pop sia più che compensata dalla possibilità di taggare una versione di esso insieme a tutte le altre mie fonti.

    
risposta data 25.09.2011 - 16:06
fonte
7

In linea di principio, apprezzo il campo "controlla tutto il necessario per costruire nel campo del controllo del codice sorgente", ma la gestione delle dipendenze si è evoluta un po 'negli ultimi anni, con strumenti come Maven, Ivy e NuGet.

Inoltre, in pratica, trovo il controllo nei file binari per creare una serie di effetti collaterali spiacevoli. Git / Mercurial non sono davvero ottimizzati per questo, ad esempio, e Subversion e Perforce possono farti impazzire quando unisci rami che contengono binari.

Con una soluzione di gestione delle dipendenze, si specifica in un file controllato dal codice sorgente nel progetto quali nomi di pacchetto e di quali versioni dipende il progetto. Quasi tutti gli strumenti di gestione delle dipendenze consentono di creare un repository privato delle proprie dipendenze, seguendo una sorta di controllo delle versioni e dei nomi; quando si esegue una build, lo strumento di gestione delle dipendenze risolverà tutte le dipendenze open source e proprietarie da un elenco di fonti approvate, quindi li inserirà nella cache locale. La prossima volta che costruisci con le stesse dipendenze di versione, tutto è già lì e va molto più veloce.

Il tuo repository privato può quindi essere sottoposto a backup con strumenti di backup del filesystem convenzionali.

Questo evita i rallentamenti che ho riscontrato quando una tonnellata di binari viene estratta dall'albero dei sorgenti e impedisce al tuo repository di avere molti file difficili da diff. C'è solo una posizione per ogni dipendenza data, per nome e numero di versione, quindi non ci sono conflitti di fusione da affrontare, e il caching del filesystem locale significa che non devi affrontare il costo di valutare se la tua copia locale è cambiata quando tiri gli aggiornamenti.

    
risposta data 25.09.2011 - 19:26
fonte
4

Questo mi ricorda il problema "jar in repository" che qualche tempo fa Java aveva. Le persone che costruiscono app java sono state utilizzate per trasferire le loro dipendenze (file jar binari) nei repository. Tutti erano contenti di questo, perché avremmo un sistema di build "one-click" e lo spazio su disco è economico, quindi a chi importa. Poi è arrivato Maven e tu potresti sbarazzarti di tutto quel cruft binario e con il repository cache-only locale mantieni ancora le build di bullet-prof. Hai ancora un sistema di build "one-click", ma il controllo del codice sorgente non deve mescolare file binari che non hanno senso lì.

Quindi sì, puoi ottenere file binari dal controllo del codice sorgente, ma questo richiederà di modificare il sistema di build, per ottenerli in fase di compilazione. Senza un software dedicato (come Maven) questo potrebbe essere un grande sforzo per tirarli fuori.

    
risposta data 25.09.2011 - 10:24
fonte
3

Il tuo controllo sorgente tieni i sorgenti in quello che fai. Se un dato blob binario può essere ricostruito dalle fonti, non è una fonte e non dovrebbe andare nel repository del codice sorgente. Solo i BLOB non ricreabili devono essere nel controllo del codice sorgente.

Di solito hai un'altra repository cartella di rete di blob binari che hai costruito nel tempo delle fonti. Questi possono essere distribuiti ai clienti o utilizzati nei progetti (invece di creare tutto da zero ogni volta).

Quindi, inseriscilo se è una fonte. Non farlo se non.

    
risposta data 25.09.2011 - 09:47
fonte
2

L'obiettivo è essere in grado di ottenere l'ultimo codice e crearlo senza dover installare / configurare nulla (quindi, una build "single click").

In molti posti che sono stato, ciò significa verificare i binari delle dipendenze. In altri, ciò significa che gli script di compilazione scaricano e ottengono automaticamente le dipendenze.

Vedi questo post del blog di Derek Greer sull'argomento.

    
risposta data 25.09.2011 - 09:13
fonte
2

Sto lavorando a un progetto con due diverse fasi di costruzione

  • la "build del programma principale" ha bisogno di pochi binari, rispetto alle migliaia di file di testo del codice sorgente, quindi i binari vengono controllati nel repository. Funziona bene.

  • la build del programma di installazione necessita di molti componenti di terze parti (alcuni di questi sono copiati sul CD di installazione, come Adobe Reader). Non li stiamo mettendo nel repository. Invece, quei componenti risiedono su un'unità di rete (anche versioni più vecchie) e gli script di build li copiano nel posto giusto. Naturalmente, per avere build riproducibili, chiunque deve fare attenzione a non modificare alcuna cartella in cui sono memorizzati i componenti di terze parti.

Entrambe le strategie funzionano bene e soddisfano il "controllo del codice sorgente include tutto il necessario per compilare il codice".

    
risposta data 25.09.2011 - 09:31
fonte
1

Devi mantenere tutto ciò di cui hai bisogno per ricostruire versioni specifiche del prodotto in futuro.

Tuttavia non devi tenere tutto nel controllo del codice sorgente.

Una società teneva un server rack congelato (perché il sistema operativo funzionava solo su quell'hardware specifico e la toolchain funzionava solo su quel SO, e la fonte dipendeva da quella toolchain). Impossibile controllarlo nel controllo del codice sorgente.

Se hai bisogno di dividere i requisiti per una build, allora hai il problema di tenere sincronizzati due sistemi di controllo della versione. per esempio. la scatola dell'hardware in questo armadio, o la VM oi binari in questo volume di backup conservato, vanno con questa revisione del codice sorgente SVN, ecc. Questo è più confuso che usando un unico sistema di controllo del codice sorgente, ma risolvibile.

    
risposta data 25.09.2011 - 20:24
fonte
0

Nella mia mente è molto caotico fare il check-in binario a SCM. Avevo eseguito un progetto molto complesso, che ha molte dipendenze da librerie di terze parti. I principi che abbiamo adottato:

  1. Tutto il codice sorgente è gestito con SCM
  2. Tutte le dipendenze sono gestite con Ivy, che ha una grande integrazione con Eclipse.

Funziona piuttosto bene. Abbiamo un file di configurazione sulla versione di ogni libreria esterna con cui è possibile compilare il codice sorgente. Questo file di configurazione viene controllato in SCM, quindi si evolve man mano che il codice sorgente si evolve. Applicando questo approccio, possiamo riprodurre esattamente una build senza fare confusione con la versione di librerie esterne.

    
risposta data 27.09.2011 - 07:57
fonte

Leggi altre domande sui tag