Ubuntu Weekly Recipe

第244回JHBuildでGNOMEをビルドしよう

はじめまして。松澤二郎と申します。GNOMEプロジェクトの日本語翻訳メンバーとして、GNOMEの翻訳と、そのためのGNOMEのビルドをする日々を過ごしています。翻訳をするためには最新のアプリケーションのUIを確認する必要がありますが、開発版のUbuntuやPPAでも提供されていないものは、自分でビルドすることになります。

今回は、JHBuildというツールを使って、最新のGNOMEをビルドする方法を紹介します。

JHBuildとは

JHBuildとは、GNOMEプロジェクトが配布する各種プログラムをビルドするための、Pythonベースのツールです。

GNOMEからはさまざまなプログラムのソースパッケージが配布されています。GNOMEでは、各ソースパッケージをモジュールと呼んでおり、それぞれGitリポジトリで管理しています。各モジュールは複雑な依存関係を持っており、ひとつひとつ手でビルドするのは至難の業です。

JHBuildは、各モジュールの依存関係を解決し、ソースの取得、ビルド、インストールまで自動実行してくれるツールです。しかも常に最新のリビジョンを追うことができます。主に、テスターや翻訳者、最新機能を試したいユーザーなどに利用されています。

JHBuildの仕組み

依存関係の解決

ファイルマネージャーのNautilusをビルドするケースを例に説明しましょう。Nautilusは、GTK+やGLibなどに依存しています。さらにGTK+はGLibやGDK-PixBufなどに依存しています。GDK-PixBufはlibpngなどにも依存しています。こういった依存関係を再帰的に解決して、もっとも土台となるモジュールから順にビルドしていきます。なお、先に示したlibpngなどはGNOMEのモジュールではありません。そうしたGNOME外部の依存物のいくつかは、システムモジュールと呼び、各ディストリビューションのパッケージ(Ubuntuではdebパッケージ)を利用して依存関係を解決します。

依存関係は、モジュールセットファイルと呼ばれる、JHBuild独自のXMLで記述しています。ファイルの例はJHBuildのリポジトリから参照できます。

ビルドの自動化

モジュールセットファイルには、依存関係だけでなく、各モジュールのGitリポジトリの場所やブランチ名などソースの取得方法、デフォルトのビルドオプションなども記載されています。この情報に基づいて、ビルドするモジュールすべてに対して、ソースの取得、ビルド、インストールを自動で行います。ビルドオプションは、ユーザーの好みに応じて変更可能です。

JHBuildでビルドしたファイルは、システム環境(/usrなど)とは独立した場所にインストールされます。JHBuildは、rootユーザーやsudoなど管理者権限で実行できないようになっており、一般ユーザーの権限で書き込み可能な場所にしかビルドしたファイルをインストールできません。インストール先はユーザーで設定できます。

JHBuildのセットアップ

今回は、JHBuildを使って最新のNautilus 3.6をビルドしてみます。Nautilus 3.6は次期12.10には搭載されませんが、検索機能の強化やワークフローの改良など多くの改善が図られています。ちょっと試してみたいというユーザーもいるのではないでしょうか。

12.10 Beta2を利用

それではJHBuildをセットアップしましょう、と行きたいところですが、残念ながら12.04のJHBuildはバージョンが古く、最新のモジュールセットファイルを解釈できません。そのため今回は12.10 Beta2を利用することにします。

VirtualBoxなど仮想環境を利用することをおすすめします。仮想環境を利用するメリットは他にもあります。先述の通りJHBuildは、システムモジュールをパッケージとしてインストールする必要があるため、仮想環境を利用すればビルドのためだけに本番環境を汚さないで済みます。なお、VirtualBoxでディスク容量を指定する場合、今回の作業を試すだけでも12GB以上は確保するようにしてください。今回のNautilusのビルド作業では、JHBuildが生成するファイルだけでも6GBは使用します。

必要パッケージのインストール

次のパッケージをインストールしてください。JHBuild以外にもいくつかのビルドツールなどをインストールしています。

$ sudo apt-get install jhbuild libtool autopoint flex bison valac libxml2-utils docbook-xml docbook-xsl libxml-simple-perl xsltproc apt-file

上記でapt-fileもインストールしています。apt-fileをインストールすると、apt-fileのデータベースをアップデートするようダイアログが表示されます。ダイアログ上の「このアクションをすぐに実行する」というボタンを押してください。

図1 apt-fileのアップデートダイアログ
図1 apt-fileのアップデートダイアログ

コンフィグファイル

ビルドしたファイルのインストール先などを指定するためのコンフィグファイルを用意します。コンフィグファイルのパスは、~/.config/jhbuildrcです。今回は次の内容とします。

import os
moduleset = ['gnome-world-3.8', 'gnome-apps-3.8', 'gnome-suites-core-3.8', 'gnome-suites-core-deps-3.8', 'gnome-suites-core-deps-base-3.8', 'gnome-sysdeps-3.8']
checkoutroot = os.path.expanduser('~/jhbuild/checkout')
prefix = os.path.expanduser('~/jhbuild/install')

コンフィグファイルはPythonの構文で記述します。と言ってもPythonを知らなくてもまったく問題ありません。基本的には「コンフィグ名 = コンフィグ値」のようにシンプルな記述だけで済みます。今回は動的な設定をしているのでPythonコードがほんの少しだけ見えます。

コンフィグファイルの内容を簡単に説明すると、⁠import os」の行は、Pythonのosモジュールをインポートします。今回は、以下でユーザーのホームディレクトリを動的に取得するためにPythonライブラリを利用します。⁠moduleset」は、参照するモジュールセットファイルの一覧を指定します。今回は、GNOMEの最新版に関わるものを指定しています。3.8と見えますが、本稿執筆時点では3.6に毛の生えた程度のバージョンとなります。⁠checkoutroot」は、チェックアウトしたソースツリーを保存するディレクトリを指定します。今回は ~/jhbuild/checkout としました。絶対パスで指定する場合は、os.path.expanduser()の部分を消しても問題ありません。⁠prefix」は、ビルドしたファイルをインストールするディレクトリを指定します。今回は、~/jhbuild/install としました。ディレクトリはお好みの場所でかまいませんが、書き込み可能である必要があります。

ディレクトリの作成

コンフィグファイルに指定したディレクトリを作成します。

$ mkdir -p ~/jhbuild/checkout ~/jhbuild/install

システムモジュールのインストール

システムモジュールに対応するUbuntuパッケージは、JHBuildを通じてインストールできます。内部では、apt-fileでパッケージを特定し、apt-getでインストールします。インストール時は認証が必要になります。次のコマンドを実行します。

$ jhbuild sysdeps --install

コマンドを実行すると、パッケージが既にインストール済みのモジュールや、まだインストールされていないモジュールなどの情報が表示されるとともに、必要なパッケージをインストールするための認証ダイアログが表示されます。認証を済ませパッケージのインストールを行なってください。なお、JHBuild側の問題で、一部のシステムモジュールを上記のsysdepsサブコマンドでインストールできません[1]⁠。今回は必要になるものを手動でインストールすることにします。

$ sudo apt-get install libjpeg-dev libtiff5-dev libacl1-dev gperf libcrack2-dev libpam0g-dev libdb-dev libnl-dev libcanberra-gtk3-dev libtasn1-3-bin ppp-dev bogofilter spamassassin ruby libicu-dev

セットアップの確認

セットアップが正しくできたか、sanitycheckサブコマンドで確認できます。

$ jhbuild sanitycheck

何も出力されなければOKです。何か問題があれば(たとえばチェックアウト先のディレクトリが書き込み可能でない等⁠⁠、その旨エラー内容が表示されます。

ビルドしてみよう

ビルド自体は非常に簡単です。次の通り、ビルドしたいモジュールを指定してbuildサブコマンドを実行します。今回は「nautilus」を指定します。指定可能なモジュール名の一覧は「jhbuild list」コマンドで確認できます。複数のモジュールを指定することもできます。

$ jhbuild build nautilus -N --nodeps

これでビルド処理が走り、Nautilusと関連する依存物のチェックアウト、ビルド、インストールが自動で行われます。

オプションについて説明します。⁠-N」を指定すると、依存物のビルドに失敗しても残りのモジュールのビルドを継続します。デフォルトでは、あるモジュールのビルドに失敗すると、それに依存するモジュールのビルドをスキップします。今回はとりあえず最後までビルドするために指定しています。⁠--nodeps」は、システムモジュールのうちインストールされていないものがあってもそれを無視するオプションです。デフォルトでは、見つからないシステムモジュールがあるとビルド自体を行わずに終了します。

ビルドには時間が掛かります。マシン性能や通信速度にもよりますが、数時間は掛かると思っておいたほうがよいでしょう。その間Beta2のテストなどをして過ごしてください。ビルドが正常に完了すると次のようなメッセージが表示されて処理が終わります。数字はビルドしたモジュール数です。

*** 成功 *** [62/62]

実際にNautilusが指定のディレクトリにインストールされたか確認するには、次のコマンドを実行します。

$ jhbuild shell
$ which nautilus

shellサブコマンドは、各種環境変数などJHBuild用の環境が設定された状態でシェルを起動します。たとえばPATHには、コンフィグのprefixに指定したディレクトリ配下が設定されています。シェル自体はユーザーが普段使用しているシェルと同じです。exitで元の環境に戻ります。

なお、幸か不幸か途中でビルドエラーが起きることもあります。開発真っ最中のファイルをビルドするため、エラーも珍しくありません。エラーが起きると次のようなプロンプトが表示され、次にどうするか選択します。

*** gtk+ の build フェーズにおけるエラー: ########## make -j 4 実行中のエラー *** [20/62]

  [1] build を再実行する
  [2] エラーを無視して install を続ける
  [3] このモジュールをビルドしない
  [4] シェルを起動する
  [5] 設定をリロードする
  [6] "ディレクトリを削除してもう一度やり直す" のフェーズへ移る
  [7] "configure" のフェーズへ移る
  [8] "clean" のフェーズへ移る
  [9] "distclean" のフェーズへ移る
選択:

シェルを起動して問題を解析したい場合は、4を入力してEnterを押してください。プログラム側の問題が疑われる場合は、バグ報告をしてみると多くの人が幸せになるかもしれません。なお、モジュールによっては、既知の事象とその解決方法がまとめられています。参考にするとヒントが得られるかもしれません。とりあえず、ビルドをスキップする場合は3を選択してください。

ビルドしたアプリを使ってみよう

それでは、ビルドしたNautilusを使ってみましょう。

通常のNautilusがログイン時に自動的に起動しているので、まずそれを終了させます。

$ nautilus -q

JHBuildの環境に移ります。以降は、ここで起動したシェル上で作業します。

$ jhbuild shell

デフォルトでは依存関係によりPangoもビルドされるので、次を実行しておきます。JHBUILD_PREFIXは、jhbuild shellで定義される環境変数です。値は、コンフィグで指定したprefixと同じディレクトリになります。

$ mkdir "${JHBUILD_PREFIX}/etc/pango"
$ pango-querymodules > "${JHBUILD_PREFIX}/etc/pango/pango.modules"

そして、Nautilusを起動します。

$ nautilus

あとは、新機能を確認してみるなど、ご自由にお試しください。

図2 JHBuildでビルドしたNautilus 3.6
図2 JHBuildでビルドしたNautilus 3.6

JHBuildを使う上でのTips

非対話処理

通常のbuildサブコマンドでは、ビルドエラーに遭遇すると、プロンプトが表示されて処理がプロックされます。--no-interactオプションをbuildサブコマンドに指定すれば、非対話的に走らせることができます。ビルドに失敗したモジュールはスキップします。

ビルドオプション

モジュールごとに、特定の機能を有効化/無効化してビルドすることができます。⁠module_autogenargs」というコンフィグを使って指定できます。これはPythonのディクショナリです。対象のモジュール名をキーに、configureに指定するオプションを値に記述します。たとえば、GTK+でBroadwayバックエンドを試してみたいという場合は、次の指定をコンフィグファイルに記述します。

module_autogenargs['gtk+'] = '--enable-broadway-backend --enable-x11-backend'

これを利用すれば、Ubuntuでは無効化されている機能を試す、要らない機能を無効にするなど、自分の好みに合わせて自由にカスタマイズできます。

GNOME全体のビルド

JHBuildは、特定のモジュールだけでなく、GNOME全体をビルドしてオリジナルのGNONE環境を作り上げることもできます。挑戦してみたい人は、JHBuildのマニュアルを参照して、ぜひトライしてください。

フィードバック

JHBuildの目的のひとつに、開発版のGNOMEをテストするというものがあります。実際にアプリケーションを試してみて、何か不具合や改善点を見つけた場合は、ぜひバグレポートをお寄せください⁠こんな機能が欲しい」という要望も、バグレポートとして受け付けています。

おすすめ記事

記事・ニュース一覧