Gestione dei bug del compilatore in Integrazione continua

4

Credo che gli avvertimenti dovrebbero essere trattati come errori. Se inizi a ignorare gli avvisi, inizierai a mancare avvisi "importanti" tra quelli "non importanti". Quindi il mio sistema di Continuous Integration fallisce una build se ci sono avvertimenti.

Uno dei miei compilatori ha un bug che provoca un avviso quando non dovrebbe. Il mio codice è valido e viene compilato correttamente e non posso disabilitare questo particolare avvertimento.

Come dovrebbe gestirlo il mio sistema di CI? Devo disabilitare temporaneamente "avvisi come errori", fino a quando il compilatore non viene corretto?

    
posta M. Dudley 02.05.2013 - 15:10
fonte

2 risposte

10

Quando il compilatore "si comporta male", lo si può avvolgere come qualsiasi altra applicazione che non funziona correttamente.

A seconda dello script di compilazione e di come funziona, ciò può essere fatto in due modi.

Il modo ideale, tuttavia, è di indirizzare il codice nel codice piuttosto che nel compilatore (quindi nel modo 0 th ). Se è possibile, questo dovrebbe essere analizzato in primo luogo in quanto riduce al minimo le differenze negli ambienti di costruzione che possono rendere difficile la realizzazione di un sistema diverso.

Way 0: ignoralo dal compilatore

Questa opzione dovrebbe essere presa in considerazione perché, mentre rende il codice un po 'più disordinato, mantiene il numero di "parti mobili" nel processo di costruzione più basso, e quindi meno probabile che abbia errori.

Questo ha il vantaggio significativo di mantenere l'ambiente di costruzione lo stesso (rispetto al modo 2). Uno non vorrebbe andare a creare un nuovo server Jenkins e quindi avere un po 'di tempo del WTF speso cercando di capire perché rompe la build da scoprire sul vecchio server di build, il compilatore ha un wrapper che il nuovo non fa t.

Questo è compilatore e dipende dalla lingua. MadKeithV ha menzionato l'approccio per Visual C ++.

La domanda SO Disabilita selettivamente gli avvisi GCC solo per una parte di un'unità di traduzione? ci va un po 'per gcc che può essere "riepilogato" come:

#pragma GCC diagnostic error "-Wuninitialized"
    foo(a);         /* error is given for this one */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
    foo(b);         /* no diagnostic for this one */
#pragma GCC diagnostic pop
    foo(c);         /* error is given for this one */
#pragma GCC diagnostic pop
    foo(d);         /* depends on command line options */

I documenti per questo possono essere consultati nella direttiva di diagnostica GCC 4.6

Clang usa un approccio simile, sebbene invece di GCC , suo clang come specificato in Ignora tutti gli avvisi in un file specifico usando LLVM / Clang :

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmultichar"

char b = 'df'; // no warning.

#pragma clang diagnostic pop

Si può vedere che questo potrebbe diventare molto confuso se si compila la stessa fonte con gcc e clang ...

In Java, uno ha l'annotazione @SupressWarnings .

Way 1: filtra attraverso una pipe

gcc args file.c | supresswarning.pl

Lo script supresswarning.pl dovrebbe quindi filtrare l'output di gcc per identificare se si è verificato quell'errore specifico e solo estrarlo dall'output. Si potrebbe anche passare il file.c allo script e identificare il numero di riga in cui si trova l'annotazione o la macro per evitare di filtrare errori reali.

Si noti che questo non è abbastanza così semplice come viene mostrato - gli errori possono apparire su un errore standard piuttosto che sullo standard, e la pipa dovrebbe essere regolata in modo appropriato. Per mantenere che gli errori si siano verificati sul corretto handle di file, suppresswarning.pl dovrebbe identificare gli errori e scriverli di nuovo sull'appropriato handle di file.

Way 2: filtra attraverso un wrapper

Se allo script di build non piace avere a che fare con i compilatori in questo modo (pensa ant e maven ambienti di stile in cui invoca il compilatore stesso), uno potrebbe scrivere un wrapper.

Un wrapper per javac si chiamerebbe javac , invoca javac_real (il javac reale che è stato rinominato), passa tutte le opzioni al richiamo reale ed elabora l'output e regola il codice di ritorno e i messaggi stesso.

Questo può anche essere usato nell'altro modo (per rendere l'errore sugli avvertimenti) se il compilatore sta restituendo degli avvertimenti e si vuole fallire con gli avvertimenti, e l'ambiente CI lo farà se il compilatore restituisce un codice di uscita diverso da zero ... ma non lo è. Lo script wrapper potrebbe esaminare l'output del compilatore e, di nuovo, regolare il codice di ritorno del wrapper in modo che sia appropriato per l'ambiente.

    
risposta data 02.05.2013 - 17:04
fonte
4

Per Visual C ++ 2012 (e probabilmente prima) uso

#pragma warning(push)
#pragma warning(disable: XYZW)
  // Code causing spurious XYZW warning here.
#pragma warning(pop) 

Non è particolarmente carino e a volte devi essere piuttosto ampio nell'ambito di questo avviso, ad es. quando all'interno di una libreria condivisa, derivante da una classe template che non ha un'istruzione export, non ho trovato nessun altro modo di disabilitare tale avviso per l'intero file.

Lo faccio solo quando compare l'avviso nei log di compilazione, ho ricontrollato che è spurio e ho determinato la quantità minima di codice necessaria per disabilitare l'avviso in modo che non vada via. Non disabilito l'avviso globalmente per l'intero progetto.

    
risposta data 02.05.2013 - 15:40
fonte

Leggi altre domande sui tag