Einrichten SCons zu Autolint
Frage
Ich bin mit google cpplint.py um zu überprüfen, source-code in meinem Projekt erfüllt die standards festgelegt, die in den Google C++ Style Guide.Wir verwenden SCons zu bauen, also möchte ich den Prozess automatisieren, indem SCons zuerst Lesen Lesen Sie in unseren .h-und .cc-Dateien und führen Sie dann cpplint.py auf Ihnen nur der Bau einer Datei wenn es geht.Die Probleme sind wie folgt:
- In SCons wie kann ich pre-hook den build-Prozess?Keine Datei kompiliert werden soll, bis es geht linting.
- cpplint nicht zurück ein exit-code.Wie führe ich einen Befehl in SCons und prüfen Sie, ob das Ergebnis entspricht einem regulären Ausdruck?I. E., wie bekomme ich die text-Ausgabe?
- Das Projekt ist groß, was auch immer die Lösung #1 und #2 es sollte gleichzeitig ausgeführt werden, wenn der -j-option übergeben wird, SCons.
- Ich brauche eine whitelist, die es erlaubt, einige Dateien zu überspringen, die Flusen überprüfen.
Lösung
Ein Weg dies zu tun ist, um monkey patch das emitter-Objekt-Funktion, die schaltet den C++ - code in linkable object-Dateien.Es gibt 2 solche emitter-Funktionen;eine für statische Objekte und eine für gemeinsam genutzte Objekte.Hier ist ein Beispiel, das Sie kopieren und einfügen in eine 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"))
Nichts ist zu schwierig es wirklich.Youd, LINT auf dem Weg zu Ihrem cpplint.py kopieren Sie, und setzt die entsprechenden LINT_OPTIONS für Ihr Projekt.Das einzige, warzig bit ist die Schaffung einer ZIEL-Datei aus, wenn die Prüfung geht über die Befehlszeile date
Programm.Wenn Sie wollen, um cross-Plattform-dann würde sich ändern müssen.
Hinzufügen einer whitelist ist jetzt ganz normale Python-code, so etwas wie:
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)
Es scheint cpplint.py funktioniert die Ausgabe der Fehler-status.Wenn es Fehler gibt 1 zurück, ansonsten 0 zurück.Es gibt also keine zusätzliche Arbeit zu tun gibt.Wenn die lint-überprüfung fehlschlägt, wird es nicht die build.
Diese Lösung funktioniert mit -j -, aber der C++ - Dateien kompilieren kann, da es keine implizite Abhängigkeiten zwischen den lint fake-Ausgang und der Objekt-Datei-Ziel.Sie können hinzufügen eine explizite env.Depends
in der es um die Kraft, die die ".lint" Ausgang hängen von der Objekt-Ziel.So ist es wahrscheinlich genug, da der Bau selbst wird scheitern (scons gibt einen nicht-null-Rückgabe-code), wenn es irgendwelche verbleibenden Flusen Fragen, auch nach all den C++ kompiliert.Für die Vollständigkeit der hängt im code wäre so etwas wie dies in der DoLint Funktion:
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)
Andere Tipps
AddPreAction
Scheint das zu sein, wonach Sie suchen, von der Manpage:
AddPreAction(target, action)
env.AddPreAction(target, action)
Arranges for the specified action to be performed before the specified target is built. T
Siehe auch http://benno.id.au/blog/2006/08/27/filtergensplint zum Beispiel.
In meinem GitHub finden Sie ein Paar Scons -Skripte mit einem Beispiel -Quellbaum. Es verwendet Googles cppLint.py.