ラベル 静的解析 の投稿を表示しています。 すべての投稿を表示
ラベル 静的解析 の投稿を表示しています。 すべての投稿を表示

2022年3月10日木曜日

Include-What-You-Use の docker image を更新しました

https://hub.docker.com/repository/docker/srzzumix/iwyu/general

表題どおりです。
今まで自分が使うようにイメージを置いといただけでしたが、各 clang バージョン x Ubuntu バージョン x Multi Arch(amd64/arm64) でビルドしておいておきました。
Include What You Use は C/C++ の include の最適化をしてくれるツールです。
過去に記事を書いてますのでそのへんを参考にしてください。
ブログズミ: [C++] Include-What-You-Use で依存関係を確認する


ビルドは GitHub Actions で行っています。
https://github.com/srz-zumix/docker-iwyu 

今後は複数 arch 対応の需要が上がっていく気がしてるので今回から対応してみました。
複数 arch 対応の image をローカルでビルドする場合は、レジストリに push しながらなら OK らしく(ようは実行環境の arch しかローカルビルドできないって感じかな?)勉強になりました。
今まではビルドしたあとにタグつけて push してたのですが、これだと実行環境の arch しか push できなかったため、一度ビルドしたイメージからバージョン情報とかを取り出し、タグを生成してから再度 docker/build-push-action を実行してます。

これらのイメージは定期的にビルドするものでもないので手動トリガーでビルドするようになってます。
一部の組み合わせではビルド失敗したり、clang のインストールできなくて image のビルドに失敗してます。
需要があればちゃんと見てみますので、もしあれば issue に書いてください。

以上。


2022年2月17日木曜日

gcc -fanalyzer が実行しきれる CI サービスを求めて・・・

 先週書いた記事の続き
ブログズミ: メモリ不足で gcc が kill される場合になんとかビルドする

上記記事の対応で CircleCI 上でいくつかメモリリークなどの検知がされたのですが、誤検知を無視したりコード修正したりしてエラーが出ない状態にしていったものの、テストコードのビルドが最後まで完了しきらない状態に陥ってしまいました。

状態としては、無出力タイムアウトが発生していたので CircleCI の no_output_timeout を延ばして回避しようとしました。
しかし、5時間とかにしても一向に終わらない。。
エラー(警告)が出ない状態であれば ggc の設定を緩和しても kill されることはなくなったので、コンパイル速度優先の設定にしても無出力タイムアウトしてしまいダメ。

長いタイムアウト設定で何度もトライアンドエラーしてるとクレジット消費に悪影響が出るので、一旦 CircleCI を諦めて他のサービスを検討することにしました。

なるべくリソース豊富はところ、かつビルド時間が無料プランの制限を圧迫しないものを探しています。
各サービスのリソース状況はこちらのリポジトリで調べたものを参考にしています。
https://github.com/srz-zumix/ci-specs
拙著にも記載してます。(宣伝)
https://srz-zumix.booth.pm/

以下、随時更新していきます。

1. GitHub Actions (kill)
2. CircleCI (no output timeout)
3. RazorOps (kill)
4. AzurePipelines (timeout 360min)


2021年12月9日木曜日

Facebook 改め Meta 社の静的解析ツール Infer を GitHub Actions でかける

この記事は「C++のカレンダー | Advent Calendar 2021 - Qiita」の9日目です。

Infer とは

Infer は Facebook 社改め Meta 社が作った静的解析ツールです。
今回は C++ Advent Calendar ということで C++ の静的解析ツールとして紹介しますが、Infer 自体は OCaml で書かれています。
また、C++ の他に Java/C/Objective-C の解析も可能です。

C++ の静的解析ツールというと Cppcheck や Coverity 、コンパイラ付属のものがあったりします。筆者はこれまでこれらのツールを使ってきました。
Infer は 2015 年にOSS化して公開されたのですが、ずっと使ってみたいと思いつつ機会がありませんでした。

今回こうして記事にしているのは、仕事で必要になったからとか趣味でやる気になったからではなく、社名が変わったからネタとして触ることにしました。
理由はともあれ、以下で紹介していきます!

ローカル環境で使う場合

本記事は表題どおり「GitHub Actions」で Infer を使う手順を紹介しますが、ローカル環境で実行する場合も軽く触れておきます。
まず大事なこととして、Windows 非対応です!
Mac の場合は brew install infer でインストールできます。Linux の場合はビルド済みバイナリをダウンロードするか、ソースコードビルドで使うことができます。Docker という手もあります。
詳しいことは公式の「Getting Started with Infer」を見てください。

セットアップできたら「infer run -- ビルドコマンド」のようにコマンド実行すると以下のように結果が出ます。

ビルドコマンドは対象によって変わると思いますが、コンパイラー以外にも cmake や make 、mvn などのビルドツールにも対応しています。

ビルドコマンドが bash script になっているような場合はキャプチャーするコマンドを認識できないので、--force-integration オプションで教えてあげてください。
対応している integration は --force-integration オプションのヘルプで確認できます。
e.g. infer run --force-integration clang -- build.sh

GitHub Actions で使う

では、ここから本題です。
GitHub Actions で Infer を使うために、Setup Infer action (srz-zumix/setup-infer) と Infer reviewdog action (srz-zumix/reviewdog-action-infer) を作成しました。

setup-infer

Infer を現在の環境にセットアップするアクションです。
当然ですが Windows は非対応です。また Mac の場合はバージョン指定はできず、 brew install で取得できるバージョンがインストールされます。
(要望あれば対応しようかと思いますので、issues へどうぞ)

reviewdog-action-infer

Infer の結果を reviewdog を使って PR にコメントするアクションです。
Infer の実行結果が入っている infer-out から result.txt を参照し、reviewdog を使って PR に問題をコメントします。


なぜ action を分けたのか

最初は Infer インストールや解析込みの action を書こうと思ったのですが、ビルドツールや環境はユーザーによってバラバラで、action 側ですべてに対応するのは難しいと考えてこのようになりました。

Infer の実行

上記2つの action は infer での解析処理をしませんので、ワークフローで適宜呼び出してください。
個人開発してるテストフレームワーク(iutest)の例を記載しておきます。

  infer:
    runs-on: ubuntu-latest
    needs: prepare
    steps:
      - uses: actions/checkout@v2
      - uses: srz-zumix/setup-infer@v1
      - name: infer
        run: |
          infer -- make -C test IUTEST_USE_PYTHON=0
      - name: Check Infer report
        uses: srz-zumix/reviewdog-action-infer@v1
        with:
          reporter: github-pr-review
   
結果

iutest のワークフローの結果はこちらです。
静的解析なしだと 10 分くらいのテストが、Infer ありだと 25 分弱と少し時間がかかってますが、まぁ趣味開発なので許容範囲です。

速度向上

Recommended flow for CI | Infer」こちらで CI 向けのおすすめ実行方法が書いてあります。うまくキャッシュできるのであれば --reactive オプションでキャプチャーした情報を再利用すれば早くなると思います。
reportdiff は reviewdog で同等のことができるのでどちらでも。

また --changed-files-index オプションで差分ファイルのリストを指定すれば、そのファイルの解析だけが行われるため、速度向上可能です。
ただし、C++ の場合はヘッダーファイルを指定しても解析されません。.cpp ファイルを指定しないとダメです。(※ --changed-files-index は analyze 時に有効なので capture 時間の短縮にはならない)

Infer capture/analyze TIPS
capture/analyze 中にクラッシュする場合

--skip-analysis-in-path で除外指定できるのでそれをおすすめします。
-g オプションでデバッグモードになるので原因調査ができるかもしれませんが、ストレージを圧迫するかもしれません。
(3,000 弱のソースコードファイル数からなるプロジェクトでやったら 600GB 越えたあたりでディスクフルになって PC 自体が落ちました。。)

解析途中でエラーが出る場合

--keep-going オプションを付けると続行可能です。

compile_commands.json の場合 --clang-blacklisted-flags/--clang-blacklisted-flags-with-arg は効かない

そのまんまです。特に xcodebuild の場合 infer が使う clang が知らないオプションを使ってることがあり、「error: unknown argument: '-index-store-path'」のように失敗していまいます。 infer はデフォルトで  --clang-blacklisted-flags-with-arg に -index-store-path が入ってますが、 compile_commands.json から capture をする場合は --clang-blacklisted-flags(-with-arg) オプションは考慮されないので、json ファイルの command から削除してください。

--continue-analyz

仕事のプロジェクトに Infer 掛けてみたら analyze でクラッシュするわ、エラー起こるわ、なんか応答なくなるわ、そもそも解析時間がクソ長いわ、で辛かったんですが、--continue-analyz オプションつけると続きから解析してくれるので作業が無駄になりません。
(最初に知りたかった)

.inferconfig にオプションを書ける

infer のコマンドラインオプションは .inferconfig ファイルに書いておくことができます。
ファイルの中身は JSON 形式でオプションから -- を除いた名前をキーに設定をします。

例えば、上記で紹介した --skip-analysis-in-path や、 infer の clang にインクルードパスを追加する場合は以下のように書けます。

{
    "skip-analysis-in-path": [
        "path/to/lib/xxx/src",
    ],
    "Xclang": [
        "-I /path/to/dir/include",
    ]
}
まとめ

静的解析ツールは1つかければ十分というものではないので、ぜひ試してみてください。

以上。

2021年2月25日木曜日

cppcheck html report

 久しぶりに cppcheck を使ってみたら HTML レポートができるようになっていたのでメモ。

環境セットアップ

HTML レポートを作成するには python 環境が必要です。
https://github.com/danmar/cppcheck/tree/main/htmlreport
バージョンは 2.7 以上であれば大丈夫なようです。
また pygments に依存してるので pip install pygments もしておきましょう。

Cppcheck を実行

HTML レポートは cppcheck の結果 xml から作成するので、まずは cppcheck をかけて xml を出力します。

e.g.
cppcheck --enable=all --xml myproject 2> result.xml

Cppcheck 自体の使い方は(かなり昔に書いた記事ですが)こちら「ブログズミ: Cppcheck を使ってみた」、もしくは公式ドキュメントを参照してください。

HTML レポート

xml ができたらいよいよ html にします。

cppcheck-htmlreport --file=result.xml --title=iutest --report-dir=./html

--file で cppcheck で出力した xml を指定します。(複数指定可能)
その他のオプションは下記のヘルプを参考にしてください。

Usage: cppcheck-htmlreport [options]

Options:
  -h, --help            show this help message and exit
  --title=TITLE         The title of the project.
  --file=FILE           The cppcheck xml output file to read defects from. You
                        can combine results from several xml reports i.e. "--
                        file file1.xml --file file2.xml ..". Default is
                        reading from stdin.
  --report-dir=REPORT_DIR
                        The directory where the HTML report content is
                        written.
  --source-dir=SOURCE_DIR
                        Base directory where source code files can be found.
  --source-encoding=SOURCE_ENCODING
                        Encoding of source code.

結果

iutest の結果を gh-pages に入れておいたのでそちらを参考にしてみてください。
https://srz-zumix.github.io/iutest/test/cppcheck/



ソースコードも HTML ページ上で確認できます。

今回はこれで以上です。



2020年10月26日月曜日

[C++][IWYU] Include What You Use CL を VS2019 対応しました

include-what-you-use-cl を VS2017/VS2019 に対応しました。
include-what-you-use-ci (以下 IWYU-CL) は include-what-you-use (以下 IWYU) を Visual Studio のプラットフォームツールセットとして選択できるようにするツールです。
プラットフォームツールセットとすることでプロジェクトの設定(インクルードパスなど)をそのまま利用して IWYU をかけることを目的に作りました。
VS2017 から VS{version}COMNTOOLS 環境変数がなくなったりと、インクルード関連の構成が一新されてから更新が滞ってましたが、最近 vswhere の存在を知り更新することにしました。

あと同僚に突っ込まれたので README も更新して、使い方を書きました。

Include-What-You-Use-CL

Include-What-You-Use-CL is Visual Studio toolset for Include-What-You-Use

Dependency

Include-What-You-Use

Install

git clone https://github.com/srz-zumix/include-what-you-use-cl.git
cd include-what-you-use-cl
install.bat

Usage

  1. Project Settings > Platform toolset
    Select "Include-What-You-Use" toolset
  2. Compile
  3. Get Include-What-You-Use result
    output

Uninstall

uninstall.bat

IWYU は cpplint にも組み込まれてたりするようなので、わざわざ cl から呼ぶ必要性はない気もしますが。。
お手軽に試せるので IWYU-CL も試してみてくださいmm

今回は以上です。
では。

2018年3月26日月曜日

Rocro を使ってみた - その2(tidy と scan-build と auto-fix)

前回(ブログズミ: [CI] Rocro 使ってみた)、他の機能(ツール)も使っていきたいといってましたが、その経過報告です。

Tidy
まず1つめは Tidy です。こちらは、HTML 向けのツールです。
開発中の iutest は C++ なのでなぜ?という感じですが、ドキュメント類のチェックもしているので実は関係があります。
というのも、iutest は gh-pages でドキュメントを公開をしています。
Doxygen 生成やドキュメントのみのブランチにする変換を Codeship で行い、自動で gh-pages ブランチに push してます。
そのため、gh-pages ブランチは HTML なブランチになっており、たまたまブランチフィルターをつくる前に INSPECODE がテストくれたので、そのまま使うことにしました。


結論としては、まだうまく使いこなせてない状態です。
こちらが書きたいフォーマットと指摘が少しずれているのを、オプションなどで調整したいのですが、あまりうまくいっていないので別のツールを使ったほうがいいのかもしれません。


auto-fix オプション
auto-fix は INSPECODE 上のツールで検知した問題を、自動修正してくれるオプションです。
(使えないツールもあります。)
こちらを Tidy で有効にしてみました。

auto-fix オプションですが、自動修正されたコードは修正専用のブランチが作成されます。
(マージはされないので安心)
修正ブランチは、もとのブランチ名+@inspecode という名前で push されます。

作成されたブランチ:https://github.com/srz-zumix/iutest/tree/gh-pages%40inspecode

それをプルリクしたやつ:https://github.com/srz-zumix/iutest/pull/31


このとき、ブランチが push されますので他の CI サービスを使っている場合に、CI が回ってしまうので注意が必要です。
(適切に除外設定がされていれば問題なし)
Rocro 自身はデフォルトで除外されます。

※ Rocro への要望としては、auto-fix コミットのコミットメッセージに任意のメッセージを追加できるようにできると嬉しいです。
skip ci または ci skip コメントをつけるだけで他の CI サービスもスキップできるので楽になると思います。

結果としては、Tidy の修正内容は使わないことにしたので、auto-fix は無効にしています。
CI 回してオートマージまでやれればよかったのですが、これはまた別の機会にオアズケ。
(本当はこれを記事のメインにするつもりだったのですが・・・また今度で・・・)

scan-build
こちらは、clang の静的解析ツールです。
iutest では Semaphore CI で実行していましたが、Rocro ではオプション指定のみで簡単に使えたので引っ越しを検討しました。

まず、Semaphore CI でやっていたことをそのままさせたところ、タイムアウトしてしまいました。


この辺は無料ユーザーですし、各サービスで制限時間は異なるので仕方がないことです。
ので、ビルド対象者を絞ってタイムアウトしないようにしました。
ここまでは OK です。

この状態でジョブが走って、ステータスも
Succeeded になり、問題の検出もなかったので良かった良かったと思っていたのですが、勘違いでした。


ログ見たら、ビルド失敗して解析されないだけでした。
Failed にしてくれー

ともあれ、ビルドエラー修正したらちゃんと scan-build の結果が報告されるようになったのでめでたしめでたし。



最後に
記事を書き始めてから大分経ってしまったが、引き続き Rocro は使っていきテストの領域を増やしていきたいと思ってます。

2017年7月31日月曜日

続・ソースコード中の単語からの略語/スペルミス検出に挑戦

ブログズミ: ソースコード中の単語からの略語/スペルミス検出に挑戦」で紹介した略語チェッカーを大幅に更新したので、続報です。
ついでなので、Glosbe でリクエスト制限にかかってしまった場合の対処方法も紹介しておきます。

変更点
usage: abbreviation.py [-h] [-v] [-g FILE] [-w FILE] [-e EXCLUDE]
                       [-a ABBREVIATION] [--glosbe] [--dejizo] [--cache]
                       [--load-cache NAME] [--cache-dir DIR]
                       [--disable-keywords] [-x {c++,c#,objc,diff}]
                       [--list-all] [--progress] [--safe-mode]
                       [--encoding ENCODING] [--extension EXTENSION]
                       [--ignore-noexists] [--relpath] [--word WORD] [-]
                       [FILE/DIR [FILE/DIR ...]]

positional arguments:
  FILE/DIR              source code file/dir

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -g FILE, --gene FILE  exlude word
  -w FILE, --whitelist FILE
                        whitelist file
  -e EXCLUDE, --exclude EXCLUDE
                        exlude word
  -a ABBREVIATION, --abbreviation ABBREVIATION
                        abbreviation word
  --glosbe              use online translation service (glosbe)
  --dejizo              use online service (dejizo)
  --cache               online translation cache enable
  --load-cache NAME     load translation cache
  --cache-dir DIR       translation cache directory
  --disable-keywords    disable general and language keywords
  -x {c++,c#,objc,diff}, --language {c++,c#,objc,diff}
                        select language
  --list-all            list up all location
  --progress            print percent progress
  --safe-mode           api request limit safe mode(glosbe)
  --encoding ENCODING   set file encoding
  --extension EXTENSION
                        file extension matcher
  --ignore-noexists     ignore option file not exists
  --relpath             print relative path
  --word WORD           dircet check words
  -                     source code from stdin

diff ファイルに対応
便利になった機能の1つがこれだと思います。
diff ファイルから差分があったところだけをチェックするので、コードレビューのときに重宝します。
対応しているフォーマットは Unified format になります。

略語判定ロジックの大幅更新
「~の略語」だけでなく、「~の過去形」「~の複数形」なども検出して、辞書判定するように改善しました。主に、boost のヘッダーファイルをチェッカーに入力して、その結果を見ながら、期待に沿わないものに対応していった感じです。

ただ、ソースコード中で出てきた場合の一般的な意味と、辞書に載っている意味で剥離している場合もあります。
例えば、「apis」とあったら、「APIs」のことだとプログラマーは思うと思うのですが、辞書的には「蜂」です。
こういったものを機械的に振り分けるのは(今の自分の力量では)難しかったので、100% プログラマーが期待する結果になるわけではありませんので、ご注意!
ディープラーニングさせたらいいのかな?

ともあれ、boost を解析して自分なりに納得のいくところまで対応できたかなーと思ってます。

Glosbe でリクエスト制限にかかってしまった場合の対処方法
('Http error:', u'429 Client Error:  for url: https://glosbe.com/gapi/translate?dest=ja&phrase=opendir&from=en&pretty=true&format=json')
('request count: ', 802)
Please access the glosbe, click the search button and check reCAPTCHA.
Glosbe でリクエスト制限にかかると上記ログが出力されます。
これが出た場合、以下の方法で回復が可能です。

まずは、https://ja.glosbe.com/ にアクセスして、普通に辞書検索します。


以下のような画面になるので、チェックをクリアすると制限が解除されます。
(何回も制限かけられましたが、今のところこの方法ですぐに解除できています。)


最後に
このツールを実際に使ってみて、当初の目的の略語検出よりも typo 検出の方が役に立ちました。
実際にヒドイ typo が見つかりました…
https://github.com/srz-zumix/iutest/commit/c063225f5abfeb157f671e3fc55b779f32e12193

ただ、typo チェックであれば、「Pull Requestに潜むタイポを自動的に検出し、修正を代行するBot - Qiita」の方がよさそうだなーと思ったのと、PyEnchant ってのがあるほを初めて知ったので機会があれば使ってみようと思いました。

最後ですが、今回のアップデートで自己満足できるところまで作れたので、これで開発を一旦終了しようと思います。
(要望いただければ対応します)
ではでは。

2017年3月13日月曜日

[MSBuild] コード分析警告をエラーとする

Visual Studio コード分析機能については省略。
こちらの機能が無効な状態で SCM 管理されている場合、MSBuild で /p:RunCodeAnalysis=true /p:EnablePREfast=true をつけてビルドするとコード分析が有効になります。
Jenkins でこれを実行して、警告集計している場合は、警告プラグインの設定でジョブを失敗にしたり、不安定にしたりできるので問題ないのですが、CI サービスを使っていると Warning は成功となってしまいます。(exit code 0)
実際、自作 C++ テスティングフレームワークの iutestAppVeyor でコード分析させてましたが、ずーーーっと警告を無視してました…





これを解決する方法はとても簡単です。
MSBuild のコマンドラインオプションに /p:CodeAnalysisTreatWarningsAsErrors=true を追加してください。これで、コード分析警告をエラーとして扱うようになります。



今回は以上です。

2016年11月22日火曜日

ソースコード中の単語からの略語/スペルミス検出に挑戦

2018/2/22 追記:続編書いた「続・ソースコード中の単語からの略語/スペルミス検出に挑戦」。Glosbe の制限の解決策も書いてあります。

ブログズミ: TreeTagger を使ってソースコード中の単語をリストアップしてみた」の続きです。
今回は抽出した単語が略語、もしくはスペルミスなどがないかチェックします。

なぜ、こんなものを作ったのか?それは


ということです。

今回作成したものはそのうちの一つで、「許可された略語以外は禁止」という規約に対して、その発見を"補助"するものです。
(あくまで補助でこれをかけて何も検出されなかったら OK というわけではありません。でも、人間が一語一語確認するものでもないので、これでも十分かなぁーっと思ってます。)

できたもの
最初に出来上がったものを紹介したいと思います。
ソースコードはこちらで公開しています。

usage: abbreviation.py [-h] [-v] [-g FILE] [-w FILE] [-e EXCLUDE]
                       [-a ABBREVIATION] [--glosbe] [--dejizo] [--cache]
                       [--load-cache NAME] [--cache-dir DIR] [--list-all]
                       FILE/DIR [FILE/DIR ...]

positional arguments:
  FILE/DIR              source code file/dir

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -g FILE, --gene FILE  exlude word
  -w FILE, --whitelist FILE
                        whitelist file
  -e EXCLUDE, --exclude EXCLUDE
                        exlude word
  -a ABBREVIATION, --abbreviation ABBREVIATION
                        abbreviation word
  --glosbe              use online translation service (glosbe)
  --dejizo              use online service (dejizo)
  --cache               online translation cache enable
  --load-cache NAME     load translation cache
  --cache-dir DIR       translation cache directory
  --list-all            list up all location

試しに iutest のソースコードを調べてみました。


設計としては、抽出した単語を辞書(オンライン/オフライン)から検索して、辞書にあれば問題なし(辞書に略語として登録されている場合は×)、辞書になかった場合に疑わしい単語として警告する設計です。

以下で詳しく説明していきます。

単語の抽出
「ソースコード中の単語」の抽出は libclang などを利用してやるほうが正しいとは思うのですが、
ブログズミ: TreeTagger を使ってソースコード中の単語をリストアップしてみた」でやったように形態素解析ツールの TreeTagger を使ってやりました。


オンライン辞書サービスを利用する
Glosbe
Glosbe Api
英単語の日本語訳をプログラム内やターミナル内で取得する - roombaの日記

いいね~いいね~とコーディングしていたら、いつの間にかエラーに…
Too many queries, your IP has been blocked

    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 429 Client Error:  for url: https://glosbe.com/gapi/translate?dest=ja&phrase=incg&from=en&pretty=true&format=json
というわけで、制限を超えてしまったようです…

ドキュメントによれば、「ブロックするリクエスト数は明確には決まってないけど、人間じゃなくてロボットだと判断したらブロックするよ」と書いてあります。

ロボットなのでしょうがないですね…
開発者でブロックされたら連絡してねとありますが、別のサービスを探すことにしました。
(一応、1日経つとブロック解除されています。今のところ)

WORDS API
WORDS API
無料プランでも 2,500 Requests/Day でよさそうだったんですが、クレジットの登録が必要だったので今回は保留としました。
(V-プリカとか使えば良いんですけど、めんどくさいので…)
(制限オーバーしたら請求が発生する感じに見えたのも保留した理由の1つ…)

デ辞蔵
デ辞蔵 オンラインでもオフラインでも使える電子辞書
続いて目をつけたのがこちら。
(SOAP ってなんだろ?って思ったんですが、そういうのがあったんですね)

こちらは特に制限がないのですが、注意事項として
・短時間にアクセスが集中するような呼び方(1秒間に20回以上の呼び出しなど)
・定常的に一定のアクセスが続くような呼び方(数秒ごとに自動的に呼び出すなど)
とありました。→「BizPal - デ辞蔵Tech よくある質問と回答
あと無償版は動作保証なし。

英和辞書で使えるのは、EDICT和英辞典(EJdict) と 三省堂 デイリーコンサイス英和辞典 試用版(DailyEJL)の2つあったので、両方を検索するようにしてます。ただし、 Glosbe よりも辞書の単語数は少ない印象
秒間20リクエストは場合によっては超えてるかもしれないので、ゴメンナサイm(__)m

その他
この記事も早く公開したいし、組み込みはこの辺で一旦終わりにしておきます。
その他の辞書サービスがあれば使ってみたいと思います。
あとは、翻訳サービス使う方法もありなのかも。

オンライン辞書のヒット結果をキャッシュする
さて、オンライン辞書から単語を引いてくることができるようになりましたが、リクエスト制限のことを考えなければいけません。というわけで、なるべくリクエストを投げないようにするために、一度検索ヒットした単語をローカルにキャッシュする仕組みを入れました。

今回 iutest を解析したときのキャッシュがリポジトリに入ってます。
このキャッシュはサービスごとに記録し、どんどん追記していく仕組みです。

また、キャッシュは2種類あります。
辞書には「略語」として単語登録されているものもありますので、ヒットしたけど略語だった場合はブラックリストに登録しています。
(※この略語判定が大変だった。特に EDICT は統一性がないのでかなり妥協…)

オフライン辞書を利用する
ソースコード中の単語で、外部に出したくないものもあると思います。(コードネームとか製品名とか?)
そこで、オフラインの辞書にも対応しています。

辞書は3つのタイプが利用可能です。

--whitelist FILE
単純な形式で単語を1行ずつ読み込みます。

--gene FILE
オープンしたファイルから、 '^[a-zA-Z][a-z]+$' にマッチするものを単語として読み込みます。
(これは GENE95 を想定して用意しているので、それ以外には使わないかもしれませんが…)

--cache-load XXX
オンライン辞書でキャッシュしたファイルを読み込みます。
XXX の部分にはオンライン辞書のオプション名を入れます。(現状、glosbe と dejizo のみ対応)
形式はホワイトリスト+ブラックリストになっています。

オンライン辞書では、場合によって "ver" などが "version" の略語として単語登録されている場合がありますので、
そのような単語はブラックリストとしてキャッシュしています。
(ホワイトリストの形式 --whitelist で読み込めるファイルと同じですので、これだけを --whitelist で読み込むことも可能です。)


使ってみた結果
当初は略語の検出を目的に作成しましたが、どちらかと言うと typo 、誤字脱字の方がよく検出される結果となりました。
(恥ずかしいのでちゃんと直しました。 > https://github.com/srz-zumix/iutest/commit/6c767630c810ef27b92bfca856a657209945433c

使ってみたい方、github で公開してますのでご自由にお使いください。




2016年10月26日水曜日

[Cppcheck] 結果を CSV で出力してエクセルで確認する

なぜそんなことが必要か?
Jenkins で xml を集計している場合は、視覚的に確認ができます。
Visual Studio などから利用した場合も、--template vs で出力ウィンドウからジャンプできますし、拡張機能もあります。
これらの組み合わせを使っている場合は、まったくもって問題ないのですが、スタンドアロンで解析して結果を確認したい場合に、視覚的に確認できる方法が欲しかったので、表題にあるような対応をしました。

方法

出力ログフォーマットを以下のように指定します。
--template={file},{line},{severity},{id},\"{message}\"

あとは、stderr を .csv にリダイレクトすれば OK
(message にたまに "" が含まれている場合があるので、そこだけセルが別れちゃいますが…)


実際にこの方法で確認してみると結構便利だということがわかりました。
ぜひ一度お試しあれ


2016年10月13日木曜日

[Cppcheck] 1.76 で Visual Studio プロジェクトファイルの読み込みに対応



--project=     Run Cppcheck on project. The  can be a Visual
                     Studio Solution (*.sln), Visual Studio Project
                     (*.vcxproj), or compile database
                     (compile_commands.json). The files to analyse,
                     include paths, defines, platform and undefines in
                     the specified file will be used.


プロジェクトファイルもしはソリューションファイルを指定すると、その定義に従って解析できるようになりました。
これを待っていた!
(あと cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON で出力できる compile_commands.json にも対応)


iutest で試してみました。


--verbose オプションをつけているので、Define とか Include がどう設定されているのかわかると思いますが、
ちゃんとプロジェクトの設定に従って、しかもすべての構成で解析してくれています!
最高やーん!

みんなも今すぐバージョンアップ!!
ダウンロードはこちらから→ Cppcheck - A tool for static C/C++ code analysis

2016/10/14 追記
Version 1.76 にはハングアップバグがあったようで、その修正バージョンとして 1.76.1 がリリースされていました。

2016年8月22日月曜日

[Jenkins] Warnings Plugin の新規警告の計算について

Warnings Plugin には警告の総数もしくは新規警告数に応じて、ステータスを変更する機能があります。

この機能を使って、警告が残っていたら不安定(黄)にすることが多いのですが、
最近になって、警告が増えたら(新規警告があったら)不安定にするような使い方を始めました。
そうしたらものの見事にハマったので備忘録として書き残しておきます。

新規警告がないにも関わらず不安定になってしまう!!
そんなことが起こってました。
再現ジョブを作ったのでそちらで確認していきます。

まず、ビルドするソースコードはこちら
int main(int argc, char** argv)
{
    return 0;
}
なんのへんてつもないコードです。
これを g++ -Wall -Wextra でビルドするジョブを作成します。

これを1回成功させておきます。
このときの警告は2件です。


続いて、新規警告が1件でもあったら不安定するように設定を変更します。
そして、ソースコードも以下のように書き換えます。
int main(int argc, char** argv)
{
    int x;
    return 0;
}

これを実行すると、結果は新規警告1件により不安定になります。
このとき警告の総数は3件です。



ここまでは、問題ありません。
次が問題です。

もう一度ジョブを実行します。
今度はソースコードを変えてませんので、警告数は3件のままで新規警告も 0件 のはずなので、成功になるはずです。ところが、実際には不安定になってしまうのです。なぜ?!



なぜなのか
ログを見てみましょう。

なぜか新規警告が1件と出力されています。
ビルド結果ページを見ると 0件 なのに?

どうやら、Warnings Plugin で見る新規警告は、最後の成功ビルドから見ての新規警告だったようです。
(ソースコード変更後の警告数は3件なので、成功時の警告2件からみると1件増えたように見える)
ログにもちゃんと
[WARNINGS] Computing warning deltas based on reference build #9
と書いてありました。

前回のビルドから見て欲しい
簡単でした。
「Use previous build as reference」にチェックを入れるだけです。


この状態でもう一度ジョブを実行すると、意図通り成功になりました!


ログもこの通り、ちゃんと1つ前のビルドを参照しているようです。

最後に
「Use previous build as reference」とか、「Only use stable builds as reference」とか、
説明が英語だったのでスルーしてましたが使いどころが分かりました。
また、どういう挙動をしているのか少し分かったことで、通知の仕方の幅が広がりました。
(成功時の警告数を下回るまで不安定するのもアリだと思った)

今回は以上。
では。


2016年4月11日月曜日

[C++] Include-What-You-Use で依存関係を確認する

ブログズミ: [C/C++][Clang] include 解析ツールを作った
ちょっと前に clang で include 依存関係解析を書きましたが、最終的にやりたいことができるツールが既にあったので使ってみました。

Include-What-You-Use
ツールは Include-What-You-Use といいます。
こちらの存在は以下の記事を見て知りました。
Include-What-You-Use も clang の AST を利用して解析しているそうです。

ホームページのダウンロードリンクに Windows バイナリがあったので、今回はこれを使いました。
Downloads

また、使用方法は Github のドキュメントを参照。
How to Run
CXX を include-what-you-use にしてビルドすれば良いようです。

iutest で試した結果がこちら。
$ make CXX=include-what-you-use sample
include-what-you-use -I../../include -g -Wall -Wextra -Wundef    -c ../../samples/main.cpp
In file included from ../../samples/main.cpp:24:
In file included from ../../samples/../include/iutest.hpp:23:
In file included from ../../include/iutest_core.hpp:20:
In file included from ../../include/internal/iutest_result_reporter.hpp:20:
In file included from ../../include/internal/iutest_core_impl.hpp:20:
In file included from ../../include/internal/iutest_internal.hpp:20:
In file included from ../../include/internal/../iutest_pred.hpp:20:
In file included from ../../include/iutest_assertion.hpp:20:
In file included from ../../include/iutest_result.hpp:20:
In file included from ../../include/internal/iutest_message.hpp:20:
In file included from ../../include/internal/../iutest_env.hpp:20:
In file included from ../../include/internal/iutest_charcode.hpp:20:
In file included from ../../include/internal/iutest_port.hpp:24:
In file included from ../../include/internal/iutest_internal_defs.hpp:20:
In file included from ../../include/internal/../iutest_defs.hpp:20:
../../include/internal/iutest_compiler.hpp:38:12: fatal error: 'windows.h' file not found
#  include <windows.h>
           ^

../../samples/main.cpp should add these lines:
#include <vcruntime_new.h>                     // for operator new
#include "internal/../impl/../iutest_env.hpp"  // for Environment
#include "iutest_config.hpp"                   // for IUTEST_HAS_LIB
#include "util/iutest_util_output.hpp"         // for Console

../../samples/main.cpp should remove these lines:
- #include <iostream>  // lines 50-50

The full include-list for ../../samples/main.cpp:
#include <vcruntime_new.h>                     // for operator new
#include "../include/iutest.hpp"               // for AddGlobalTestEnvironment
#include "internal/../impl/../iutest_env.hpp"  // for Environment
#include "iutest_config.hpp"                   // for IUTEST_HAS_LIB
#include "util/iutest_util_output.hpp"         // for Console
---
Makefile:104: ターゲット 'main.o' のレシピで失敗しました
make: *** [main.o] エラー 7

Windows バイナリを使っているため、Windows sdk のパスを通さないといけません。
が、とりあえず sample.cpp に不要な iostream の include があるのがわかったので修正しました。

Visual Studio でできないか?
Visual Studio の拡張機能でないかなーと見ましたが、今現在はないもよう。
Clang for Windows があるし、このへんも対応してくれるとうれしいなーと思いました。
(※ なんとかできないか調査中)

2016/4/14 追記
include-what-you-use-cl を公開しました。
こちらは Visual Studio のプラットフォームツールセットとして、Include-What-You-Use を使えるようにするツールです。

git clone して install.bat を実行するとインストールされます。
別途、Include-What-You-Use.exe へのパスを通しておく必要があります。

インストールすると、プラットフォームツールセットに Include-What-You-Use の選択肢が出ます。

ビルドすると以下のように結果が出ます。


(※エラー出るかもしれませんが、依存関係の解析はできてるはず。)
(※なんでツールセットなのかは、ツールセットの定義の仕方の勉強がてらです。)

追記ここまで
==============

最後に
今回は、軽く触れる程度に Include-What-You-Use を紹介させていただきました。
では、また今度。


2015年11月16日月曜日

cpplint でコーディングチェック

Google Style Guides のチェックツールとして cpplint.py があります。
今回はこれを使って iutest のコーディングスタイルをチェックしてみました。

cpplint.py の使い方
cpplint.py は github から取得できます。クローンしてもいいですし、cpplint.py だけダウンロードしても OK です。
https://github.com/google/styleguide

iutest の場合



1行の文字数やスペース、改行の入れ方などの報告のほかに、explicit を付けましょうとか const 参照にしましょうなどの報告も出ました。

チェック内容
チェックされる内容は以下のものがあります。

buildclass
c++11
deprecated
endif_comment
explicit_make_pair
forward_decl
header_guard
include
include_alpha
include_order
include_what_you_use
namespaces
printf_format
storage_class
legalcopyright
readabilityalt_tokens
braces
casting
check
constructors
fn_size
function
inheritance
multiline_comment
multiline_string
namespace
nolint
nul
strings
todo
utf8
runtimearrays
casting
explicit
int
init
invalid_increment
member_string_references
memset
indentation_namespace
operator
printf
printf_format
references
string
threadsafe_fn
vlog
whitespaceblank_line
braces
comma
comments
empty_conditional_body
empty_loop_body
end_of_line
ending_newline
forcolon
indent
line_length
newline
operators
parens
semicolon
tab
todo

これらはコマンドラインオプションで有効/無効を設定できます。

警告の除外
該当行にコメントで NOLINT と書いておくと無視してくれます。
using namespace matchers; // NOLINT

それか、--filter コマンドライン引数で無視指定ができます。
警告の末尾に [runtime/explicit] とか [whitespace/end_of_line] とかタグが表示されますので、該当のタグの先頭に '-' を付けると無効にできます。複数指定する場合は、カンマ(,) で区切ります。

cpplint.py --filter=-runtime/explicit,-whitespace/end_of_line

行の長さの設定
1行の長さも --linelength コマンドライン引数で指定できます。

cpplint.py --linelength=150

まとめ
cpplint.py (Google Style Guides)の規則が必ずしも良い、正しいわけではありませんが、1つの指標として役に立つと思いました。iutest でも一通りチェックしてみて、可読性に対してやポータビリティなどに対して改善できました。
というわけで、cpplint を CI で回すようにしています。

来週は cpplint を回している CI サービスの紹介をしたいと思います。
それでは、また来週~




2015年10月27日火曜日

[Coverity] CEDEC 2015 で出題されたバグクイズ

バグクイズです!(CEDEC 2015 の問題) « Coverity Blog

CEDEC 2015 で出題されたバグクイズ。
私も実際に CEDEC に行って見てきたわけですが、
3日目の問題が直ぐに解けず、なんだか悔しかったのでこの記事を書いてる次第です。
(あーだこーだしているうちに2ヶ月も経ってしまいましたが…)

ちなみに、答えはこちらです。
CEDEC 2015 Tokyo でのバグクイズの正解を発表! « Coverity Blog

Coverity 以外では検出できないのか?

検証の際に実際に使用したソースコードはこちら。
https://github.com/srz-zumix/coverity_test/tree/master/cedec_coverity

Cppcheck v1.70
まずは、フリーで使える C++ 静的解析の定番となっている Cppcheck です。
使用したのは現時点での最新バージョンである 1.7.0 です。

残念ながら、どちらの問題も検出されませんでした。

Visual Studio コード分析
次に Visual Studio です。
Visual Studio にはコード分析機能が付いています。プロジェクトプロパティのコード分析で有効にできます。

これもかなり優秀なんですが…


残念ながら、どちらの問題も検出されませんでした。

gcc/clang
最後はコンパイラーです。
Visual Studio はコード分析のときにビルドしましたが、検出できなかったので既に脱落しております。

それぞれの結果です。


どちらも delete (void*)p の問題は検出されました。

scan-build
おまけです。
scan-build は clang の静的解析ツールです。
cygwin パッケージに入ってたので使ってみました。


結果としては clang コンパイラーと一緒で delete (void*)p の検出だけでした。

まとめ
Coverity すごい!!


2015年7月6日月曜日

[C++][静的解析] PVS-Studio を使ってみた



どうやら C++ の静的解析ツールに PVS-Studio があるらしい。ということで、使ってみました。

インストール
PVS-Studio は Visual Studio の拡張機能として使います。(単体でも使用可能
インストーラーのダウンロードはこちらから。
http://www.viva64.com/en/pvs-studio-download/

インストーラーをダウンロードしたら指示にしたがってインストールしてください。

トライアル版を使ってみて
iutest を解析した結果がこちら。
検出数は2つだけ。それもテスト用にわざと書いたコードでした。


よかったよかったと思ったら、これは Level1 の警告で Level2, Level3 の警告がまだありました。

トライアル版では見れない!!
うーん、これは気になる。商売うまいぜ…

ライセンス購入するにはメールを送る必要があるようで、ちょっと敷居が高く感じた。
値段もパッとわからなかったので、今回はここまでとします。

ちなみに、無料の C++ 静的解析ツールといえば Cppcheck が有名ですが、PVS-Studio と Cppcheck との比較資料もありました。
http://www.viva64.com/en/b/0149/

2014年7月15日火曜日

[C++] Coveralls でコードカバレッジ - その3 (lcov + lcoveralls)

前回、「Coveralls でコードカバレッジ - その2」でカバレッジ集計ができるようになったのですが、いつの間にかおかしな状態になってしまっていました。
なぜか CHANGED が 0 のままで前回との差分が見れなくなってしまいました。
ちょっとお手上げ状態なので、誰か助けてください。
と言うついでに、環境変えたら直るんじゃね?というとこから locv + lcoveralls に対応してみました。

lcov + lcoveralls に鞍替え
https://github.com/pcolby/lcoveralls
こちらに手順が書いてあるのでそのとおりに .travis.yml を編集します。
インストール
install:
  - sudo apt-get install lcov rubygems
  - gem install lcoveralls
ビルド ~ lcov
gcov のときと同様に -coverage オプションを付けてビルド、実行ファイルを実行します。
.gcda と .gcno が生成されるので、そこで
lcov -c -d . -o coverage.info
と実行する。
集計したくないファイルがある場合は、--remove(-r) オプションで削除します。
lcov -r coverage.info *gcc* -o coverage.info
lcoveralls
続いて、以下のコマンドを実行する。
lcoveralls coverage.info
今回は Travis CI 上で実行するので、token 指定は不要です。
もし、それ以外で実行する場合は --token オプションを指定する必要があります。

実行、結果
以上で設定は終わりです。実行すると以下のようにログが出力されます。

gcov + cpp-coveralls と比べて色付きログが出るの見やすい!
また、coveralls.io でちゃんと集計もされています。


が、やっぱり CHANGED は 0 のままで検出してくれませんでした。
しかたがないので、coveralls.io から一旦リポジトリを削除しました。

が、やっぱダメでした。

う~ん。困った。。。

2014/09/30 追記
issue 出てましたが、反応なし。
'source change' and 'coverage change' not detected · Issue #327 · lemurheavy/coveralls-public

2014年2月3日月曜日

[Cppcheck] cfg ファイル設定

Cppcheck 1.63 がリリースされました。
といっても大分前ですが…
調べたり検証したり別のことやってたりしてたら時間がかかってしまいました。

トラブってました
1.63 を早速インストールしたところ、下記のようなエラーが…
(information) Failed to load std.cfg. Your Cppcheck installation is broken, please re-install. The Cppcheck binary was compiled without CFGDIR set. Either the std.cfg should be available in cfg or the CFGDIR should be onfigured.
cygwin から実行すると動作して、コマンドプロンプトからだと上記エラーが…
どうしたものかと調べていたら、1.63.1 がリリースされました。
こちらをインストールしたところ、問題なく実行できました。

メデタシメデタシ。ですが、転んでもただでは起きません。
.cfg ファイルは今までノータッチでしたので、少し調べてみました。

書式
<?xml version="1.0"?>
  <def>
    <function name="ZeroMemory">
      <noreturn>false</noreturn>
    </function>
  </def>
マニュアルより引用

.cfg ファイルの中身は XML になっています。
<def> ノードの中に定義を書きます。

リークチェック
Cppcheck にはメモリ/リソースのリークチェック機能があります。
ただし、この機能を使うためには確保/解放関数を Cppcheck に教えてあげる必要があります。
定義は .cfg ファイルの <memory> および <resource> ノードに書きます。
<resource>
  <alloc>CreatePen</alloc>
  <dealloc>DeleteObject</dealloc>
</resource>
マニュアルより引用

alloc ノードに確保、dealloc ノードに解放関数を定義します。
allco ノードには init 属性を付けることができ、確保されたメモリ/リソースが初期化されるかどうかを true/false で指定できます。

関数
関数は function ノードに定義します。
function ノードでは <arg nr="1"> のようにすることで、各引数に条件を持たせられます。
(nr の値は引数の順番)

未初期化チェック
<function name="CopyMemory">
  <arg nr="2">
    <not-uninit/>
  </arg>
</function>
マニュアルより引用
not-uninit サブノードを追加することで未初期化変数を引数に渡された場合に警告を出すようにできます。

nullptr チェック
<function name="CopyMemory">
  <arg nr="1">
    <not-null/>
  </arg>
</function>
マニュアルより引用
not-null サブノードを追加することで関数引数の NULL チェックができます。

範囲 チェック
<function name="do_something">
  <arg nr="1">
    <valid>0-1023</valid>
  </arg>
</function>
マニュアルより引用
valid サブノードに有効な値の範囲を記述することで範囲外チェックができます。

書式文字列
<function name="do_something">
  <arg nr="1">
    <formatstr/>
  </arg>
</function>
マニュアルより引用
formatstr を指定することで %d %x などの書式のチェックがされるようになります。

return しない関数
<function name="ZeroMemory">
  <noreturn>false</noreturn>
</function>
マニュアルより引用
noreturn に true を指定することで、exit 関数などのような制御を返さない関数であることを通知できます。
また、false にすると制御を返す関数であることを明示的にし、パス解析を助けます。

その他
他にも not-bool や leak-ignore などマニュアルに書いていないものもあるようです。


cfg の保存
.cfg ファイルは cppcheck のインストールディレクトリ直下の cfg フォルダに保存するか、
任意の場所に保存し、cppcheck のコマンドラインオプションに指定することで有効にできます。
cppcheck src --library=my.cfg

試しに書いてみた
試しに .cfg 書いてみたのですが、思ったように書くことができませんでした。

クラスメンバーにある確保・解放関数を登録しようと考えたのですが、
まずメンバー関数に対しての書き方がよくわからない。
あーだこーだやってみたが全然検出してくれず…埒が明かん!ということでソースコードチェックアウトして確認しました。

結論としては「できません」。
cppcheck はトークンごとに解析をする感じになっていて、例えばメンバ関数の呼び出し
void* p = heap.MyAlloc(10);
は、
[void][*] [p] [=][heap][.][MyAlloc][(][10][)][;]
のように分解され解析されます。
alloc 関数かどうかの判定も1つのトークンで判定されるので、この場合 MyAlloc と書くことになります。

しかし、このとき alloc 関数かどうかの判定に使われるのは「heap」という名前です。
なんでと言われようがそうなっていたので、そうなのです。
当然マッチしません。

マッチしなかった場合、トークン列が [hoge][::] や [hoge][.] などにマッチするか判断します。
マッチした場合、現在のトークンの2つ先のトークンを関数名として使用します。
上の例では、「heap」 の次の次なので 「MyAlloc」。ようやくお出まし。

そして、取得した関数名から関数定義を引いてきて、return ステートメントなどから戻り値の allocType を判定します。
戻り値から判定するときにユーザー定義の alloc も参照しますが、「MyAlloc」が alloc 関数だと判定して欲しいので期待と異なります。

というわけで、メンバー関数呼び出しによるメモリリークの検出はできなさそうでした…残念orz
※ この記事はリビジョン 10720 で書いています。最新の動作と異なる場合があります。

なんにせよ、.cfg を使ったら検出率上げられるかもしれないので、試してみてはいかかがでしょうか?
以上。

2014年1月6日月曜日

SonarQube で C++ のコードを解析してみた

C++ の静的解析にはこれまで cppcheck を使ってきましたが、今回は SonarQube を使ってみたいと思います。
※ SonarQube で C++ の解析をする場合、プラグインのライセンス購入が必要になります。本記事ではトライアルキーを使用しています。

セットアップ~サンプルの解析
まずは環境をセットアップしたいと思います。
手順は公式ドキュメントを参考にしました。

サーバープログラムのセットアップ
ダウンロードページから sonarqube-X.X.zip をダウンロードします。X.X はバージョン番号です。
今回は 2013/11/21(検証したのが去年なの…) 時点での最新である、4.0 を使用しました。
ダウンロードしたら、解凍します。
保存先は C:\sonarqube か /etc/sonarqube にしましょうと書いてありますが、今回は D:\sonarqube\sonarqube に保存しました。

つづいて、プログラムを起動します。
sonarqube\bin\windows-x86-32\StartSonar.bat を実行すると以下のような画面が出ます。


クライアントのセットアップ
クライアント側をダウンロードします。
ダウンロードページの SonarQube Runner のところから sonar-runner-dist-X.X.zip をダウンロードしてください。(2013/11/21 時点での最新である、2.3 を使用しました。)
保存先は C:\sonar-runner か /etc/sonar-runner にしましょうと書いてありますが、今回は D:\sonarqube\sonar-runner に保存しました。

サンプルの解析
公式ドキュメントの手順 4. のダウンロードリンクからサンプルがダウンロードできるので取得し、解凍します。
保存先は C:\sonar-examples か /etc/sonar-examples にしましょうと書いてありますが、今回は D:\sonarqube\sonar-examples に保存しました。

展開したら、コマンドプロンプトで D:\sonarqube\sonar-examples-master\projects\languages\java\sonar-runner\java-sonar-runner-simple まで移動し、そこで sonar-runner.bat を実行します。
D:\sonarqube\sonar-runner\bin\sonar-runner.bat

INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
と、出力されたら成功です。
http://localhost:9000/ にアクセスすると以下のように結果が見れます。

プロジェクトページはこんな感じ。


C++ で試す
Java の解析ができたので、次は C++ を解析したいと思います。
SonarQube で C++ の解析をするためには、プラグインが必要になります。
こちらからプラグインがダウンロードできます。
sonar-cpp-plugin-X.X.jar(2013/11/21 時点での最新である、1.6 を使用しました。) がダウンロードされるので、そのファイルを
sonarqube\extensions\plugins にコピーします。

次にサーバーを再起動し、http://localhost:9000/ を開きます。
右上の Login ボタンをクリックし、administrator アカウントでログインします。
(デフォルトでは admin/admin)



ログイン後、右上の Setting ボタンをクリックします。
設定ページが開くので、General Settings > Licenses を開くと図のようなページが開きます。

C/C++ のライセンス入力ボックスにキーを入力します。(本記事ではトライアルキーを使用)

ライセンスキーの入力が完了したらプラグインを使用できるようになります。
まずは、サンプルを解析しました。
sonar-examples-master\projects\languages\cpp\cpp-sonar-runner で java の時と同様に sonar-runner.bat を実行します。
問題なく解析でき、以下のように結果が得られます。


サンプルの結果は公式ページからも見ることができるので、どんなものかすぐに見たい方はこちらからどうぞ。
http://nemo.sonarqube.org/dashboard/index/poco.net

iutest で試す
自作テスティングフレームワークの iutest を解析してみました。
結果がこんな感じ。

結構な数が出ました…ちまちま修正していきます…

Jenkins との連携
Jenkins との連携もできます。プラグインは Sonar plugin です。
その辺についてはこちらでは省きます。
詳しく知りたい人は、以下が参考になると思います。(セットアップも詳しく書かれています。)
SonarQubeをWindows環境で使ってC#コードを解析する - 亀岡的プログラマ日記
SonarとJenkinsを連携させる - 亀岡的プログラマ日記

感想
使ってみた感想。
検出数は多いのですが、コーディングルールに関するものが多くクリティカルな問題はあまり検出されないように感じました。(nullptr デリファレンスを検出できるか試したが、出なかった(※サンプルコードが悪かったのかもしれないが…))
複雑度やコード重複なども出力されるのでメトリクスツールとしては使えそうでした。

MIRSA や長い行・関数・引数、複雑度の高いものなどなど出ますが、自分のコーディングスタイルと合ってなかったり、直しようのないものもあったりしたので、これらの警告を無視/無効にする方法を調べないといけないと思いました。(トライアルライセンスの期限が切れてしまってるが…)

あとは、今回トライアルライセンスで検証しましたが、ライセンスが有料で € 7,000 するのがネックでしょうか・・・

2013年7月4日木曜日

[Jenkins] SourceMonitor Plugin を使ってみた

Jenkins のプラグインに SourceMonitor Plugin が新しくリリースされていたので、使ってみました。
コードメトリクスツールは Jenkins のプラグインがなかったという理由もあって、
SourceMonitor ではなく CCCC を使って来ました。
が、このプラグインが良ければ乗り換えもありだと思います。(CCCC の Jenkins プラグインはイマイチ。

SourceMonitor に xml を吐かせる
まずは、SourceMonitor から結果の xml を取得します。
/C コマンドオプションを指定して、動作を指示した xml ファイルを渡します。
今回使用した xml はこちらです。
<?xml version="1.0" encoding="UTF-8" ?>
<sourcemonitor_commands>
    <command>
        <project_file>iutest.smp</project_file>
        <project_language>C++</project_language>
        <modified_complexity>true</modified_complexity>
        <source_directory>trunk</source_directory>
        <file_extensions>*.h,*.hpp,*.c,*.cpp,*.cxx,*.ipp</file_extensions>
        <include_subdirectories>true</include_subdirectories>
        <export>
            <export_file>smdump.xml</export_file>
            <export_type>1 (project summary as XML)</export_type>
            <export_option>Include method metrics: option 3</export_option>
        </export>
    </command>
</sourcemonitor_commands>
SourceMonitor.exe /C smcmd.xml

Jenkins の設定
Jenkins の設定は簡単です。
まず、対象のプロジェクトの設定ページから、「ビルド後の処理の追加」をクリックし「Publish SourceMonitor result」を選択します。

次に、「SourceMonitor summary metric file path」に SourceMonitor から出力される xml のパスを指定します。

以上で設定は終わりです。

結果を見る
プロジェクトのページに「SourceMonitor result」があるので、クリックします。

すると、このような結果画面が表示されます。

残念ながら、モジュールや関数ごとの詳細な結果は見れないようです…

まとめ
CCCC Plugin と同様 SourceMonitor Plugin もまだまだイマイチな感じでした。
CCCC は junit 形式の xml に変換する c4ju を作って詳細な要素のテストに対応しました。
SourceMonitor も同じようにツールを作ればいいのですが、面倒臭いのでまたにします。


というわけで、しばらくはこれまで通り CCCC を使っていこうと思います。
以上。