概要
本ドキュメントは、Mozilla の GNU make ベースビルドシステムを必要とする Mozilla 開発者をターゲットとしています。 本ドキュメントでは、ビルドシステムの基本概念と用語ならびに、コンポーネントのコンパイルや jar ファイルの作成といった共通的作業をどのように行うかを解説しています。
本書は Mozilla をただビルドしたい人を対象にはしていません。その場合はBuild Documentationを参照してください。
概念
Mozilla のビルドシステムは GNU Make をベースにしたシステムです。最も基本的なレベルでは、make はターゲットを自動生成するツールで、ターゲットごとにdependencies とrules を生成します。
Mozilla プロジェクトでは、make はライブラリと実行モジュールのコンパイル、chrome の jar ファイル作成、関係ファイルのコピーに使用されます。我々は、2 パスのビルドシステムを使用しています:
- export フェーズでは、public ヘッダファイルを dist/include へコピーし、IDL ファイルから C++ ヘッダファイルを生成します。
- libs フェーズでは、ライブラリをコンパイルし、 jar ファイルを作成し、IDL ファイルから typelib ファイルを作成します。
いずれのフェーズでも、ターゲットを make するだけです。これは、それぞれのディレクトリは export ターゲットとともにまず一度横断し、libs ターゲットとともに、再び横断します。 二段階のビルドは、モジュール間の循環的参照のために存在します。最初にすべてのヘッダファイルを export することで、あるモジュール(Aとする)は、別のモジュール(B)の public なヘッダファイルをインクルードしながら、モジュール(B)はモジュール(A)の public なヘッダファイルをインクルードできます。
その他の重要なツールとして、configure が挙げられます。これは、ビルドの最初のステップに実行されます。configure スクリプトはシステムやコンパイラの特徴を決定し、オプションを生成します。configure スクリプトから実行される重要な製品が二つあります:
- autoconf.mk ファイルは autoconf.mk.inから生成されます。このファイルは、グローバルなビルドオプションを制御するmake 変数 を含みます。
- Makefile ファイルは、ツリーの至る所にある Makefile.in ファイルから生成されます。ビルドを正確に行うため、Makefile.in 中に記述されたソースディレクトリの場所が置換されます。
configure スクリプトは bash シェルベースのものです。このスクリプトは M4 とともに書かれた configure.in と呼ばれるファイルから生成され、最終的なスクリプトを生成するために Autoconfを使って処理します。
Makefile の基礎
Makefile は、非常に複雑にもなり得ますが、Mozilla チームは、大半の Makefile をとてもシンプルにすべく、多数のビルトインルールを提供しています。make についての網羅的な解説は本説明の範囲を超えますので、こちら(GNU make)を参照してください。
精通しておくとよいであろう概念の一つとして、make の変数が挙げられます。変数はVARIABLE = VALUE
という構文で定義され、その値は$(VARIABLE)
と記述することで参照されます。すべての変数は文字列です。
Mozilla のソースコードに含まれる Makefile.in ファイルはすべて同じ基本的なフォーマットで記述されています。
# ... Makefile の中心となる本体部分がここに入ります ...
include $(topsrcdir)/config/rules.mk # ... 追加のルールがここに入ります ...
- DEPTH 変数はMakefile.in から Mozilla ディレクトリの最上位への相対パスがセットされます。
- topsrcdir は configure によって置換されます。これは Mozilla ディレクトリの最上位 を示します。
- srcdir もまた、configure によって置換されます。これは、現在のディレクトリに対するソースファイルの場所を示します。ソースツリーからのビルドでは、この値は単に "."(カレントディレクトリ)を示すでしょう。
- VPATH は、make が必須ファイル(例:ソースファイル)を探す対象ディレクトリの一覧です。
この他によく使われる変数の一つとして、特定のビルドターゲットを指定しない DIRS があります。DIR は、現在のディレクトリを再帰的に組み込むためのサブディレクトリの一覧です。サブディレクトリは親ディレクトリの後に配置されます。以下に例を示します。
DIRS = \ public \ resources \ src \ $(NULL)
上記の例は、行結合の例でもあります。行の中の最後に現れるバックスラッシュ(訳注:通常の日本の環境では¥記号に見えることも多いので注意)は、変数定義が次の行にも続いていることを示します。行の継ぎ目の余分な空白は縮められます。終端の $(NULL) は表記に一貫性を持たせる手段です。これにより、行末のバックスラッシュの有無を気にせず行の追加・削除が行えます。
Makefile examples
ライブラリのビルド
Mozilla のビルドにおけるライブラリは、主として3種に分けられます:
- Components は(静的ビルド時を除いて)共有ライブラリで、 dist/bin/components にインストールされます。Components は他のいかなるライブラリからもリンクされません。
- Non-component shared libraries には、libxpcom、libmozjs といったライブラリが含まれます。これらのライブラリは dist/bin にインストールされ、リンクもされます。この種のライブラリを新規に作成する必要にせまられることはあまりありません。
- Static libraries はしばしば共有ライブラリのビルドの中間段階として使われます。 共有ライブラリの一部となるいくつかのディレクトリにソースファイルがある場合などがそれに該当します。静的ライブラリは実行ファイルからリンクされることもあります。
Non-component shared libraries
non-component shared library は、複数のコンポーネントが共有しなければならない共通コードがあり、それを XPCOM を通じて共有することが、適切でないもしくは不可能な場合に有用です。 一例として、libmsgbaseutil 向けの Makefile の一部を見てみましょう。これは、mailnews コンポーネント全体からリンクされます:
DEPTH = ../../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = msgbaseutil LIBRARY_NAME = msgbaseutil EXPORT_LIBRARY = 1 SHORT_LIBNAME = msgbsutl
上述した component の例との実際問題としての相違点は、IS_COMPONENT が設定されていない事だけである点に注意してください。この値を設定しない事によって、共有ライブラリが生成され、dist/bin にインストールされるでしょう。
Static libraries
上述の通り、静的ライブラリの主要な使用方法としては、大規模ライブラリ(主に component)のビルドの中間段階としての使用が挙げられます。これにより、複数のサブディレクトリにソースファイルを分散させて配置することができます。静的ライブラリは実行可能モジュールにもリンクされることがあります。例として、layout/base/src の Makefile の一部を以下に示します。
DEPTH = ../../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = layout LIBRARY_NAME = gkbase_s # REQUIRES and CPPSRCS omitted here for brevity # # we don't want the shared lib, but we want to force the creation of a static lib. FORCE_STATIC_LIB = 1 include $(topsrcdir)/config/rules.mk
ここでは FORCE_STATIC_LIB = 1 というキーが設定されています。これにより、(unix の場合)libgkbase_s.a が、Windows の場合はgkbase_s.lib が生成され、dist/lib にコピーされます。では、コンポーネントを作成するために複数の静的ライブラリを合わせてリンクする方法をざっと見てみましょう。
DEPTH = ../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = layout LIBRARY_NAME = gklayout EXPORT_LIBRARY = 1 IS_COMPONENT = 1 MODULE_NAME = nsLayoutModule CPPSRCS = \ nsLayoutModule.cpp \ $(NULL) SHARED_LIBRARY_LIBS = \ $(DIST)/lib/$(LIB_PREFIX)gkhtmlbase_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkhtmldoc_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkhtmlforms_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkhtmlstyle_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkhtmltable_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkxulbase_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkbase_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkconshared_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkxultree_s.$(LIB_SUFFIX) \ $(DIST)/lib/$(LIB_PREFIX)gkxulgrid_s.$(LIB_SUFFIX) \ $(NULL) include $(topsrcdir)/config/rules.mk
SHARED_LIBRARY_LIBS は、本共有ライブラリにリンクすべき静的ライブラリを並べて記述します。LIB_PREFIX や LIB_SUFFIX を使用することで、すべてのプラットフォームで動作させることができることに注意してください。
Jar ファイルをビルドする
Jar ファイルは(XUL、JavaScript、CSSといった) chrome ファイルのパッケージングに使用します。Jar パッケージングについてのより詳細な情報は、[jar-packaging.html このドキュメント]で得られます。ここでは、Jar パッケージを行うために Makefile をどのように設定するかのみ述べます。以下に例を示します。
DEPTH = ../../../.. topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk
そうです。ここでは定義が必要な外部変数は使用されていません。Makefile.in と同じディレクトリに jar.mn ファイルがある場合、自動的に処理されるのです。jar.mn と chrome ファイルを含む resources ディレクトリを作成するのが通例ですが、ライブラリを作成するディレクトリに jar.mn を設置したいのであれば、これも動作します(処理されます)。
著作情報
- 著作者: Brian Ryner
- 著作権情報: Portions of this content are © 1998–2006 by individual mozilla.org contributors; content available under a Creative Commons license