Настройка SCons для Autolint - PullRequest
       10

Настройка SCons для Autolint

10 голосов
/ 25 января 2011

Я использую Google cpplint.py для проверки того, что исходный код моего проекта соответствует стандартам, установленным в Руководстве по стилю Google C ++ .Мы используем SCons для сборки, поэтому я хотел бы автоматизировать процесс, чтобы SCons сначала читал во всех наших файлах .h и .cc, а затем запускал cpplint.py для них, только создавая файл, если он прошел.Проблемы заключаются в следующем:

  1. В SCons как предварительно подключить процесс сборки?Файл не должен быть скомпилирован, пока он не пройдет linting.
  2. cpplint не возвращает код завершения.Как запустить команду в SCons и проверить, соответствует ли результат регулярному выражению?IE, как мне получить выводимый текст?
  3. Проект большой, независимо от того, что решение № 1 и № 2 должно выполняться одновременно, когда опция -j передается в SCons.
  4. Мне нужен белый список, который позволяет некоторым файлам пропустить проверку lint.

Ответы [ 3 ]

2 голосов
/ 11 февраля 2011

Один из способов сделать это - 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)
2 голосов
/ 25 января 2011

AddPreAction, кажется, то, что вы ищете, из справочной страницы:

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

Также см. http://benno.id.au/blog/2006/08/27/filtergensplint для примера.

1 голос
/ 24 октября 2013

Посмотрите на моем github пару скриптов scons в комплекте с исходным деревом примеров.Он использует Google cpplint.py.

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

...