10

私はGoogleのcpplint.pyを使用して、プロジェクトのソースコードがGoogleC ++スタイルガイドに記載されている基準を満たしていることを確認しています。SConsを使用してビルドするので、SConsに最初にすべての.hファイルと.ccファイルを読み込んでから、それらに対してcpplint.pyを実行し、合格した場合にのみファイルをビルドすることで、プロセスを自動化したいと思います。問題は次のとおりです。

  1. SConsでは、ビルドプロセスを事前にフックするにはどうすればよいですか?lintingを通過するまで、ファイルをコンパイルしないでください。
  2. cpplintは終了コードを返しません。SConsでコマンドを実行し、結果が正規表現と一致するかどうかを確認するにはどうすればよいですか?IE、テキストを出力するにはどうすればよいですか?
  3. プロジェクトは大規模ですが、#1と#2のソリューションが何であれ、-jオプションがSConsに渡されるときに同時に実行する必要があります。
  4. 一部のファイルがlintチェックをスキップできるようにするホワイトリストが必要です。
4

3 に答える 3

2

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も参照してください。

于 2011-01-25T20:25:21.327 に答える
2

これを行う 1 つの方法は、オブジェクト エミッター関数にモンキー パッチを適用することです。これにより、C++ コードがリンク可能なオブジェクト ファイルに変換されます。このようなエミッタ関数は 2 つあります。1 つは静的オブジェクト用、もう 1 つは共有オブジェクト用です。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 で機能しますが、lint の偽の出力とオブジェクト ファイル ターゲットの間に暗黙的な依存関係がないため、C++ ファイルがコンパイルされる場合があります。そこに明示を追加し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)
于 2011-02-11T17:19:31.397 に答える
1

サンプル ソース ツリーを含む scons スクリプトのペアについては、私の github を参照してください。Google の cpplint.py を使用します。

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

于 2013-10-24T15:19:24.633 に答える