Ответ 1
Один из способов сделать это - патч обезьяны функция эмиттера объекта, которая превращает код С++ в связываемые объектные файлы. Есть две такие функции эмиттера; один для статических объектов и один для общих объектов. Вот пример, который вы можете скопировать в 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. Поэтому нет никакой дополнительной работы. Если проверка линта не удалась, это приведет к сбою сборки.
Это решение работает с -j, но файлы С++ могут компилироваться, поскольку не существует неявных зависимостей между выводом фальшивки fint и целевым файлом объектного файла. Вы можете добавить явный env.Depends
туда, чтобы заставить вывод ".lint" зависеть от цели объекта. Как это, вероятно, достаточно, поскольку сама сборка не сработает (scons дает ненулевой код возврата), если есть какие-либо проблемы с lint даже после всех компиляций на С++. Для полноты кода в коде 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)