Perché le build incrementali in "make" non usano algoritmi di hashing?

7

Sono un principiante con make e mi chiedo quando utilizzare make clean .

Un collega mi ha detto che le build incrementali con make sono basate sul timestamp dei file. Quindi, se esegui il checkout di una vecchia versione di un file nel tuo VCS, avrà un "vecchio" timestamp e verrà contrassegnato come "non c'è bisogno di ricompilare questo file". Quindi, quel file non verrebbe incluso nella build successiva.
Secondo lo stesso collega, sarebbe un motivo usare make clean .

Ad ogni modo, ho avuto la risposta alla domanda "quando usare make clean " da altre domande StackExchange ma la mia altra domanda è:

Why do incremental builds using make rely on files timestamps and not on SHA-1 for example? Git, for instance, shows that we can successfully determine if a file was modified using the SHA-1.
Is it for speed issues?

    
posta filaton 24.05.2016 - 17:42
fonte

2 risposte

3

Un problema ovvio (e probabilmente superficiale) sarebbe che il sistema di generazione dovrebbe tenere traccia degli hash dei file che sono stati usati per l'ultima build. Sebbene questo problema possa essere risolto sicuramente, richiederebbe l'archiviazione laterale quando le informazioni relative alla data e ora sono già presenti nel file system.

Più seriamente, però, l'hash non trasmetterebbe la stessa semantica. Se sai che il file T è stato creato dalla dipendenza D con hash H 1 e poi scopri che D ora hash su H 2 , dovresti ricostruire T ? Probabilmente sì, ma potrebbe anche essere che H 2 si riferisca effettivamente a una vecchia versione del file. I timestamp definiscono un ordine mentre gli hash sono paragonabili per l'uguaglianza.

Una funzionalità che supporta il timestamp è che è possibile aggiornare semplicemente il timestamp (ad esempio, utilizzando l'utilità della riga di comando POSIX touch ) per ingannare make nel pensare che una dipendenza sia cambiata o - più interessante - un obiettivo sia più recente di quanto non sia in realtà. Mentre giocare con questo è una grande opportunità per spararti nel piede, è utile di volta in volta. In un sistema basato su hash, è necessario il supporto del sistema di compilazione stesso per aggiornare il suo database interno di hash utilizzato per l'ultima build senza creare effettivamente qualcosa.

Mentre un argomento potrebbe certamente essere fatto per l'utilizzo di hash su timestamp, il mio punto è che non sono una soluzione migliore per raggiungere lo stesso obiettivo, ma una soluzione diversa per raggiungere un obiettivo diverso. Quale di questi obiettivi sia più desiderabile potrebbe essere aperto al dibattito.

    
risposta data 25.05.2016 - 02:54
fonte
1

L'hashing di un intero progetto è molto lento. Devi leggere ogni singolo byte di ogni singolo file. Git non esegue l'hashing di ogni file ogni volta che si esegue un git status . Né i checkout VCS normalmente impostano il tempo di modifica del file all'orario originale. Un ripristino di backup sarebbe, se si presta attenzione a farlo. L'intero motivo per cui i filesystem hanno i timestamp è per casi d'uso come questi.

Uno sviluppatore tipicamente esegue make clean quando una dipendenza non tracciata direttamente dal Makefile cambia. Ironicamente, questo di solito include il Makefile stesso. Solitamente include anche le versioni del compilatore. A seconda di come è stato scritto il tuo Makefile, potrebbe includere versioni di librerie esterne.

Questi sono i tipi di cose che tendono ad essere aggiornati quando fai un aggiornamento del controllo di versione, quindi la maggior parte degli sviluppatori ha l'abitudine di eseguire un make clean allo stesso tempo, quindi sai che stai iniziando da un tabula rasa. Puoi andartene senza farlo molto tempo, ma è molto difficile prevedere le volte che non puoi.

    
risposta data 24.05.2016 - 19:53
fonte

Leggi altre domande sui tag