このページでは、密閉性、密閉ビルドを使用するメリット、ビルド内の非密閉動作を識別するための戦略について説明します。
概要
密閉型のビルドシステムでは、同じ入力ソースコードとプロダクト構成が与えられると、ホストシステムに対する変更からビルドが分離されるため、常に同じ出力が返されます。
密閉型のビルドでは、ビルドを分離するため、ローカルまたはリモートのホストマシンにインストールされているライブラリやその他のソフトウェアの影響を受けません。ビルドツール(コンパイラなど)や依存関係(ライブラリなど)の特定のバージョンに依存します。これにより、ビルド環境の外部のサービスに依存しないため、ビルドプロセスは自己完結型になります。
密閉性の 2 つの重要な側面は次のとおりです。
- 分離: 密閉型のビルドシステムでは、ツールをソースコードとして扱います。ツールのコピーをダウンロードし、ストレージを管理し、マネージド ファイルツリー内で使用します。これにより、インストールされている言語のバージョンを含め、ホストマシンとローカル ユーザーが分離されます。
- ソース ID: 密閉型のビルドシステムは、入力の同一性を保証しようとします。Git などのコード リポジトリは、一意のハッシュコードを使用して一連のコード ミューテーションを識別します。密閉型のビルドシステムは、このハッシュを使用してビルドの入力に対する変更を識別します。
利点
密閉型ビルドの主なメリットは次のとおりです。
- 速度: アクションの出力をキャッシュに保存できます。入力が変更されない限り、アクションを再度実行する必要はありません。
- 並列実行: 指定された入力と出力に対して、ビルドシステムはすべてのアクションのグラフを作成して、効率的な並列実行を計算できます。ビルドシステムがルールを読み込み、アクション グラフとハッシュ入力を計算してキャッシュで検索します。
- 複数のビルド: 同じマシン上に複数の密閉型のビルドをビルドし、ビルドごとに異なるツールとバージョンを使用できます。
- 再現性: 密閉型ビルドは、そのビルドの正確な条件を把握しているため、トラブルシューティングに適しています。
非密閉性の特定
Bazel に移行する準備をしている場合は、既存のビルドの密閉性を事前に改善しておくと、移行が容易になります。ビルドが密閉性を示さない一般的な原因は次のとおりです。
.mk
ファイルでの任意の処理- 非確定的にファイルを作成するアクションやツール(通常はビルド ID やタイムスタンプを含む)
- ホスト間で異なるシステム バイナリ(
/usr/bin
バイナリ、絶対パス、ネイティブ C++ ルールの自動構成用のシステム C++ コンパイラなど) - ビルド中にソースツリーに書き込む。これにより、同じソースツリーが別のターゲットに使用されるのを防ぐことができます。最初のビルドはソースツリーに書き込み、ターゲット A のソースツリーを修正します。この場合、ターゲット B をビルドしようとすると、失敗する可能性があります。
非密閉ビルドのトラブルシューティング
ローカル実行以降、ローカル キャッシュ ヒットに影響する問題により、密閉でないアクションが明らかになります。
- null シーケンシャル ビルドを確実にする:
make
を実行してビルドが成功した場合、ビルドを再実行してもターゲットは再ビルドされません。各ビルドステップを 2 回実行したり、異なるシステムで実行したりして、ファイル コンテンツのハッシュを比較して異なる結果になった場合、ビルドは再現できません。 - 使用可能なさまざまなクライアント マシンからローカル キャッシュ ヒットをデバッグする手順を実行し、クライアント環境がアクションに漏洩していないことを確認します。
- チェックアウトされたソースツリーとホストツールの明示的なリストのみを含む Docker コンテナ内でビルドを実行します。ビルドの不具合とエラー メッセージにより、暗黙的なシステム依存関係が検出されます。
- リモート実行ルールを使用して、密閉性の問題を検出して修正する。
- ビルド内のアクションはステートフルであり、ビルドや出力に影響を与える可能性があるため、アクションごとのレベルで厳格なサンドボックス化を有効にします。
- ワークスペース ルールを使用すると、デベロッパーは外部ワークスペースに依存関係を追加できますが、依存関係が十分にあればプロセス内で任意の処理を行うことができます。フラグ
--experimental_workspace_rules_log_file=PATH
を Bazel コマンドに追加すると、Bazel ワークスペース ルールで密閉されていない可能性のあるアクションのログを取得できます。
Bazel による密閉性
他のプロジェクトで Bazel で密閉型のビルドを使用して成功を収めた方法について詳しくは、以下の BazelCon の講演をご覧ください。
- Bazel を使用したリアルタイム システムの構築(SpaceX)
- Bazel リモート実行とリモート キャッシュ(Uber、TwoSigma)
- リモート実行とキャッシュ保存によるビルドの高速化
- Bazel の融合: 増分ビルドの高速化
- リモート実行とローカル実行
- リモート キャッシュのユーザビリティを向上させる(IBM)
- Bazel を使用した自動運転車の構築(BMW)
- Bazel による自動運転車の構築と Q&A(GM Cruise)