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