D言語研究室



D言語のインストール

D言語をインストールする - makeを使ってビルドする - 秀丸からビルドする - デバッガで追いかける - antによるコンパイル - D言語のソースにdoxygenを使う - DIDEでビルドする

D言語をインストールする

run.bat (shellを呼び出すバッチファイル) - all.sh (shellの定義ファイル)

D言語[Digital Mars Dの翻訳]ページの「D コンパイラ」のところからdownloadページに飛べます。インストール方法もそこに書かれています。わからなければ、D言語チュートリアル[日本語]のほうも参考にしてください。

dmd\binにpathを通しておかないといけないようですけど設定が何かと面倒っぽいので、素直に c:\ に 解凍して出来た dmd と dmフォルダを置くことにします。

※ DIDE(D言語用のIDE)のページからDIDE with Dというのをダウンロードすればインストールの手間が省けるようです。

コンパイルに際してはいちいちコマンドプロンプトで作業するのは面倒なので次のようなshellを呼び出すバッチファイルを組んでおきます。

run.bat (shellを呼び出すバッチファイル)

shell all.sh

all.sh (shellの定義ファイル)

# Little shell script to compile, link, and run all the samples.
# Use \dmd\bin\shell.exe to execute.

DMD=\dmd\bin\dmd
DFLAGS=

$(DMD) hello $(DFLAGS)
hello

makeを使ってビルドする


makeを使うのが基本でしょう。makeを使ってコンパイルしてみます。

代表的なmakeと言えばMicrosoft系のnmake(VisualC++とかに付属している)か、cygwinに付属しているmakeかですが、前者はフリーではない模様。後者は、cygwin環境でなければ動作しないようです。(cygwin.dllが必要)

dmdコンパイラ付属のmakeは、フォルダ名に半角スペースがまじっているとうまく動きません。dmdコンパイラ付属のshellも同様の問題があります。つまりは「Documents and Settings」とか不可になります。このディフォルトで作られるフォルダ名にスペース入れるのやめて欲しいですけど>Microsoft..

そこで、MinGWのほうのmakeをdownloadしてきます。
http://www.mingw.org/download.shtml

MinGWのほうのmakeは、ダブルコーテーション" "でフォルダ名やファイル名を囲むことが出来ますので、これに対応できます。

bin mingw32-make-3.80.0-2.exe
って書いてあるのが実行ファイルのようです。インストーラー付きなのでmingw\bin\とかいうフォルダに入ります。どっちかと言うと実行ファイルだけが欲しいです。(;´Д`)人

インストール先に
mingw32-make.exe
というファイルが出来るので、これをmakeとリネームして使うことになります。

makefileの書き方[英語]
http://www.mingw.org/mingwfaq.shtml#faq-Makefile

makefile というテキストファイルを用意して、以下のよう編集。
make.exe を実行すれば、コンパイル出来ます。
(make.exeはmakefileと同じフォルダか、pathの通ったフォルダに。)


# ここでソースを指定してやる
#  sdl.libなどの追加ライブラリもここで指定してやる
SRC = test.d

# コンパイラ本体の位置
DMD = "\dmd\bin\dmd"
# リンカーの位置は、DMDコンパイラの存在するフォルダに対して、
#  ../../dm/bin/linkと決まってるいようだ

#  追加のinclude path
INCLUDE = 

# コンパイルオプション
# (リリース時)
DFLAGS = -O -release
# (デバッグ時)
#DFLAGS = -debug -g

# -----  以下はいじらなくてok --------------

# objファイルは拡張子を置換したもの
#OBJ = $(SRC:.d=.obj)

# これが依存関係
all : $(SRC)
	$(DMD) $(SRC) $(DFLAGS) -I$(INCLUDE)


関連項目:→make関連リンク

make(GNU make)では、ソースファイル名の指定はwildcardが使えます。

以下は、ロベールさんが書かれたmakefile。DMDコンパイラのリンカーは、ファイル名に'/'を受け付けないので、ファイル名を'\'に置換する処理も含まれています。



TARGET = foo.exe
SRCS   = $(wildcard */*/*/*.d */*/*.d */*.d *.d) # 必要なだけ
OBJS1  = $(SRCS:.d=.obj)
OBJS2  = $(subst /,\\,$(OBJS1))

%.obj: %.d
		dmd -of$@ -c $<

$(TARGET): $(OBJS1)
		dmd -of$@ $(OBJS2)

clean:
		rm -f $(OBJS1) *.map *.exe



※ makeというか、MS-DOSだとWin9x系はコマンドプロンプト1024文字制限(だったかな)があって、これ以上長い文字列は渡せません。そこで、ファイル数が多くなってくるとこの制限にひっかかります。これを回避するには、dmdコンパイラに、コンパイルオプションを@を使ってファイルに書かれた内容を指定してやれば良いでしょう。→ yaneSDK4D本体のダウンロード のコーナーに dmake追加。

例:
dmd @optfile.txt
(optfile.txtには、コンパイルオプションが書かれている)

秀丸からビルドする


私はテキストエディタとしては秀丸を愛用しているのですが、秀丸のマクロ機能を使い、裏でmakeを起動して、エラーが発生すればエラー行へ飛ぶというようにしました。

今回は、このマクロについて解説します。

秀丸エディタについては、
http://hp.vector.co.jp/authors/VA001418/

makeについては、makeを使ってビルドするをご覧ください。

まず、makeerror.logというファイルにmake中のエラーを吐くmakefileを作ります。makeを起動するときにリダイレクトしても良いのですが、秀丸ではちょっと難しいようなので、makefileのなかで指定します。

# ここでソースを指定してやる
#  sdl.libなどの追加ライブラリもここで指定してやる
SRC = test.d

# コンパイラ本体の位置
DMD = "\dmd\bin\dmd"
# リンカーの位置は、DMDコンパイラの存在するフォルダに対して、
#  ../../dm/bin/linkと決まってるいようだ

#  追加のinclude path
INCLUDE = 

# コンパイルオプション
# (リリース時)
DFLAGS = -O -release
# (デバッグ時)
#DFLAGS = -debug -g

# -----  以下はいじらなくてok --------------

# objファイルは拡張子を置換したもの
#OBJ = $(SRC:.d=.obj)

# これが依存関係
all : $(SRC)
	$(DMD) $(SRC) $(DFLAGS) -I$(INCLUDE) > makeerror.log
#	test.exe	# ついでに実行するならここに書くべし


秀丸用のマクロは、以下のような感じです。そのままコピペして、適当な名前(拡張子は.mac)をつけて保存し、秀丸エディタのインストール先のフォルダへ入れてやります。秀丸のディフォルトのインストール先は、C:\Program Files\Hidemaruです。

そのあと、メニューの「マクロ」→「マクロ登録」で、タイトルは「DMDコンパイル」とでも名前をつけて、ファイル名としてこのマクロファイル名を指定してやります。

ついでにF5キーあたりでこのマクロが起動すると使い勝手がいいので、「その他」→「キー割り当て」でキーとして「F5」を選択し、コマンドとして「メニュー/マクロ」を選び、さきほど名前をつけた「DMDコンパイル」というマクロを選択してやります。


//	makeによるエラーログファイル名
$ERROR_LOG = "makeerror.log";

//	編集中のファイル名を保存
save;

//	編集中のファイル名を待避
$f1 = basename;

if ($f1==$ERROR_LOG) {
	message "D言語のソースではありません。";
	quit;
}

#c = findhidemaru($ERROR_LOG);
//	閉じる必要がある..
if (#c != -1) {
	closehidemaru(#c);
}

//	裏でmakeを起動
runsync2 "make";

openfile "/(0,0,600,200) makeerror.log ";

//	先頭行へ移動
golinetop;

searchdown "(";

//	(231)のようにタグジャンプ指令があるならそこにジャンプしてみる
if (result == 1) {
	//	タグジャンプしてみる
	tagjump;
} else {
	//	なければ元のファイルの編集に戻る
	setactivehidemaru(findhidemaru($f1));
}


これでD言語のソースを秀丸で編集し、F5を押すだけでエラー行へ飛べるようになりました。なかなか便利ですね。

デバッガで追いかける


デバッガが使いたい場合、gdbには現状対応していないようなので、

windbg:
http://www.microsoft.com/whdc/ddk/debugging/default.mspx

を用いるか、VisualStudioを使っている人ならば、VisualStudioからデバッグしてもいいでしょう。

VisualStudioでデバッグする場合は、プロジェクトを作って(Visual C++のWin32プロジェクトがお手軽)そのなかでやるといいでしょう。以下、VisualStudio.NETでのデバッグ例。

1.-gオプション付きでコンパイルする。
2.VSを起動して、「ソリューションを開く」で作成したexeを開く。普通に「開く」やドラッグアンドドロップで開くとリソースの編集画面になってしまいます。「ソリューションを開く」がポイント。
3.IDEに自分で作ったソースコードをドラッグアンドドロップします。
4.(試しに)そのソースコードの適当な部分にブレークポイントを設定してF5を押す。

まあ、3.までくればあとはステップイン/ステップオーバーを駆使してデバッグしていけます。

antによるコンパイル

Javaのビルドツールとしては、Ant[ビルドツール]が有名でしょう。起動が遅いらしいので、私は使っていなかったのですが、長 健太(ABA."Saba")氏の日誌にantに関する情報が載っているので、関連記事を引用させていただきます。


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

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

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

2003-08-26
昨日のDをAntでビルド話(id:ABA:20030825#p1)続き。コメントいただいたとおり、
'-op'オプションでばっちりいけました。これで.dと.objを同じディレクトリに
配置できたので、mapperのglobタイプで依存関係が示せます。
具体的には、以下のような感じ。

<property name="import" location="import"/>
<property name="src" location="src"/>

<target name="compile">
  <apply</pp>
	executable="dmd"
	dir="${src}" dest="${src}" parallel="false" failonerror="true">
	<mapper type="glob" from="*.d" to="*.obj"/>
	<fileset dir="${src}" includes="**/*.d"/>
	<arg value="-c"/>
	<arg value="-I${import}"/>
	<arg value="-op"/>
	<srcfile/>
  </apply>
</target>

(<applyの後に</pp>っていう謎のタグが付いちゃうんだけどなんだこれ?
こんなの書いてないんだけど。どうやっても消えないし)

2003-08-29
ファイル間依存関係が強すぎないか? 
前に苦労してAntのbuild.xmlを書いて、修正されたDファイルのみ再コンパイルされる
ようにしたが、リンカが思ったほどよきにはからってくれない。あるファイルのどこ
からも呼ばれていないメソッドを1つ削除してコンパイル、リンクすると、
Access Violationを起こすこともある。

2003-12-08
Antの高速化
D言語で書いたゲームのビルドを、私はAntでやっている(id:ABA:20030826#p1)のだが、
Antの大きな欠点として、makeと比較すると動作が遅いということがある。

Antが遅い理由は明らかで、Antコマンドが叩かれるたびにJavaVMを起動している
ためだ。いくらJavaが速くなったといっても、相変わらずVMの起動は非常にコストの
かかる動作で、すかっと立ち上がるものにはなっていない。

ならばVMを立ち上げっぱなしにしておけばいいんじゃねーの、っていうのが自然な
解決方法で、そのためのツールが'Sweet Ant Tools''Ant Console'だ。

Sweet Ant Tools(http://www.sdv.fr/pages/casa/html/sat.doc.en.html#3) 
build.xmlがあるディレクトリ上でこのAnt Consoleを立ち上げておけば、あとは
コンソール上で'all'とでも入力するだけで、さくさくビルドできる。2回目以降は
リターンを押すだけでよい。Antの遅さに辟易している人にお奨め。


ということで、非常に詳しく書かれているので、私がここで説明することは何もなくなってしまいました。(´Д`)

D言語のソースにdoxygenを使う

仕様書の作成に関しては、C++やJavaなんかだと、doxygen[仕様書生成ツール]を用いるのが一般的のようですが、D言語の場合はどうなのでしょうか?

C++とD言語とは言語的には似通っているので、少しソースをコンバートしてやればdoxygenでも変換できます。

コンバータは、Matthew Wilson氏(Dr Dobb's JournalやC/C++ User's Journalのライター)が、news groupに投稿していました。
http://www.digitalmars.com/drn-bin/wwwnews?D/18911

使ってみてわかったのは、
・doxygenは日本語フォルダ名不可。
・dfilterに一つずつファイルを渡してリダイレクトして使う
(実際にはmakefileを書くと良い)

以下サンプルは.d => .cppへの暗黙の変換規則でdfilterを用いてます。実際には.cppファイルは生成していません。makeのforeachの使い方がいまいちわからなかったのでこうやってます_| ̄|○

makefile

YANESDK4D_INCLUDE = yaneSDK4D

YANESDK4D = $(wildcard $(YANESDK4D_INCLUDE)/*/*/*.d \
$(YANESDK4D_INCLUDE)/*/*.d $(YANESDK4D_INCLUDE)/*.d)

#   ---- yanesdk4d用document生成用project

%.cpp: %.d
    -dfilter $<
#       ↑c:\\doxygen\\yaneSDK4Dフォルダに変換後のソースをぶちこむのだ。

TXTS1  = $(YANESDK4D:.d=.cpp)
TXTS2  = $(subst /,\\,$(TXTS1))

doc : doc_imp $(TXTS2)
    doxygen "c:\doxygen\doxygen.def"
    del "html" /S /Q
    xcopy c:\doxygen\html "C:\Documents and Settings\yaneen\デスクトップ\因幡物置\develop\研究室\d言語\work\test4(yaneSDK4D)\html" /S /Y
    del "c:\doxygen\yaneSDK4D" /S /Q
    del "c:\doxygen\html" /S /Q
# ↑doxygenは日本語フォルダ名不可なのでコピーしておく

#↓delすると、サブフォルダまで消してしまうので、サブフォルダを再現するためのxcopy

doc_imp:
    xcopy "C:\Documents and Settings\yaneen\デスクトップ\因幡物置\develop\研究室\d言語\work\test4(yaneSDK4D)\yaneSDK4D" "c:\doxygen\yaneSDK4D" /S /Y


備考:あとで掲示板のほうで教えていただいたんですけど、static ruleを用いれば以下のように書ける模様。

DSTDIR:=別のフォルダ
DSTSRC:=$(addprefix $(DSTDIR)/,$(SRC))
$(DSTSRC) : $(DSTDIR)/%.d : %.d
 dfilter $< >$@


また、doxygenのほうは、INPUT_FILTERという設定で、dfilterを指定すれば、そのまま変換できるんじゃないかという指摘をMLで受けました。


試してないのでなんとも言えませんが・・・
Doxyfileの中のINPUT_FILTERにdfilter.exeを
設定するのではダメでしょうか?
こんなかんじ↓
	INPUT_FILTER = dfilter.exe

私はLinuxでSJISのソースコードをDoxygenにかけるとき
	INPUT_FILTER = "nkf -eLu"
とかやってるので・・・


な、、なるほど。そんな機能あるんですね..。

さて。D言語のソースを上記のdfilterを通過させてdoxygenを使ってみた感想ですけど、なかなかうまく変換できています。

気づいたこととしては、
・コンストラクタがthis()なので、コンストラクタとして認識してくれない。(これは、doxygen側の問題でしょうけど。)
・デストラクタは~this()なのでデストラクタとして認識してくれる
・例外はErrorから継承しているのですが、これが基底クラスだと認識してくれない。(doxygen側の問題?)
・private class ...のような書き方をするとmodule内privateとして認識されない
private: class ... のように : であればprivateだと認識します。これはdfilterの変換上のバグだと思います。
・delegateを用いている部分は関数ポインタ表記に変換される。

です。template内のクラスはある程度うまく変換できています。

このdfilterをHauke Duden氏が、さらに改良し、doxygenのほうにもパッチを当てて、本格的にDに対応させたそうです。
http://www.digitalmars.com/drn-bin/wwwnews?D/20989

Hauke氏から、Win32用のバイナリをメールでいただきましたので、以下に置いておきます。(doxygenのバイナリ、dfilterのソース、バイナリ付き)

ddoc.zip

doxygenはMS-DOSのpipeを使ってdfilterを通すようなんですが、どうもMS-DOSは、unicodeのpipeに問題があるようで、化けます。そこで、ソース全体をフォルダまるごとxcopyしたあと、UnicodeからMCSに変換しておきdoxygenを実行する必要があります。

yaneSDK4Dを用いて、c:\doxygen\yaneSDK4D以下のすべてのファイルをunicode -> mbsに変換するサンプル:


	DirEnumerator d = new DirEnumerator;
	d.setDir(r"c:\doxygen\yaneSDK4D");
	foreach(char[] filename;d){
		printf("now convert %.*s\n",filename);
		void[] v = FileSys.read(filename);
		if (v) {
			void[] v2 = cast(void[])(toMBS((wchar[])v));
			FileSys.write(filename,v2);
		}
	}
	return 0;


DIDEでビルドする


DIDEを用いて、yaneSDK4Dをビルドしてみました。

手順1.DIDEは、path名に空白(例:Document and Setting)が含まれているとうまくコンパイルできないようなので、yaneSDK4DとSDLのフォルダの中身を、c:\dmd\includeに放り込みます。


c:\dmd\include\y4d.d
c:\dmd\include\ytl\vector.d
c:\dmd\include\ytl\list.d
(中略)
c:\dmd\include\SDL.d
c:\dmd\include\SDL_image.d
(以下略)


手順2.プロジェクトを作成し、これらのファイルをプロジェクトに追加します。プロジェクトに追加しておかないと、リンカがシンボルを解決できません。

手順3.Setting → Project Settings → Linker Settings の Librariesの、下側の記入欄で「SDL.lib opengl32.lib SDL_image.lib SDL_mixer.lib SDL_ttf.lib」などと、使用するlibファイルを指定します。

これでコンパイルできます。


Last Updated : 2004-4-19

written by yaneurao
http://bm98.yaneu.com/dlang/