DをAntでビルド

D言語はモジュール(http://www.kmonos.net/alang/etc/d.php#module)というものがあって、これによってimport対象のファイルを指定することができる。モジュールは'.'を使って階層的に示すこともでき、Javaのパッケージに少し似ている。階層化された場合、Dのコンパイラは、カレントディレクトリがCLASSPATHに指定された場合のjavacと似た動作をするようだ。つまり'.'がディレクトリのセパレータのように扱われ、import abagames.util.Vectorはabagames/util/Vector.dを取ってこようとする。

Javaに慣れ親しんだ人間としては、やはりパッケージのようにソースをディレクトリに分けて管理したい。そのときに問題になるのは、Makefile記述の煩雑さだ。フラットにソースの.dファイルがある場合ならともかく、それらがディレクトリに散らばっているとなるといちいちそれをMakefileで指定するのが面倒である。Makefileを階層化するのはもっと面倒。

ならばAntである。

AntはJavaベースのビルドツールで、makeをよりよくしたものと言われている。makeと比べて記述が簡単であり、拡張性も高い。ただしその記述の簡易性は、Javaの持つ各種特性(ソースファイルとクラスファイルが1対1対応しているなど)によるところが多く、完全にmakeをリプレースできるものではなさそうだ。特にAntをJava以外のビルドに使うのは現実的でないと言う人も多い。

Use for non-Java projects not realistic without more builtin commands.

でもせっかくなのでDのビルドにAntを使ってみようとした。が、やはり問題発生。とりあえずコンパイルおよびリンクを行ってexeファイルを作成するところまではなんとかなった。が、コンパイル済みの.dファイルをコンパイルさせないために、.dと.objの依存関係を指定するところがうまくいかない。基本的にはmapperを使って対応を示してやればいいと思うんだけど、Antを良く分かってないせいか、なにか問題にぶつかる。以下の3つの問題のうち、どれでもいいから1つ分かればなんとかなりそうなんだけどなー。助けてAntの偉い人!

  • -ofの後スペースを空けずにtargetfileを指定する方法

applyを使ってdmd.exeを呼び出しているんだけど、特定のargsの直後に「スペースを空けずに」ターゲットファイルを指定する方法が分からない。dmdが'-offilename'っていうオプションになっているのだが、これに適合した外部ツール呼び出しができない。

  • dmdで.dと同じディレクトリに.objを配置する方法

dmdを使って普通にコンパイルすれば、.dと同じディレクトリに.objができるはずなんだけど、Antを通してやるとなぜかソースのルートに生成されてしまう。なのでmapperのglobタイプで依存関係を指定できない。

  • mapperでflattenしてかつ拡張子を変更する方法

特定のディレクトリに.objファイルを作ることはできるので、.dをflattenしてかつ.objに拡張子を変更できれば依存関係を指定できるんだけど、そんなtypeはありゃしねえ。

こういった細かいところに手が届かないのがAntの欠点なのかなあ。まあ独自タスクで拡張してしまえばなんとでもなるんだろうけど。

あとコンパイル済みのものが再コンパイルされるという挙動、実はあんまり困らないんだよね。Dのコンパイルがやけくそに速いので。はっきりいってAntが立ち上がるまでのオーバヘッドのほうがでかいと思う。ちょっとした規模のDプログラムだったら。