2011-01-25 16 views
10

Googleのcpplint.pyを使って、私のプロジェクトのソースコードを確認していますが、Google C++ Style Guideに記載されている基準を満たしています。我々はSConsを使ってビルドを行うので、SConsが.hと.ccのすべてのファイルを最初に読み込んでから、cpplint.pyを実行してファイルを作成するだけで、プロセスを自動化したいと考えています。問題は次のとおりです。AutonintにSConsを設定する

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

答えて

2

これを行う1つの方法は、オブジェクトエミッタ関数です。これは、C++コードをリンク可能なオブジェクトファイルに変換します。このようなエミッタ関数は2つあります。 1つは静的オブジェクト用、もう1つは共有オブジェクト用です。

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")) 

本当にそれについてあまりにもトリッキーなものは何もありません。ここでは、SConstructにコピー&ペーストすることができます例です。 LINTをcpplint.pyコピーのパスに設定し、プロジェクトに適切なLINT_OPTIONSを設定します。小切手がコマンドラインdateプログラムを使用して合格すると、TARGETファイルが作成されます。クロスプラットフォームにしたい場合は、それを変更する必要があります。

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ようだ:

は、ホワイトリストを追加すると、今だけ通常のPythonコードのようなものです。エラーがある場合は1を返し、それ以外の場合は0を返します。そこで余分な作業はありません。 lintチェックが失敗すると、ビルドに失敗します。

このソリューションは-jオプションで動作しますが、lint fake出力とオブジェクトファイルターゲットの間に暗黙的な依存関係がないため、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) 
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を参照してください。

+0

これが機能するには、事前に目標を知る必要があります。どうすれば私のプロジェクトにすべての.cc/cpp/cと.h/hppファイルのリストが得られますか?私はまた、システムやブーストヘッダーなどのヘッダーを除外する必要があります。 – Jonathan

+0

@Jonathan、あなたは2行のシェルスクリプトでこれを行うことができます。 – ismail

+0

@İsmail、SConsスクリプトですでに収集されたノードを使用するのが最善でしょう。私はSCons.Action、SCons.Job、&SCons.Nodeモジュールを見ていますが、保留中のビルドがどこに置かれているのかは分かりません。 – Jonathan

1

は例のソースツリーとの完全なsconsのスクリプトのペアのための私のgithubのを参照してください。それはGoogleのcpplint.pyを使用します。

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

+0

ようこそStackOverflow!私はあなたの投稿を編集してあなたの紹介を削除しました。確かに良い意味ではあるが、ここでは人々は質問に関連するものだけを書くという方針を保つ。 – Thilo

関連する問題