2016年2月2日火曜日

[C/C++][Clang] include 解析ツールを作った

無駄な include を消したいなーと思って、そのためにまずは解析できるようにならないと、と Clang を使ってやってみました。

ビルド環境構築
clang ソースのセットアップ
LLVM.org から LLVM と clang のソースをダウンロードします。
それぞれ展開をし、LLVM は任意のファルダに保存してください。

ここでは、 D:\usr\local\LLVM に置いたこととします。
clang は展開したフォルダを "clang" にリネームして、 D:\usr\local\LLVM\tools\clang に置きます。

clang のビルド
今回は Visual Studio 2015 向けにビルドします。
その前に CMake が必要になるので、インストールしておいて下さい。

コマンドプロンプトを開き、LLVM ソースフォルダに移動して、以下のコマンドを実行します。
LLVM> set path=%ProgramFiles(x86)%\CMake\bin
LLVM>mkdir build
LLVM>cd build
LLVM\build>cmake -G "Visual Studio 14" -D CMAKE_INSTALL_PREFIX=D:\LLVM ..

最初に path を書き換えているのは、cygwin のパスが通ってると CMake に失敗するためです。
CMAKE_INSTALL_PREFIX にはインストールフォルダを指定します。今回は D:\LLVM としています。
CMake が成功すると、LLVM.sln が出来上がってるのでビルドします。

ビルドができたら、INSTALL プロジェクトを選択してビルドします。
CMAKE_INSTALL_PREFIX に指定したところにインストールがされますので、これで完了です。

事始め
まずは、なにかサンプル的なものをビルド・実行できるようにするとイイと思います。
今回私は、以下のページを参考にしました。

include の解析
今回は #include の依存関係を知ることが目的です。
プリプロセスの追跡には PPCallbacksTracker を使うことになります。

そして include の依存関係から dot ファイルを作成するスゴク参考になりそうなものが clang/lib/Frontend/DependencyGraph.cpp にあります。
これを参考に書いたのがこちら。
https://github.com/srz-zumix/cincluder

システムファイルを除外したり、複数ファイルから include されているファイルに色付けするようにしています。
iutest を解析した結果がこちら。


コマンドラインオプション
cincluder を書いていて独自のコマンドラインオプションに対応したいなと思って調べたのでメモ。

static cl::OptionCategory CincluderCategory("cincluder");
static cl::opt< ::std::string > DotFile("dot", cl::init("cincluder.dot"), cl::desc("output dot file"), cl::cat(CincluderCategory));

cl::opt でオプションを定義します。
最初の文字列がオプション名で、あとは init で初期値、 desc で説明、 cat でカテゴリ情報を付与しています。
これらの設定には、cl::Positional とか、 cl::Required とかもあるみたいです。
他にどんな設定があるかは、 LLVM/include/llvm/Support/CommandLine.h を参照してください。

最後に
LibTooling 難しそうと思ってましたが使ってみたらそうでもなく、やりたいことがこんなにも簡単にできてしまうのかー、と驚きました。
「できる」というのが分かってしまえば気楽なもんで、お仕事とかでも気軽にツール作りができそうです。

0 件のコメント:

コメントを投稿