一种方法是通过猴子补丁对象发射器函数,将C ++代码转换为可链接的对象文件。有两个这样的发射器函数:一个用于静态对象,另一个用于共享对象。以下是一个示例,您可以将其复制并粘贴到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')
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。唯一棘手的部分是,如果检查通过,则使用命令行date
程序创建TARGET文件。如果您想跨平台,则需要进行更改。
现在添加白名单只需要编写普通的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虚假输出和目标对象文件之间没有隐式依赖关系。您可以在其中添加一个显式的env.Depends
,以强制“.lint”输出依赖于对象目标。由于即使在所有C++编译之后仍然存在任何剩余的lint问题,构建本身也会失败(scons给出非零返回代码),因此现在可能已经足够了。对于完整性,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)