gpt4 book ai didi

c++ - 将 SCons 设置为 Autolint

转载 作者:太空狗 更新时间:2023-10-29 19:25:55 25 4
gpt4 key购买 nike

我正在使用谷歌的 cpplint.py验证我项目中的源代码是否符合 Google C++ Style Guide 中规定的标准.我们使用 SCons 来构建,所以我想通过让 SCons 首先读取我们所有的 .h 和 .cc 文件然后在它们上运行 cpplint.py 来自动化这个过程,只有在它通过时才构建一个文件。问题如下:

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

最佳答案

执行此操作的一种方法是 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。如果使用命令行 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)

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com