我正在使用Google的cpplint.py来验证我的项目中的源代码是否符合Google C++ Style Guide中规定的标准。我们使用SCons进行构建,因此我想通过使SCons首先读取我们所有的.h和.cc文件,然后在它们上运行cpplint.py来自动执行该过程,如果通过则仅构建一个文件。问题如下:

  • 在SCons中,我如何预 Hook 构建过程?除非通过文件,否则不要编译任何文件。
  • cpplint不返回退出代码。如何在SCons中运行命令并检查结果是否与正则表达式匹配? I.E.,如何获取文本输出?
  • 该项目很大,无论-1和#2的解决方案是什么,当-j选项传递给SCons时,它都应同时运行。
  • 我需要一个白名单,该白名单允许某些文件跳过 Lint 检查。
  • 最佳答案

    一种实现方法是monkey patch对象发射器函数,该函数将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')
    
    # 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。因此,没有多余的工作要做。如果棉绒检查失败,它将使构建失败。

    此解决方案可与-j一起使用,但是C++文件可以编译,因为棉绒假输出与目标文件目标之间不存在隐式依赖关系。您可以在其中添加一个显式的env.Depends,以强制“.lint”输出依赖于对象目标。这可能就足够了,因为即使在所有C++编译之后,如果还有任何剩余的lint问题,构建本身也会失败(scons给出的返回码为非零)。为了完整起见,在DoLint函数中,depends代码将如下所示:
    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)
    

    关于c++ - 设置SCons到Autolint,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4797781/

    10-12 22:16