qbs の紹介

この記事は Qt Blog の "Introducing qbs" を翻訳したものです。
執筆: Jörg, 2012年2月15日

何年もの間、qmake とは愛憎の入り混じった関係を育んできました。ちゃんと仕事はしてくれるのですが、うまく行かないこともあり、多くの人がメンテナンスは不可能だと考えています。こちらのブログ記事 [TMQB] には qmake の次の世代へのウィッシュリストがあります。既に市場に出回っているたくさんのツールを考慮しましたが、要求を満たすものはありませんでした(例えばこちら [WNCM])。結局私たちは、少し前に社内でプロジェクトを立ち上げ、いくつかのアイデアを試すことになりました。その成果として Qt Build Suite、別名 qbs (「キューブス」と読みます) をご紹介します。

qmake との違い

qmake と違い qbs は Qt バージョンに依存せず、プロジェクトファイル内のハイレベルな記述から適切なビルドグラフ(依存関係グラフ)を生成します。また qmake や CMake のような既存のツールは Makefile のみを作成し、実際のビルドコマンドの実行は make や ninja に任せてしまいます。それに対し qbs は並行的に make をする役割を担い、直接コンパイラやリンカやその他のツールを呼びます。この点は SCons や Ant と似ています。

宣言型言語

qbs は QML を簡素化した言語で記述され、ソフトウェアプロジェクトを IDE フレンドリーな形で表現します。プロパティバインディングの右辺には、あらゆる JavaScript のコードが書けます。ファイルリストは単なる文字列の配列なので、プロジェクトファイルエディタで簡単に編集することができるでしょう。より複雑な構成では、代替手段としてテキストエディタで直接編集することもできます。

files: ["foo.h", "foo.cpp", "main.cpp"]              // editable from IDE
files: generateFileList().concat(['extra.cpp']) // only editable in your text editor

ほとんどの場合 IDE フレンドリーなプロジェクトファイルで事足りるはずですが、より複雑なことをしたい場合は JavaScript のスキルを最大限に活用することができます。

それでは、お約束の Hello World を見てみましょう。

// helloworld.qbp
import qbs.base 1.0

CppApplication {
name: "HelloWorld"
files: "main.cpp"
}

上記の import 文によって、アイテムを Application として使うことが可能になります。ここではアプリケーションの名前を HelloWorld とし、C++ のソースファイルを追加しています。

全体をカバーした言語の紹介は "language introduction" 以下のドキュメントをご覧ください。

拡張性

qmake でコード生成ツールやリソースコンパイラをいじるのは、誰もが避けたいところでしょう。qbs では、あるファイルを別のタイプに変換するためのルールを簡単に書くことができます。rcc のような外部プロセスを使うこともできますし、JavaScript で直接変換することもできます。以下に Qt Creator ソースツリーの .pluginspec.in ファイルを .pluginspec ファイルに変換する簡単な例を示します。

Rule {
...
prepare: {
var cmd = new JavaScriptCommand();
cmd.description = "generating " + FileInfo.fileName(output.fileName);
cmd.qtcreator_version = product.module.qtcreator_version;
cmd.sourceCode = function() {
var inf = new TextFile(input.fileName);
var all = inf.readAll();
all = all.replace(new RegExp('\$\$QTCREATOR_VERSION(?!w)', 'g'), qtcreator_version);
var file = new TextFile(output.fileName, TextFile.WriteOnly);
file.write(all);
file.close();
}
return cmd;
}
}

高速なインクリメンタルビルド

qbs はプロジェクトを全体として見るため、サブディレクトリに枝分かれする必要がありません。プロジェクトの一部しかビルドされない時も、全体のビルドグラフを考慮に入れて行われます。再帰的 make の問題(こちら [RMCH] をご覧ください)はもう存在しません。

これは結果として make よりもインクリメンタルビルドが早くなることも意味します。私はこちら [QPBS] にあるベンチマーク生成スクリプトを変更して qbs サポートを追加しました。200 のライブラリからなるプロジェクト(各ライブラリに 50 のクラスがあり、各ファイルが 30 の内部ライブラリと 10 の外部ライブラリをインクルード)のインクリメンタルビルドに対して行ったベンチマークの結果を以下に示します。

私のマシンで、ファイルを全く変更せず make でインクリメンタルビルドをすると、

real 0m4.076s
user 0m2.556s
sys 0m1.952s

同じ事を qbs ですると、

real 0m0.843s
user 0m0.724s
sys 0m0.112s

という結果になりました。

ビルド方法

説明はこれくらいにしておきましょう。コードを取得し、ビルドする手順を以下に示します。

git clone git://gitorious.org/qt-labs/qbs.git
cd qbs
qmake -r qbs.pro
make
make docs

まずはドキュメントを読んで下さい。特に "configuring qbs" は重要です。オンラインでは ここ で読むことができます。それから qbs/tests/manual 以下のサンプルプロジェクトで色々と試すのが良いでしょう。本物のプロジェクトで試したいという方は、Qt Creator 向けの qbs プロジェクトファイルを こちら から取得してください。

このプロジェクトへの貢献は大歓迎です。手順については Qt Project の wiki にある "Setting up Gerrit" を参照して下さい。Gerrit リモートの URL は <Gerrit/Jira ユーザー名>@codereview.qt-project.org:qt-labs/qbs です。

プロジェクトのメーリングリストは こちら です。

今後の展望

このプロジェクトはまだ実験の段階で、さまざまなビルドツールのコンセプトを試すための場所という位置づけになっています。qmake は今後も長い間使われ続けるので、qbs や他のビルドツールを使う義務はありません。私達はいつか qbs を Qt 独自のビルドシステムとして推進していこうとするかもしれませんが。

CMake や GNU Autotools といった一般的なビルドツールのユーザーの皆さんはお気づきかと思いますが、qbs がクロスプラットフォームのビルドツールとして受け入れられる為には一つの大事なパーツが欠けています。それはホスト環境への対応、つまりコンフィグレーションのチェックです。今のところは qbs が使う JSON ファイルを生成する為に外部ツールを使わなくてはなりませんが、もちろんこれは一時的なものです。他のツールと同様にコンフィグレーションのテストを使えるようにしたいと思っています。当然ながら宣言型言語だけで実装することはできないので、JavaScript のコードを使うことになるでしょう。

やることは山ほどあります。アイデアのリストについては、issue tracker をご覧ください。

参照

[RMCH] Peter Miller (1998), "Recursive Make Considered Harmful", AUUGN Journal of AUUG Inc., 19(1), pp. 14-25
[TMQB] Marius Storm-Olsen (2009), "To make, or not to make – QMake and beyond"
[WNCM] "[Qt5-feedback] Build system requirements for Qt5"
[QPBS] Noel Llopis (2005), "The Quest for the Perfect Build System"


Blog Topics:

Comments