Один из способов сделать это - monkey patch функция-эмиттер объекта, которая превращает код C ++ в связываемые объектные файлы.Есть 2 такие функции эмиттера;один для статических объектов и один для общих объектов.Вот пример, который вы можете скопировать вставить в 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"))
В этом нет ничего сложного.Вы должны установить LINT на путь к вашей копии cpplint.py и установить соответствующий LINT_OPTIONS для вашего проекта.Единственный бит бродяги - это создание файла TARGET, если проверка проходит с использованием программы командной строки date
.Если вы хотите быть кроссплатформенным, это должно измениться.
Добавление белого списка теперь просто обычный код Python, что-то вроде:
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)
Кажется, cpplint.py выводит правильный статус ошибки.При наличии ошибок он возвращает 1, в противном случае возвращает 0. Так что там нет никакой дополнительной работы.Если проверка lint завершится неудачно, сборка завершится неудачей.
Это решение работает с -j, но файлы C ++ могут компилироваться, поскольку не существует неявных зависимостей между выводом lint fake и целью объектного файла.Вы можете добавить явный env.Depends
, чтобы вывод «.lint» зависел от цели объекта.Вероятно, этого достаточно, поскольку сама сборка завершится неудачно (scons дает ненулевой код возврата), если возникнут какие-либо проблемы с lint даже после всех компиляций C ++.Для полноты зависимый код будет выглядеть примерно так в функции 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)