Posted at
D言語Day 11

Digger なるツールについて

More than 3 years have passed since last update.

みなさん、DMD を自前でビルドしてますよね。


What's Digger?

Digger とは CyberShadow さんが開発している、DMD をビルドするためのツールです。もちろん D 言語製です。


DMD をビルドするツール

単にその時点で最新の DMD をビルドしたいのであれば、公式 wiki のガイドに従ってコマンドを打っていけばできるはずです。しかしながら、ある時点でのバージョンや未マージの pull request を適用したバージョンが欲しくても git になじみがない自分にはおっくうだったりします。

そんなときでも 1 コマンドでサクッとビルドできてしまうのがこのツールです。

また、同梱の digger-web というツールはフロントエンドがウェブブラウザであり、よさげな pull request や誰かがフォークしたものをポチポチと選ぶことができるので手軽です。


犯人捜しツール

もう 1 つの側面として、エンバグしたコミットを見つけ出す機能があります。これは git bisect を使った機能であるらしく、バグっていないコミットとバグっているコミットを指定し、その間からどこでバグったかをひたすらビルドとテストを繰り返すことで原因となるコミットを二分探索的に特定するもののようです。逆に、どこで正常になったのかを探すこともできます。


使い方


入手

Windows 版のバージョン 1.0 のバイナリがリリースページで公開されていますが、それ以外の環境では自前でビルドする必要があります。また、このリリース版は若干古いので Windows な人も自らビルドすればいいと思います。gitrdmd があれば README のとおりにすれば可能です。

執筆時点で最新の DMD 2.066.1 ではコンパイルエラーになるようで、対応策も出ていますが、そのうち直るかもしれません。

自分は 32 ビット Windows 版の 2.067.0-b1 を使いました。ライブラリが見つからないとリンカが言ってきますが、スルー推奨です。


DMD をビルドしてみる

以下、Windows での話です。他の環境では適当に読み替えてください。また、コマンドラインツールの digger を使うことにします。


ビルド

まずは digger.ini という設定ファイルを用意する必要があります。digger.ini.sample を参考に編集し、digger のあるディレクトリに置いておきます。とりあえず作業ディレクトリだけ変更したかったので次のようにしてみました。


digger.ini

workDir = d:\d\digger_tmp

[environment]


あとは


console_input

$ digger build


で GitHub の master から最新のソースを持ってきて、DMD, druntime, Phobos, rdmd とビルドしてくれます。なお、初回はビルドに必要なツールを自動でダウンロードし、作業ディレクトリに展開するようです。

無事に終われば最終的に


console_output

digger: Build successful.

Add d:\d\digger_tmp\result\bin to your PATH to start using it.


のように表示されるはずです。

どの時点での DMD が欲しいかは、このコマンドのオプションとして指定するわけですが、例によって README にさまざまな例があるのでそちらをどうぞ。


リビルド

ビルド後、ソースファイルは作業ディレクトリ内の repo に置かれています。そこのソースを編集した上でビルドしたい場合は


console_input

$ digger rebuild


とする必要があります。$ digger build ではソースがリモートの物で上書きされ、悲しいことになります。

リビルド機能はバージョン 1.0 には搭載されていないので注意してください。


単体テストなど

DMD のビルドでは単体テスト一式を走らせるのが儀礼ですが、残念ながらその機能は未搭載のようなので、公式 wiki のガイドのように手作業で行う必要があります。

ドキュメント生成や他のツールのビルド機能もないようなので、これも手作業でどうぞ。


bisect してみる


準備

bisect.ini を用意します。同様に bisect.ini.sample を元に作りましょう。

今回は std.rangeenumerate ができたタイミングを発見してみます。事実として、2014/09/20 にその pull request がマージされています。

では、次のような bisect.inidigger と同じディレクトリに用意します。


bisect.ini

bad  = @ 2014-09-19

good = @ 2014-09-21

reverse = true

tester = dmd -main -o- d:\d\digger_tmp\tester.d

[build]
model = 32
debugDMD = false

[environment]


reverse = true を指定したので、テスト失敗状態からテスト成功状態になったコミットを探すモードになりました。そのため、good よりも bad が古くなるように指定しています。テスト結果は tester で指定したコマンドの終了ステータスで判断されます。

今回はコンパイルエラーが出るか出ないかというテストを行うので、作業ディレクトリの d:\d\digger_tmp に次のようなテスト用のファイルを作ります。


tester.d

import std.range : enumerate;


コンパイルが成功し、dmd0 を返せばテスト成功です。


実行

次のコマンドを実行します。


console_input

$ digger bisect bisect.ini


すると、ひたすらビルドとテストが行われ、最終的にターゲットが捕獲されるはずです。


console_output

a46170ff9647111d45f5743139b95db19e9274f1 is the first bad commit

commit a46170ff9647111d45f5743139b95db19e9274f1
Author: Михаил Страшун <registrations@dicebot.lv>
Date: Sat Sep 20 16:14:02 2014 +0400

phobos: Merge pull request #1866 from JakobOvrum/enumerate

https://github.com/D-Programming-Language/phobos/pull/1866

Add std.range.enumerate

:160000 160000 cbdbf52cac4d408acf09a4e69d48d64ba795dc0c 2ad0698308c788c55ee0f2be30725d80c144f76f M phobos
bisect run success



最後に

最先端の D 言語を先取りしたい方々、コンパイラや標準ライブラリに手を加えたい方々には便利なツールではないでしょうか。