#DUBとは
yum, apt-get, RubyGems, MacPorts, HomeBrewなどのパッケージマネージャを使ったことがある人なら、ライブラリの依存性を解決してくれるパッケージマネージャの便利さはご存知かと思います。
DUBはそんなパッケージマネージャのように、プロジェクトに必要なライブラリの依存性を解決してビルドしてくれるツールです。
#ビルド手順の簡略化
D言語に限らず、一般的に標準ライブラリでは事足りないプログラムを作成する手順と言うのは
- ライブラリを取ってくる
- (ライブラリをリンク可能な形にビルドする)
- ライブラリをinclude/import可能な場所に配置する
- ソースコードでライブラリをinclude/importする
- ソースコードをビルドする
- 実行する
と言った手順を踏みます。
持ってきたライブラリのバージョンが違っていたり、ライブラリのビルド方法が違っていたりするとビルド時や実行時にエラーが発生し、それを手作業で調査・解決する必要があって非常に骨が折れます。
DUBを用いると、上記の手順は
- プロジェクトフォルダのdub.jsonに必要なライブラリとバージョンを記述する
- app.dにエントリポイント(main関数)を記述したソースコード一式をsourceフォルダに配置する
- dub buildでビルドする
- dub(またはdub run)で実行する
のようになります。
dubが自動的にdub.jsonに書かれたライブラリをダウンロード、ビルド、リンクしてくれるので、プログラマはsourceフォルダでライブラリをimportしたソースコードを書くだけで実行可能なプログラムがビルドされます。
ライブラリを利用する際に生じるバージョン指定ミス以外の人為的なミスを無くすことが出来るので、より快適にソースコードを書くことが出来るようになります。
次の項目からは実際にDUBの使い方を説明していきます。
#DUBをインストール
Download - DUB registryでDUBの実行ファイルかソースコードをダウンロードしてインストールします。
Windows/Mac/Linuxのバイナリが用意されており、ソースコードやHomebrewパッケージ版もあるのでここで躓くことは無いと思います。
この記事を読んでいるということはD言語のコンパイラは当然インストール済みですよね?
#DUBプロジェクトを作成する
DUBのプロジェクトを作成する時は以下のコマンドを実行します。
dub init "プロジェクト名"
実行すると、以下のファイルが作成されます。
ファイル | 概要 |
---|---|
プロジェクト名/ | ルートフォルダ |
/source/ | ソースコードを配置する |
/source/app.d | プロジェクトのエントリポイントを記述する |
/public/ | 実行時に用いるファイルを配置する(Webサービス向け) |
/view/ | HTMLやUIテンプレートなどのインポート用テキストファイルを配置する(Webサービス向け) |
package.json | パッケージの概要を記述する |
Webサービス向けのディレクトリは、dub init時のオプションにタイプ"vibe.d"を指定した場合のみ作成されます。
#dub.jsonを記述する
出力されたdub.jsonは以下のような内容になっています。
{
"name": "project name",
"description": "An example project skeleton",
"homepage": "http://example.org",
"copyright": "Copyright © 2000, Your Name",
"authors": [
"Your Name"
],
"dependencies": {
}
}
nameはdub init時に記述したものになっているので、descriptionからauthorsまでは自由に記述しましょう。
dependenciesに使いたいライブラリの名前を記述していきます。
現在DUBが使えるライブラリは http://code.dlang.org/ に掲載されています。非同期Webアプリケーションフレームワークのvibe.d、マルチメディアライブラリのDerelictやOpenGL Mathライブラリのgl3nなど、実用的なライブラリが既に豊富に登録されています。
今回は前回の記事に合わせてDerelictSDL2を利用しましょう。
"dependencies": {
"derelict-sdl2": "~master"
}
JSONオブジェクトのキーがライブラリ名、値がバージョン番号となります。 ~masterはライブラリのリポジトリの最新を引っ張ってきます。
通常はこれで問題無いですが、バージョンが存在するライブラリでは比較演算子で指定することも可能です。
"dependencies": {
"dub": ">=0.9.18"
}
その他、コンパイラのオプションやソースファイルの位置なども指定できます。dub.jsonの詳しい書式についてはPackage file format - DUB registryを参照してください。
#app.dにソースコードを記述する
今回は前回の記事からのコピペで十分です。
app.dを書き換えましょう。
#DUBプロジェクトをビルドする
DUBではスタティックライブラリやダイナミックライブラリの管理も行えますが、今回はスタンドアロンアプリケーションなのでこのまま実行します。
dub build
実行すると以下のように表示されます。
Checking dependencies in '/project name/'
The following changes will be performed:
Install derelict-util ~master, userWide
Install derelict-sdl2 ~master, userWide
Downloading derelict-util ~master...
Installing derelict-util ~master to /Users/user name/.dub/packages/...
derelict-util has been installed with version ~master
Downloading derelict-sdl2 ~master...
Installing derelict-sdl2 ~master to /Users/user name/.dub/packages/...
derelict-sdl2 has been installed with version ~master
Building configuration "application", build type debug
Compiling...
Linking...
DerelictSDL2がまだインストールされていなかったので、DUBはリポジトリからmasterバージョンを取得してインストールしています。
また前回の記事で解説した通り、DerelictSDL2のビルド・実行にはDerelictUtilが必須です。
DUBのレジストリに依存関係が登録されているので、DUBはDerelictSDL2だけでなくDerelictUtilも自動的にダウンロードしてきます。
両方のインストールが終わると、DUBはソースコードとDerelictSDL2の依存関係を解決してプロジェクトをビルドします。
前回の記事で行ったDerelictSDL2とDerelictUtilを手動リンクする作業は一切不要です。
#DUBプロジェクトを実行する
最後に作成したファイルを実行します。ビルドされた実行ファイルを直接実行するのは勿論、DUBからも実行できます。
dub
# または
dub run
あ、各OS用のSDL2ランタイムをインストールすることを忘れないで下さいね。
#DUB対応ライブラリをインストールする
いちいちプロジェクトを作成してビルドしなくても、DUBを実行することでライブラリをインストールすることも可能です。この辺りはRubyGemsと同じです。
dub fetch "ライブラリ名"
dub remove "ライブラリ名"
dub list #インストール済みライブラリを表示
#DUBプロジェクトからIDE用プロジェクトファイルを自動生成する
DUBはD言語対応IDEを使う助けにもなります。
generateコマンドを用いることでプロジェクトからIDE用のプロジェクトファイルを作成することが出来ます。
dub generate "target" #visuald, visuald-combined, mono-d, build, rdmd
#終わりに
DUBは今後RubyGemsのように言語公式のパッケージマネージャとして推進されていくことが協議されています。
D言語はC言語のライブラリをリンクする事が出来、C++よりビルド速度が圧倒的に速く、近年ではコンパイラが洗練されてC/C++と遜色の無い実行速度も得られてきたのですが、
バージョンの整合性やC言語用ライブラリのリンクなどの事情があって、ライブラリの利用に他の言語と比べて一手間掛かるということであまり普及してきませんでした。
ですが、今回DUBの登場によってD言語のプログラミング環境が一気に改善されました。
今後はFacebookのように、D言語を用いるプロジェクトが増えていくことを望みます。