CppNcss のダウンロードはこちらからしました。
セットアップ
ダウンロードしたファイルを解凍すると、バイナリなどが入っているフォルダが展開されるので適当な場所に保存します。このとき、パスに "空白" が含まれていると動作しないので気をつけてください。
cppncss\bin にパスを通します。
コマンドプロンプトを開いて、cppncss -h[ENTER] と打ちます。
>cppncss -h Usage: cppncss [options] [file [file2 [directory [directory2] ...]]] Version: 1.0.3 Options: -h print this message -d print debugging information -v be extra verbose -k keep going on parsing errors -r process directories recursively -x output result as xml -m=<measurements> output the <measurements> sorted in given order, defau lt is equivalent to -m=NCSS,CCN,function -n=<number> output only the top <number> results -f=<file> output result to <file> -D<symbol>[=[<value>]] replace define <symbol> with <value> -M<symbol>[=[<value>]] replace macro <symbol> with <value> -p=<path> remove <path> prefix when displaying file names See http://cppncss.sourceforge.net for more information.上記のようにヘルプが表示されれば OK です。
使ってみる
試しに使ってみました。解析対象は iutest を使用しました。include フォルダ以下すべてを解析させるので、 -r オプションをつけています。
>cppncss -r include ---- 省略 ---- Average Function NCSS: 4.86 Average Function CCN: 2.14 Nr. NCSS CCN Functions File 1 106 45 21 include\gtest\iutest_assertion_only.hpp 2 0 0 0 include\gtest\iutest_gtest_ver.hpp 3 0 0 0 include\gtest\iutest_spi_switch.hpp Average File NCSS: 35.33 Average File CCN: 15.00 Average File Functions: 7.00 Project NCSS: 106 Project CCN: 45 Project Functions: 21全部のファイルが解析されていないようです。
-k オプションをつけてパーサーエラーが発生しても続行するようにします。
>cppncss -k -r include ---- 省略 ---- Average Function NCSS: 3.75 Average Function CCN: 1.61 Nr. NCSS CCN Functions File 1 228 81 38 include\internal\iutest_list.hpp 2 120 42 30 include\iutest_core.hpp 3 112 56 10 include\util\iutest_util_tests.hpp 4 106 45 21 include\gtest\iutest_assertion_only.hpp 5 98 39 30 include\iutest_result.hpp 6 83 24 11 include\internal\iutest_console.hpp 7 76 26 22 include\internal\iutest_message.hpp 8 70 21 14 include\internal\iutest_params_util.hpp 9 67 23 21 include\iutest_body.hpp 10 62 16 15 include\internal\iutest_filepath.hpp 11 46 3 3 include\internal\iutest_option_message.hpp 12 44 22 18 include\util\iutest_util_quiet_result_printer.hpp 13 36 12 11 include\internal\iutest_random.hpp 14 35 10 9 include\internal\iutest_result_reporter.hpp 15 31 10 10 include\internal\iutest_factory.hpp 16 30 9 5 include\internal\iutest_exception.hpp 17 25 1 1 include\internal\iutest_stdlib.hpp 18 24 4 4 include\internal\iutest_mediator.hpp 19 18 4 3 include\internal\iutest_pool.hpp 20 13 2 2 include\iutest_static_assertion.hpp 21 11 4 2 include\gtest\switch\iutest_switch_inform.hpp 22 10 4 4 include\gtest\switch\iutest_switch_filepath.hpp 23 5 0 0 include\internal\iutest_regex.hpp 24 2 0 0 include\util\iutest_util_output.hpp 25 1 0 0 include\internal\iutest_tuple.hpp 26 1 0 0 include\iutest_util.hpp 27 0 0 0 include\gtest\iutest_gtest_ver.hpp 28 0 0 0 include\gtest\iutest_spi_switch.hpp 29 0 0 0 include\gtest\switch\iutest_switch_assert.hpp 30 0 0 0 include\gtest\switch\iutest_switch_core.hpp 31 0 0 0 include\gtest\switch\iutest_switch_expect.hpp 32 0 0 0 include\gtest\switch\iutest_switch_no_failure.hpp 33 0 0 0 include\gtest\switch\iutest_switch_package.hpp 34 0 0 0 include\gtest\switch\iutest_switch_peep.hpp 35 0 0 0 include\gtest\switch\iutest_switch_pmz.hpp 36 0 0 0 include\gtest\switch\iutest_switch_pred.hpp 37 0 0 0 include\gtest\switch\iutest_switch_skip.hpp 38 0 0 0 include\gtest\switch\iutest_switch_throw_value.hpp 39 0 0 0 include\internal\iutest_compiler.hpp 40 0 0 0 include\internal\iutest_internal.hpp 41 0 0 0 include\internal\iutest_pp.hpp 42 0 0 0 include\internal\iutest_pragma.hpp 43 0 0 0 include\iutest_config.hpp 44 0 0 0 include\iutest_ignore.hpp 45 0 0 0 include\iutest_ver.hpp Average File NCSS: 30.09 Average File CCN: 10.18 Average File Functions: 6.31 Project NCSS: 1354 Project CCN: 458 Project Functions: 284
できました。
NCSS と CCN
NCSS は "Non Commenting Source Statements"CCN は "Cyclomatic Complexity Number"
の略です。計測できるのはこの2つだけのようです。
Jenkins との連携
CPPNCSS Plugin があるのでインストールします。適当に CppNcss を行うプロジェクトを作成したら、
[ビルド後の処理の処理の追加] から [Publish Cpp NCSS Report] を選択します。
xml ファイルのパスと、関数単位でのステートメント数と複雑度の閾値を設定します。
こんな感じで集計、グラフ化できました。
CCCC との比較
C/C++ のコードメトリクスツールには他にも SourceMonitor や CCCC などがあります。個人的に CCCC を使っているので比較をしてみたいと思います。
(※ CCCC についてはこちらも参考にしてください)
計測できる項目
CppNcss | CCCC | 概要 | |
---|---|---|---|
Number of Module | x | o | モジュール(クラス)数 |
Line of Code | x | o | コード行数 |
Non Commenting Source Statements | o | x | ステートメント数 |
Cyclomatic Number | o | o | 複雑度 |
Line of Comment | x | o | コメント行数 |
LOC/COM | x | o | 1コメントあたりのコード行数 |
MVG/COM | x | o | 1コメントあたりの複雑度 |
Information Flow measure (inclusive) | x | o | モジュール間結合 |
Information Flow measure (visible) | x | o | モジュール間結合 |
Information Flow measure (concrete) | x | o | モジュール間結合 |
Weight Methods per Class (unity) | x | o | 関数の重み(重み=1) |
Weight Methods per Class (visible) | x | o | 関数の重み(重み=外部アクセスの可否) |
Depth of Inheritance Tree | x | o | 継承の深さ |
Number of Children | x | o | 子クラスの数 |
Coupling between objects | x | o | クラスが依存する外部クラスの数 |
Lines of Code rejected by parser | x | o | 解析に失敗した行数 |
ステートメント数
CppNcss で計測できるのは、ステートメント数(NCSS)です。一方 CCCC で計測できるのは、コード行数(LOC)です。
以下のコードで比較してみました。
class X { int value; public: int getValue() { return value; } void setValue(int v) { value = v; } }; int f() { int a=0; int b=0, c=0; // loop for( int i=0; i < 10; ++i ) { do { while(1) { ++a; break; } } while(0); } if( a != b ) { if( a != c ) { X x; x.SetValue(a); c = x. GetValue(); } else { } } else { } a = b; b = c; c = a; return b; } int main(int, char**) { f(); return 0; }
CppNcss の結果
Nr. NCSS CCN Function
1 19 6 f() at main.cpp:14
2 3 1 main( int, char** ) at main.cpp:50
3 2 1 X::getValue() at main.cpp:7
4 2 1 X::setValue( int ) at main.cpp:8
Average Function NCSS: 6.50
Average Function CCN: 2.25
1 19 6 f() at main.cpp:14
2 3 1 main( int, char** ) at main.cpp:50
3 2 1 X::getValue() at main.cpp:7
4 2 1 X::setValue( int ) at main.cpp:8
Average Function NCSS: 6.50
Average Function CCN: 2.25
CCCC の結果
全く別物であることがわかりますね。
さて、ステートメント数の計算についてもう少し調べてみたいと思います。
今度はこちらのコードを CppNcss にかけます。
int a=0; void for_() { for( int i=0; i < 10; ++i ) { ++a; } } void do_() { do { ++a; } while(1); } void while_() { while(1) { ++a; } } void if_() { if(1) { ++a; } else { } } void elseif_() { if(0) { } else if(1) { ++a; } else { } } void switch_() { switch(a) { case 0: ++a; break; } } void switch2_() { switch(a) { case 0: ++a; break; case 1: break; } } void switchdefault_() { switch(a) { case 0: ++a; break; default: break; } } void cond_() { a > 0 ? --a : ++a; } class A { public: int get() const { return 1; } }; class B { A a; public: const A* get() const { return &a; } }; B b; void call_() { b.get(); } void call2_() { b.get()->get(); }
こちらのコードを解析した結果がこちら。
Nr. NCSS CCN Function
1 7 3 switch2_() at main.cpp:62
2 7 2 switchdefault_() at main.cpp:74
3 6 3 elseif_() at main.cpp:38
4 5 2 switch_() at main.cpp:52
5 4 2 if_() at main.cpp:27
6 3 2 for_() at main.cpp:3
7 3 2 do_() at main.cpp:11
8 3 2 while_() at main.cpp:19
9 2 2 cond_() at main.cpp:86
10 2 1 A::get() at main.cpp:94
11 2 1 B::get() at main.cpp:100
12 2 1 call_() at main.cpp:104
13 2 1 call2_() at main.cpp:108
Average Function NCSS: 3.69
Average Function CCN: 1.85
1 7 3 switch2_() at main.cpp:62
2 7 2 switchdefault_() at main.cpp:74
3 6 3 elseif_() at main.cpp:38
4 5 2 switch_() at main.cpp:52
5 4 2 if_() at main.cpp:27
6 3 2 for_() at main.cpp:3
7 3 2 do_() at main.cpp:11
8 3 2 while_() at main.cpp:19
9 2 2 cond_() at main.cpp:86
10 2 1 A::get() at main.cpp:94
11 2 1 B::get() at main.cpp:100
12 2 1 call_() at main.cpp:104
13 2 1 call2_() at main.cpp:108
Average Function NCSS: 3.69
Average Function CCN: 1.85
想定した結果になりました。とくに言うことはありませんね。
(switchdefault_ と switch2_ で CCN が違うのはこういうもん?)
複雑度
CppNcss の複雑度の計算方法がわかりませんが(CCCC は McCabe)、こちらも上記の最初のコードで比較してみました。
CppNcss | CCCC | |
---|---|---|
f | 6 | 7 |
main | 1 | 1 |
これだけではわかりにくいので、Visual Studio 2012 の Win32 プロジェクトのテンプレートコードで比較してみました。
計測できなかったので、スルー。
iutest の結果で比較しようと思いましたが、どちらか片方が計測できていないものばかりで、良いサンプルがなかったので割愛させてもらいます。m(__)m
c++ ファイル以外の計測
CppNcss では、.cpp や .c など標準的な拡張子のファイルしか計測してくれません。なので、.ipp など独自拡張子を計測することができません。
CCCC の場合は、コマンドライン引数に --lang=c++ とすることで、独自ファイルの計測も可能です。
Jenkins との連携
CCCC の Jenkins との連携はちょっと残念なかんじです。プロジェクトやモジュール単位の結果をみることができるのですが、関数単位での結果が見れません。
この関数単位での結果が一番みたいところなんですが…
CCCC の結果 xml/html ファイルには関数単位の結果も書き込まれているので、
Jenkins でそれらを見たい場合は HTML Publisher Plugin を使うとよいでしょう。
また、独自に xml を解析して Jenkins で集計可能な xml にするのも手です。
そのへんについては、
ブログズミ: CCCC + Jenkins + HTML Publisher Plugin
ブログズミ: CCCC + Jenkins
を参考にしてください。
CppNcss の方は関数単位の結果を表示してくれます。
Jenkins プラグインは CppNcss の方がイイ感じです。
総評
CppNcss は CCCC と比べて、解析出来る内容は少ないですが手軽に使えそうです。また、ステートメント数が計測できるのと、CCCC では計測失敗する箇所でも CppNcss なら計測できる場合もあるので、CppNcss と CCCC を両方使うのもありだと思いました。
あとは、集めた情報をどう活かすかになりますが、それはまた今度の機会にでも…(できたら…)
0 件のコメント:
コメントを投稿