一种方法是对对象发射器函数进行猴子补丁,该函数将 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。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)