C/C++のコーディング中に静的解析を実行する。

目的

コーディング中にコンパイルと静的解析を実行し、問題箇所を早期に発見する。

方針

emacsとflymakeを使う。
flymakeのマニュアルに従って、make check-syntaxが呼ばれた時に、
C言語であればsplintを、C++であればcppcheckを呼び出すように設定する。

設定

0. ディレクトリ構成の例

設定例では、以下のディレクトリ構成を用いる。

$ls *
Makefile  test0

inc:
Foo.hpp

src:
Foo.cpp  main.cpp
1. Makefileにターゲット"check-syntax"を追加し、静的解析ツールを呼び出すように設定する

flymakeは以下のようなコマンドを作成して実行し、その実行結果を解析して、問題箇所をハイライト表示する。

make -s -C Makefileのあるディレクトリ CHK_SOURCES=ソースコードのフルパス SYNTAX_CHECK_MODE=1 check-syntax

以下の例のようにMakefileを書いておけば、静的解析ツールによるソースコードのチェックを行う事が出来る。

例: C言語の場合

check-syntax:
	gcc -Wall -Wextra -pedantic -fsyntax-only -I./inc $(CHK_SOURCES)
	splint -I./inc $(CHK_SOURCES)

例: C++11の場合

check-syntax:
	g++ -Wall -Wextra -std=c++0x -fsyntax-only $(CHK_SOURCES) -I./inc
	cppcheck --enable=all --std=c++11 --template gcc -q $(CHK_SOURCES) -I./inc

flymakeはソースファイルのあるディレクトリを順番に上がりながらMakefileを探す。

2. emacsにマスターファイル探索パスを追加する

flymakeはヘッダファイルの文法チェックをする際に、ヘッダファイルと同じ名前で拡張子だけ異なるソースファイルを、
flymake-master-file-dirsに束縛された相対パスのリストで示されるディレクトリ内から探す。
そして、見つかったソースファイルとヘッダファイルの内容をコピーしたソースファイルをソースファイルのあったディレクトリに作成する。
このコピーされたファイルをマスターファイルと呼ぶ。
flymakeは、このマスターファイルに対して文法チェックを行うことで、ヘッダファイルに対する文法チェックを行っている。

flymake-master-file-dirsはデフォルトでは("." "./src" "./UnitTest") であるため、incからsrcを検索出来ない。
以下の式を.emacs.d/init.elに追加して、incからsrcを検索出来るようにしておく。

例:

(push "../src" flymake-master-file-dirs)
3. hppをflymakeの対象に追加する

ヘッダファイルの拡張子として登録されているのが".h"だけなので、".hpp"もヘッダファイルとして扱うように登録する。

例:

(push '("\\.hpp\\'" flymake-master-make-header-init flymake-master-cleanup)
      flymake-allowed-file-name-masks)
4. 静的解析の結果を表示する

問題のあるコードがハイライト表示されている場合に、ハイライトされている箇所にカーソルを移動させ、
以下のページで掲載してくださっている"警告エラー行の表示のカスタマイズ"にある関数を評価すると、静的解析結果が表示される。
http://moimoitei.blogspot.jp/2010/05/flymake-in-emacs.html

5. その他

flymakeの動作があやしい場合には、以下のように設定して*Message*のログを確認すると原因がわかるかもしれない。

(setq flymake-log-level 3)

cppcheckは関数テンプレートをチェックしてくれない。
splintはチェックが厳しすぎて使いづらいかも。