Domanda

sto usando Google cpplint.py per verificare il codice sorgente nel mio progetto soddisfa gli standard stabiliti nel Google C ++ Style Guide . Usiamo SCons di costruire così mi piacerebbe di automatizzare il processo avendo SCons Prima leggi in tutti i nostri file .he .cc e cpplint.py quindi eseguire su di loro, solo la costruzione di un file se passa. I temi sono i seguenti:

  1. In SCons come faccio a pre-agganciare il processo di generazione? Nessun file deve essere compilato finché non passa rilascio di fibre.
  2. cpplint non restituisce un codice di uscita. Come faccio a eseguire un comando in SCons e controllare se il risultato corrisponde a un'espressione regolare? Vale a dire come faccio a ottenere l'essere output di testo?
  3. Il progetto è grande, qualunque sia la soluzione al # 1 e # 2 dovrebbe funzionare contemporaneamente quando l'opzione -j viene passata al SCons.
  4. Ho bisogno di una whitelist che permette ad alcuni file per ignorare il controllo di lanugine.
È stato utile?

Soluzione

Un modo per farlo è quello cerotto scimmia l'oggetto emettitore funzione, che trasforma il codice C ++ in file oggetto collegabili. Ci sono 2 tali funzioni di emettitore; uno per gli oggetti statici e uno per gli oggetti condivisi. Ecco un esempio che è possibile copiare incollare in uno SConstruct:

import sys
import SCons.Defaults
import SCons.Builder
OriginalShared = SCons.Defaults.SharedObjectEmitter
OriginalStatic = SCons.Defaults.StaticObjectEmitter

def DoLint(env, source):
    for s in source:
        env.Lint(s.srcnode().path + ".lint", s)

def SharedObjectEmitter(target, source, env):
    DoLint(env, source)
    return OriginalShared(target, source, env)

def StaticObjectEmitter(target, source, env):
    DoLint(env, source)
    return OriginalStatic(target, source, env)

SCons.Defaults.SharedObjectEmitter = SharedObjectEmitter
SCons.Defaults.StaticObjectEmitter = StaticObjectEmitter
linter = SCons.Builder.Builder(
    action=['$PYTHON $LINT $LINT_OPTIONS $SOURCE','date > $TARGET'],
    suffix='.lint',
    src_suffix='.cpp')

# actual build
env = Environment()
env.Append(BUILDERS={'Lint': linter})
env["PYTHON"] = sys.executable
env["LINT"] = "cpplint.py"
env["LINT_OPTIONS"] = ["--filter=-whitespace,+whitespace/tab", "--verbose=3"]
env.Program("test", Glob("*.cpp"))

Non c'è niente di troppo difficile su di esso in realtà. Quando si imposta lanugine per il percorso per la vostra copia cpplint.py, e impostare LINT_OPTIONS appropriati per il progetto. Il bit solo verrucosa è la creazione di un file di destinazione se il controllo passa utilizzando il programma da riga di comando date. Se si vuole essere cross-platform allora che avremmo dovuto al cambiamento.

L'aggiunta di una whitelist ora è il codice appena regolare Python, qualcosa come:

whitelist = """"
src/legacy_code.cpp
src/by_the_PHB.cpp
"""".split()

def DoLint(env, source):
    for s in source:
        src = s.srcnode().path
        if src not in whitelist:
            env.Lint( + ".lint", s)

Sembra cpplint.py fa uscita lo stato di errore corretto. Quando ci sono errori restituisce 1, altrimenti restituisce 0. Quindi non c'è alcun lavoro supplementare da fare lì. Se il controllo di lanugine fallisce, fallirà la generazione.

Questa soluzione funziona con -j, ma i file C ++ può compilare come non ci sono dipendenze implicite tra l'uscita pelucchi falso e il target file oggetto. È possibile aggiungere un env.Depends esplicito in là per forzare che l'uscita ".lint" dipendono l'oggetto di destinazione. Come è probabilmente sufficiente, dal momento che la costruzione in sé non riuscirà (scons dà un codice di ritorno diverso da zero) se ci sono problemi di pelucchi rimasti anche dopo tutti compila il C ++. Per completezza il dipende codice sarebbe qualcosa di simile nella funzione DoLint:

def DoLint(env, source, target):
    for i in range(len(source)):
        s = source[i]
        out = env.Lint(s.srcnode().path + ".lint", s)
        env.Depends(target[i], out)

Altri suggerimenti

AddPreAction sembra essere quello che stai cercando, dalla pagina di manuale:

AddPreAction(target, action)
env.AddPreAction(target, action)
Arranges for the specified action to be performed before the specified target is built. T

Si veda anche http://benno.id.au/blog/2006/ 27/08 / filtergensplint per un esempio.

Vedere la mia GitHub per un paio di scons script completo con un albero sorgente di esempio. Esso utilizza cpplint.py di Google.

https://github.com/xyzisinus/scons-tidbits

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top