Bazel は、ワークスペースと呼ばれるディレクトリ ツリーに編成されたソースコードからソフトウェアをビルドします。ワークスペース内のソースファイルは、パッケージのネストされた階層で編成されます。各パッケージは、関連するソースファイルのセトと 1 つの BUILD
ファイルを含むディレクトリです。BUILD
ファイルには、ソースからビルドできるソフトウェア出力を指定します。
ワークスペース
ワークスペースは、ビルドするソフトウェアのソースファイルを含むファイル システム上のディレクトリ ツリーです。各ワークスペースには WORKSPACE
という名前のテキスト ファイルがあります。このファイルは空の場合も、出力の作成に必要な外部依存関係への参照を含んでいる場合もあります。
WORKSPACE
という名前のファイルを含むディレクトリは、ワークスペースのルートと見なされます。したがって、WORKSPACE
ファイルを含むサブディレクトリをルートとするワークスペース内のディレクトリ ツリーは、別のワークスペースを形成するため、Bazel では無視されます。
Bazel は、WORKSPACE
ファイルのエイリアスとして WORKSPACE.bazel
ファイルもサポートしています。両方のファイルが存在する場合は、WORKSPACE.bazel
が使用されます。
リポジトリ
コードはrepositoriesにまとめられます。WORKSPACE
ファイルを含むディレクトリは、メイン リポジトリのルート(@
とも呼ばれます)です。その他の(外部)リポジトリは、ワークスペース ルールを使用して WORKSPACE
ファイルで定義されます。
Bazel にバンドルされているワークスペース ルールは、Build Encyclopedia のワークスペース ルールのセクションと、埋め込みの Starlark リポジトリ ルールに関するドキュメントに記載されています。
外部リポジトリはそれ自体がリポジトリであるため、多くの場合、WORKSPACE
ファイルも含まれています。ただし、これらの追加の WORKSPACE
ファイルは Bazel によって無視されます。特に、推移的に依存するリポジトリが自動的に追加されることはありません。
パッケージ
リポジトリ内のコード編成の主要な単位はパッケージです。パッケージは、関連するファイルのコレクションと、それらを使用して出力アーティファクトを生成する方法の仕様です。
パッケージは、BUILD
(または BUILD.bazel
)という名前のファイルを含むディレクトリとして定義されます。パッケージには、そのディレクトリ内のすべてのファイルと、その下に存在するすべてのサブディレクトリが含まれます(ただし、それ自体に BUILD
ファイルが含まれているものは除きます)。この定義から、ファイルまたはディレクトリが 2 つの異なるパッケージに属することはできません。
たとえば、次のディレクトリ ツリーには、2 つのパッケージ(my/app
とサブパッケージ my/app/tests
)があります。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 がある場合があります。この依存関係の効果により、A はコンパイル時に B のヘッダー ファイルを、A ではリンク時に B のシンボルを使用でき、実行中には B のランタイム データを A で使用できます。
すべてのルールの不変条件は、ルールによって生成されたファイルは常にルール自体と同じパッケージに属することです。別のパッケージにファイルを生成することはできません。ただし、ルールの入力が別のパッケージから取得されることは珍しくありません。
パッケージ グループは、特定のルールへのアクセスを制限することを目的としたパッケージのセットです。パッケージ グループは package_group
関数で定義されます。パッケージ グループには、含まれるパッケージのリスト、名前、他のパッケージ グループの 3 つのプロパティがあります。これらのファイルを参照できるのは、ルールの visibility
属性または package
関数の default_visibility
属性からのみです。ファイルの生成や使用は行われません。詳細については、package_group
のドキュメントをご覧ください。