2014年1月27日月曜日

iutest v1.8.0 をリリースしました

iutest v1.8.0 をリリースしました。
今回の変更点は以下のとおりです。

  • 追加
    • IUTEST_*_EQ_RANGE を追加
    • IUTEST_*_STRIN,IUTEST_*_STRNOTIN を追加
    • IUTEST_FLAG(output) に対応
    • IUTEST_*_NO_FAILURE の gtest モード対応
    • Visual Studio Type Visualizer 用 .natvis ファイルを追加
    • AVR 対応
  • 変更
    • IUTEST_USE_THROW_ON_ASSERT_FAILURE を IUTEST_USE_THROW_ON_ASSERTION_FAILURE に変更
    • IUTEST_USE_THROW_ON_ASSERTION_FAILURE を指定した場合 SKIP や ASSUME も例外を投げるように変更
    • IUTEST_*_NO_FAILURE が警告やスキップを失敗と判断しないように変更
    • リスナーのセットアップ関数を変更
    • パッケージ内の値のパラメータ化テストのテストケース名が pkg.prefix/testcase となるように変更
    • IUTEST_SCOPED_PEEP,IUTEST_MAKE_SCOPED_PEEP を廃止
    • ソースコードのエンコーディングを UTF8 BOM 有りに変更
  • 修正
    • IUTEST_*_TRUE/FALSE を可変長対応
    • フィクスチャークラス名を IUTEST_TEST マクロのテストケース名に使用した場合にエラーになるように修正(MSVC拡張)
    • Visual C++ Compiler November 2013 CTP 対応
    • バグ修正

追加
EQ_RANGE などの新しい utilty アサーション追加、
未対応だった IUTEST_FLAG(output) と IUTEST_*_NO_FAILURE の gtest モードに対応しました。

あとは、VS Type Visualizer 用の .natvis ファイルを追加しています。
.natvis は Visual Studio のウォッチ式の表示を制御するファイルで、よりわかりやすい評価結果を表示します。
(追加した .natvis では テスト関数中に this からテストケース/テスト名が表示されるようにしてあります。便利かどうかはわかりません。)

Type Viualizer についてはこちらを参考にしてください。
[Visual Studio] デバッガー変数表示のカスタマイズ

変更
今回のバージョンでは少し大きめの変更があります。
まず、IUTEST_SCOPED_PEEP,IUTEST_MAKE_SCOPED_PEEP を廃止しました。
SCOPED のついたマクロは過去のバージョンの互換性のため残してありましたが、今回 IUTEST_MAKE_PEEP のバグ修正を機に廃止しました。

次に、ソースコードの文字コードを「UTF8 BOM あり」に変更しました。
この変更が一番大きいかもしれません。
iutest には日本語テスト名機能がありますが、そのテストコードが SJIS の場合に日本語名を不正な文字コードとしてエラーとなってしまうコンパイラがあったため、UTF8 に変更しました。
テストコードだけ変えれば良い話ですが、複数の文字コードが入り混じるのはよくないと考え「UTF8 BOM あり」に統一しました。
逆に SJIS でないとエラーになってしまうコンパイラもありますが、 iutest のメインターゲットではないので非対応としています。文字コード変換ツールなどで一度変換してからお使いください。
(※ 私は文字コードについて詳しくないのでアドバイス・ダメ出しなどドシドシください。)

次に、IUTEST_PACKAGE を利用した際のテストケース名を変更しています。
具体的には、これまではパッケージ化された値のパラメータテストのテストケース名は「prefix/package.testcase」となっていましたが、「package.prefix/testcase」になりました。
これは Jenkins でのテストケース名表示を考慮しての変更になります。


最後は、SKIP や ASSUME フレーバーに対する挙動で不自然だった部分を変更しました。
制御用マクロも若干変わっていますのでご注意ください。(旧マクロ名も一応まだ使えます。)

修正
修正はバグ修正が主ですが、2点だけとりあげておきます。

1つ目は、IUTEST_*_TRUE,IUTEST_*_FALSE で可変長マクロ引数対応をしました。
これにより、template 引数を複数指定するような記述で () で囲う必要がなくなりました。
template<int A, int B>
bool f() { return A == B; }
IUTEST_ASSERT_TRUE( f<1, 1>::value ); // OK

2つ目は、テストフィクスチャを定義したのにそれを使わないでテストを書いた場合にコンパイルエラーにする仕組みを入れました。
(※ ただし、__if_exists が使えるコンパイラに限ります。)
これは、自分自身がはまったから導入した機能で、
static int a=0;
class Hoge : public iutest::Test
{
protected:
    static void SetUpTestCase() { a = 1; }
};

IUTEST(Hoge,Test)
{
    IUTEST_ASSERT_EQ(1, a);
}
上記のように、本来ならば IUTEST_F(Hoge, Test) と書くべきところを、誤って IUTEST(Hoge, Test) と書いてしまったため、このテストでは Hoge::SetUpTestCase が呼ばれずテストが失敗してしまいます。
今回入れた機能により、上記コードがエラーになるようにしました。


すぐ気づきそうなミスですが、自分は結構悩んだので…
(ライブラリの初期化を SetUpTestCase で呼ぶようにしていて、テストで使用した API のエラーコードが「** は見つかりません」的なエラーコードが返るから、初期化されてないことに気付かなかった…(「初期化されてません」ってエラーコードだったらすぐわかったのになぁ…))

最後に
v1.8.0 については以上です。
iutest のご意見・バグ報告など頂けると、私がとても喜びます。
Google GroupSourceForgegithub または、このブログや twitter などでも構いません。よろしくお願います。

2014年1月22日水曜日

Windows で clang のビルド

Windows でも clang が使えるようにビルドしてみたので、個人用備忘録として残しておきます。
※ 完全に自分用の記事です。自分がした手順をまとめているだけです。
※ この手の情報は検索すればよく出てくるので、そちらを参考にしてもらったほうが良いです。

参照:
clang/LLVMをWindowsでビルドする - 原色奈良阪
LLVM を Windows で使う(clang 編) - 電脳スピーチ blog

準備したもの
MinGW
http://www.mingw.org/ からインストーラーをダウンロードしてセットアップ
※ 筆者環境は Windows 8 のためか、64bit 版の MinGW が必要になった。途中でダメなことに気づき 64bit 版のセットアップをしました。

CMake
cygwin の cmake は MinGW の Generator がなかったので、http://www.cmake.org/ から Windows インストーラーをダウンロードしてパスを通しました。

LLVM/clang
http://llvm.org/ のダウンロードページから LLVM source code と Clang source code をダウンロードし、
任意の場所に展開しました。
Clang は展開した後 clang にリネームして、llvm-3.3.src\tools に移動しました。


ビルド
パスを通す
MinGW のパスを環境変数に設定していないので、コマンドプロンプトを開いた後パスを通しました。
set path=C:\MinGW\bin;%PATH%
cmake
cmake のワーキングディレクトリとして、適当にフォルダを作成します。
今回は、build として作成しました。作成後、build ディレクトリに移動し cmake を実行します。
llvm-3.3.src>mkdir build
llvm-3.3.src>cd build
llvm-3.3.src>cmake -G "MinGW Makefiles" -D CMAKE_INSTALL_PREFIX=C:\usr\LLVM ..

libiconv-2.dll
cmake を実行したら libiconv-2.dll がないと言われて失敗してしまいました。
検索してもいまいちわからなかったので、msys の bin にあった msys-iconv-2.dll を C:\MinGW\bin にリネームしてコピーしました。
(今思えば コマンドプロンプトからではなく msys でやるべきだったのかも)

make
cmake が完了したら、build ディレクトリで make をします。
ビルドエラー
70% くらい進んだところでビルドエラーが発生
llvm-3.3.src\tools\clang\lib\Basic\FileManager.cpp:317:73: err
or: no matching function for call to 'clang::FileManager::getStatValue(const cha
r*&, _stat64i32&, bool, int)'
   if (getStatValue(InterndDirName, StatBuf, false, 0/*directory lookup*/)) {
検索したところ以下のサイトがヒットしました。
http://comments.gmane.org/gmane.comp.compilers.clang.devel/32242
そこから以下のサイトを参考にしたら解決したとのことなので、私も参考にしました。
https://github.com/KhronosGroup/webcl-validator#building-with-windows-mingw--msys
これによると、64bit 版の MinGW を使えってことのようです。
早速、MinGW 64bit 版をダウンロード、セットアップし、同様にビルドしました。
MinGW 64bit 版のセットアップはこちらを参考にしました。
PENGUINITIS - MinGW 64 bit 版 のセットアップ

ビルド(MinGW 64bit)
MinGW 64bit 版をセットアップし、 cmake からやり直しました。
(make.exe がなかったので mingw32-make.exe をコピー・リネームしました。)

これで無事ビルド完了。

最後に make install をします。
CMAKE_INSTALL_PREFIX で指定したパスにインストールされます。

Visual Studio でビルド
そもそもの目的が libclang 使ったツールを作ることだったので、Visual Studio でビルドしました。

LLVM と clang のソースを取得するとこまでは一緒で、cmake するときの -G オプションを "Visual Studio 10" にします。
cmake が無事に終わると Visual Studio のプロジェクト/ソリューションが出来上がるので、それを Visual Studio で開いてビルドするだけです。

特に問題なくビルドできました。
これで libclang が使えます。

Clang for Windows
先日リリースされた Clang for Windows には libclang が付いているので、libclang が使いたいだけならこれをインストールするだけで OK でした。。。

まぁ、ともあれ。
libclang のことは知らないことだらけなので、これから少しずつやっていこうかと思います。

2014年1月20日月曜日

[LLVM 3.4] Clang for Windows を使ってみた

clang 3.4 から Visual Sutdio 向けのツールセットが使えるようになりました。
これに関しては二、三番煎じもいいとこなので、説明を省きます。
Happy my life » Clang 3.4をVisualStudioから利用する

さて、早速 clang for windows をインストールして使ってみたのですが、
警告やらエラーだらけでビルドできませんでした。

その辺の解決方法を記しておきます。

warning : argument unused during compilation
warning : argument unused during compilation: '/Gm'

まず、コンパイラオプションに対して警告が出ます。
こちらは公式ドキュメントにも書いてあるとおりに、"-Qunused-arguments" オプションをつけると無視されます。

type_traits
type_traits ヘッダーでエラー
error : '_Ty' does not refer to a value
error : expected class name
__is_constructible などの builtin 機能がないためエラーになっているようです。
バグ報告もされています。
Bug 17926 – clang-cl: error compiling VC++12 type_traits header

type_traits ヘッダーは vector や tuple などから include されているので、単純に type_traits を include しないだけでは回避できませんでした。
ちょっと回避策もないので、次バージョンまで待とうと思います。。。