ワークスペース、パッケージ、ターゲット

Bazel は、ワークスペースと呼ばれるディレクトリ ツリーで整理されたソースコードからソフトウェアをビルドします。ワークスペース内のソースファイルは、ネストされたパッケージの階層で編成されます。各パッケージは、関連するソースファイルのセットと 1 つの BUILD ファイルを含むディレクトリです。BUILD ファイルは、ソースからビルドできるソフトウェア出力を指定します。

ワークスペース

ワークスペースは、ビルドするソフトウェアのソースファイルを含む、ファイル システム上のディレクトリ ツリーです。各ワークスペースには WORKSPACE という名前のテキスト ファイルがあります。このファイルは空にすることも、出力のビルドに必要な外部依存関係への参照を含むこともできます。

WORKSPACE というファイルを含むディレクトリは、ワークスペースのルートとみなされます。したがって、Bazel は、WORKSPACE ファイルを含むサブディレクトリをルートとするワークスペース内のディレクトリ ツリーが別のワークスペースを形成するため、無視します。

Bazel は、WORKSPACE ファイルのエイリアスとして WORKSPACE.bazel ファイルもサポートしています。両方のファイルが存在する場合は、WORKSPACE.bazel が使用されます。

リポジトリ

コードはリポジトリにまとめられます。WORKSPACE ファイルを含むディレクトリはメイン リポジトリのルートです(@ とも呼ばれます)。その他の(外部)リポジトリは、ワークスペース ルールを使用して WORKSPACE ファイルで定義されます。

Bazel にバンドルされているワークスペース ルールは、ビルド百科事典ワークスペース ルールのセクションと、埋め込みの Starlark リポジトリ ルールのドキュメントをご覧ください。

外部リポジトリはリポジトリ自体であるため、多くの場合、WORKSPACE ファイルも含まれます。ただし、これらの追加の WORKSPACE ファイルは Bazel で無視されます。特に、推移的に依存しているリポジトリは自動的に追加されません。

パッケージ

リポジトリ内のコードを構成する主な単位はパッケージです。パッケージは、関連するファイルの集まりと、出力アーティファクトの生成方法の仕様です。

パッケージは、BUILD(または BUILD.bazel)という名前のファイルを含むディレクトリとして定義されます。パッケージには、そのディレクトリ内のすべてのファイルと、その下のすべてのサブディレクトリ(BUILD ファイルを含むものを除く)が含まれます。この定義では、2 つの異なるパッケージにファイルやディレクトリを含めることはできません。

たとえば、次のディレクトリ ツリーには、my/app とサブパッケージ my/app/tests の 2 つのパッケージがあります。my/app/data はパッケージではなく、パッケージ my/app に属するディレクトリです。

src/my/app/BUILD
src/my/app/app.cc
src/my/app/data/input.txt
src/my/app/tests/BUILD
src/my/app/tests/test.cc

ターゲット

パッケージはターゲットのコンテナであり、パッケージの BUILD ファイルで定義されます。ほとんどのターゲットは、ファイルとルールという 2 つのプリンシパルの種類のいずれかです。

ファイルはさらに 2 種類に分類されます。ソースファイルは通常、人の手によって作成され、リポジトリにチェックインされます。生成ファイル(派生ファイルや出力ファイルとも呼ばれます)はチェックインされず、ソースファイルから生成されます。

2 つ目の種類のターゲットはルールで宣言します。各ルール インスタンスでは、入力ファイルセットと出力ファイルセットの関係を指定します。ルールへの入力はソースファイルにすることもできますが、他のルールの出力にすることもできます。

ほとんどの場合、ルールへの入力がソースファイルか生成されたファイルかは重要ではありません。重要なのは、そのファイルの内容だけです。そのため、複雑なソースファイルを、ルールによって生成された生成ファイルに簡単に置き換えることができます。たとえば、高度に構造化されたファイルを手動でメンテナンスする負担が大きくなり、それを取得するプログラムを記述した場合などです。このファイルのコンシューマを変更する必要はありません。逆に、生成されたファイルは、ローカルの変更のみを行ったソースファイルに簡単に置き換えることができます。

ルールへの入力には、その他のルールも含まれる場合があります。多くの場合、このような関係の正確な意味は非常に複雑で、言語やルールによって異なりますが、直感的にはシンプルです。C++ ライブラリ ルール A が、入力用に別の C++ ライブラリルール B を持つ場合があります。この依存関係により、B のヘッダー ファイルはコンパイル時に A が使用でき、B のシンボルはリンク時に A が使用でき、B のランタイム データは実行中 A が使用できます。

どのルールも不変条件は、ルールによって生成されたファイルは常にルール自体と同じパッケージに属していることです。つまり、別のパッケージにファイルを生成することはできません。ただし、ルールの入力が別のパッケージから取得されることも珍しくありません。

パッケージ グループは、特定のルールのアクセシビリティを制限することを目的とするパッケージのセットです。パッケージ グループは、package_group 関数で定義されます。このオブジェクトには、含まれているパッケージのリスト、名前、他のパッケージ グループという 3 つのプロパティがあります。これらを参照するために許可される方法は、ルールの visibility 属性または package 関数の default_visibility 属性からのみです。ファイルの生成や消費は行われません。詳細については、package_group のドキュメントをご覧ください。

ラベル